Merge branch 'next'

This commit is contained in:
John Wiegley 2009-10-29 00:55:01 -04:00
commit 0b6460d062
13 changed files with 89 additions and 37 deletions

View file

@ -352,7 +352,7 @@ AC_STRUCT_TM
#AC_FUNC_MKTIME #AC_FUNC_MKTIME
#AC_FUNC_STAT #AC_FUNC_STAT
#AC_FUNC_STRFTIME #AC_FUNC_STRFTIME
AC_CHECK_FUNCS([access realpath getpwuid getpwnam]) AC_CHECK_FUNCS([access realpath getpwuid getpwnam isatty])
# Pepare the Makefiles # Pepare the Makefiles
AC_CONFIG_FILES([Makefile po/Makefile.in intl/Makefile]) AC_CONFIG_FILES([Makefile po/Makefile.in intl/Makefile])

View file

@ -111,7 +111,7 @@ void global_scope_t::read_init()
ifstream init(init_file); ifstream init(init_file);
if (session().read_journal(init_file) > 0 || if (session().read_journal(init_file, NULL, &report()) > 0 ||
session().journal->auto_xacts.size() > 0 || session().journal->auto_xacts.size() > 0 ||
session().journal->period_xacts.size() > 0) { session().journal->period_xacts.size() > 0) {
throw_(parse_error, _("Transactions found in initialization file '%1'") throw_(parse_error, _("Transactions found in initialization file '%1'")
@ -418,8 +418,18 @@ void global_scope_t::normalize_report_options(const string& verb)
report_t& rep(report()); report_t& rep(report());
if (! rep.HANDLED(no_color)) #ifdef HAVE_ISATTY
rep.HANDLER(color).on_only(string("?normalize")); if (! rep.HANDLED(force_color)) {
if (! rep.HANDLED(no_color) && isatty(STDOUT_FILENO))
rep.HANDLER(color).on_only(string("?normalize"));
if (rep.HANDLED(color) && ! isatty(STDOUT_FILENO))
rep.HANDLER(color).off();
}
if (! rep.HANDLED(force_pager)) {
if (rep.HANDLED(pager_) && ! isatty(STDOUT_FILENO))
rep.HANDLER(pager_).off();
}
#endif
// 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) &&
@ -530,6 +540,10 @@ void global_scope_t::normalize_report_options(const string& verb)
if (cols > 0) { if (cols > 0) {
DEBUG("auto.columns", "cols = " << cols); DEBUG("auto.columns", "cols = " << cols);
if (! rep.HANDLER(date_width_).specified)
rep.HANDLER(date_width_)
.on_with(none, format_date(CURRENT_DATE(), FMT_PRINTED).length());
long date_width = rep.HANDLER(date_width_).value.to_long(); long date_width = rep.HANDLER(date_width_).value.to_long();
long payee_width = (rep.HANDLER(payee_width_).specified ? long payee_width = (rep.HANDLER(payee_width_).specified ?
rep.HANDLER(payee_width_).value.to_long() : rep.HANDLER(payee_width_).value.to_long() :

View file

@ -99,12 +99,15 @@ namespace {
} }
} }
void process_option(const string& whence, const string& name, scope_t& scope, bool process_option(const string& whence, const string& name, scope_t& scope,
const char * arg, const string& varname) const char * arg, const string& varname)
{ {
op_bool_tuple opt(find_option(scope, name)); op_bool_tuple opt(find_option(scope, name));
if (opt.first) if (opt.first) {
process_option(whence, opt.first->as_function(), scope, arg, varname); process_option(whence, opt.first->as_function(), scope, arg, varname);
return true;
}
return false;
} }
void process_environment(const char ** envp, const string& tag, void process_environment(const char ** envp, const string& tag,

View file

@ -295,7 +295,7 @@ inline bool is_eq(const char * p, const char * n) {
#define WANT_DIR() \ #define WANT_DIR() \
(std::strncmp(p, DIR_PREFIX, DIR_PREFIX_LEN) == 0) (std::strncmp(p, DIR_PREFIX, DIR_PREFIX_LEN) == 0)
void process_option(const string& whence, const string& name, scope_t& scope, bool process_option(const string& whence, const string& name, scope_t& scope,
const char * arg, const string& varname); const char * arg, const string& varname);
void process_environment(const char ** envp, const string& tag, void process_environment(const char ** envp, const string& tag,

View file

@ -560,6 +560,8 @@ option_t<report_t> * report_t::lookup_option(const char * p)
OPT(flat); OPT(flat);
else OPT_ALT(forecast_while_, forecast_); else OPT_ALT(forecast_while_, forecast_);
else OPT(format_); else OPT(format_);
else OPT(force_color);
else OPT(force_pager);
else OPT_ALT(head_, first_); else OPT_ALT(head_, first_);
break; break;
case 'g': case 'g':

View file

@ -237,6 +237,8 @@ public:
HANDLER(exact).report(out); HANDLER(exact).report(out);
HANDLER(exchange_).report(out); HANDLER(exchange_).report(out);
HANDLER(flat).report(out); HANDLER(flat).report(out);
HANDLER(force_color).report(out);
HANDLER(force_pager).report(out);
HANDLER(forecast_while_).report(out); HANDLER(forecast_while_).report(out);
HANDLER(format_).report(out); HANDLER(format_).report(out);
HANDLER(gain).report(out); HANDLER(gain).report(out);
@ -539,6 +541,8 @@ public:
}); });
OPTION(report_t, flat); OPTION(report_t, flat);
OPTION(report_t, force_color);
OPTION(report_t, force_pager);
OPTION(report_t, forecast_while_); OPTION(report_t, forecast_while_);
OPTION(report_t, format_); // -F OPTION(report_t, format_); // -F
@ -630,10 +634,11 @@ public:
OPTION(report_t, output_); // -o OPTION(report_t, output_); // -o
#ifdef HAVE_ISATTY
OPTION__ OPTION__
(report_t, pager_, (report_t, pager_,
CTOR(report_t, pager_) { CTOR(report_t, pager_) {
if (! std::getenv("PAGER")) { if (! std::getenv("PAGER") && isatty(STDOUT_FILENO)) {
bool have_less = false; bool have_less = false;
if (exists(path("/opt/local/bin/less")) || if (exists(path("/opt/local/bin/less")) ||
exists(path("/usr/local/bin/less")) || exists(path("/usr/local/bin/less")) ||
@ -654,6 +659,20 @@ public:
else else
option_t<report_t>::on_with(whence, text); option_t<report_t>::on_with(whence, text);
}); });
#else // HAVE_ISATTY
OPTION__
(report_t, pager_,
CTOR(report_t, pager_) {
}
virtual void on_with(const optional<string>& whence, const value_t& text) {
string cmd(text.to_string());
if (cmd == "" || cmd == "false" || cmd == "off" ||
cmd == "none" || cmd == "no" || cmd == "disable")
option_t<report_t>::off();
else
option_t<report_t>::on_with(whence, text);
});
#endif // HAVE_ISATTY
OPTION(report_t, payee_as_account); OPTION(report_t, payee_as_account);

View file

@ -94,13 +94,14 @@ session_t::session_t()
std::size_t session_t::read_journal(std::istream& in, std::size_t session_t::read_journal(std::istream& in,
const path& pathname, const path& pathname,
account_t * master) account_t * master,
scope_t * scope)
{ {
if (! master) if (! master)
master = journal->master; master = journal->master;
std::size_t count = journal->parse(in, *this, master, &pathname, std::size_t count = journal->parse(in, scope ? *scope : *this,
HANDLED(strict)); master, &pathname, HANDLED(strict));
// remove calculated totals and flags // remove calculated totals and flags
clean_posts(); clean_posts();
@ -110,13 +111,14 @@ std::size_t session_t::read_journal(std::istream& in,
} }
std::size_t session_t::read_journal(const path& pathname, std::size_t session_t::read_journal(const path& pathname,
account_t * master) account_t * master,
scope_t * scope)
{ {
if (! exists(pathname)) if (! exists(pathname))
throw_(std::logic_error, _("Cannot read file '%1'") << pathname); throw_(std::logic_error, _("Cannot read file '%1'") << pathname);
ifstream stream(pathname); ifstream stream(pathname);
return read_journal(stream, pathname, master); return read_journal(stream, pathname, master, scope);
} }
std::size_t session_t::read_data(const string& master_account) std::size_t session_t::read_data(const string& master_account)

View file

@ -84,9 +84,11 @@ public:
std::size_t read_journal(std::istream& in, std::size_t read_journal(std::istream& in,
const path& pathname, const path& pathname,
account_t * master = NULL); account_t * master = NULL,
scope_t * scope = NULL);
std::size_t read_journal(const path& pathname, std::size_t read_journal(const path& pathname,
account_t * master = NULL); account_t * master = NULL,
scope_t * scope = NULL);
std::size_t read_data(const string& master_account = ""); std::size_t read_data(const string& master_account = "");

View file

@ -38,6 +38,7 @@
#include "option.h" #include "option.h"
#include "pstream.h" #include "pstream.h"
#include "pool.h" #include "pool.h"
#include "session.h"
#define TIMELOG_SUPPORT 1 #define TIMELOG_SUPPORT 1
#if defined(TIMELOG_SUPPORT) #if defined(TIMELOG_SUPPORT)
@ -60,7 +61,7 @@ namespace {
instance_t * parent; instance_t * parent;
std::istream& in; std::istream& in;
scope_t& session_scope; scope_t& scope;
journal_t& journal; journal_t& journal;
account_t * master; account_t * master;
const path * original_file; const path * original_file;
@ -85,7 +86,7 @@ namespace {
time_log_t& _timelog, time_log_t& _timelog,
#endif #endif
std::istream& _in, std::istream& _in,
scope_t& _session_scope, scope_t& _scope,
journal_t& _journal, journal_t& _journal,
account_t * _master = NULL, account_t * _master = NULL,
const path * _original_file = NULL, const path * _original_file = NULL,
@ -142,7 +143,7 @@ namespace {
virtual expr_t::ptr_op_t lookup(const string& name); virtual expr_t::ptr_op_t lookup(const string& name);
}; };
void parse_amount_expr(scope_t& session_scope, void parse_amount_expr(scope_t& scope,
std::istream& in, std::istream& in,
amount_t& amount, amount_t& amount,
post_t * post, post_t * post,
@ -162,7 +163,7 @@ namespace {
#endif #endif
if (expr) { if (expr) {
bind_scope_t bound_scope(session_scope, *post); bind_scope_t bound_scope(scope, *post);
value_t result(expr.calc(bound_scope)); value_t result(expr.calc(bound_scope));
if (result.is_long()) { if (result.is_long()) {
@ -184,7 +185,7 @@ instance_t::instance_t(std::list<account_t *>& _account_stack,
time_log_t& _timelog, time_log_t& _timelog,
#endif #endif
std::istream& _in, std::istream& _in,
scope_t& _session_scope, scope_t& _scope,
journal_t& _journal, journal_t& _journal,
account_t * _master, account_t * _master,
const path * _original_file, const path * _original_file,
@ -194,7 +195,7 @@ instance_t::instance_t(std::list<account_t *>& _account_stack,
#if defined(TIMELOG_SUPPORT) #if defined(TIMELOG_SUPPORT)
timelog(_timelog), timelog(_timelog),
#endif #endif
parent(_parent), in(_in), session_scope(_session_scope), parent(_parent), in(_in), scope(_scope),
journal(_journal), master(_master), journal(_journal), master(_master),
original_file(_original_file), strict(_strict) original_file(_original_file), strict(_strict)
{ {
@ -489,7 +490,14 @@ void instance_t::option_directive(char * line)
if (p) if (p)
*p++ = '\0'; *p++ = '\0';
} }
process_option(pathname.string(), line + 2, session_scope, p, line);
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);
}
} }
void instance_t::automated_xact_directive(char * line) void instance_t::automated_xact_directive(char * line)
@ -624,7 +632,7 @@ void instance_t::include_directive(char * line)
#if defined(TIMELOG_SUPPORT) #if defined(TIMELOG_SUPPORT)
timelog, timelog,
#endif #endif
stream, session_scope, journal, master, stream, scope, journal, master,
&filename, strict, this); &filename, strict, this);
instance.parse(); instance.parse();
@ -689,7 +697,7 @@ void instance_t::pop_directive(char *)
void instance_t::define_directive(char * line) void instance_t::define_directive(char * line)
{ {
expr_t def(skip_ws(line)); expr_t def(skip_ws(line));
def.compile(session_scope); // causes definitions to be established def.compile(scope); // causes definitions to be established
} }
void instance_t::general_directive(char * line) void instance_t::general_directive(char * line)
@ -865,7 +873,7 @@ post_t * instance_t::parse_post(char * line,
if (*next != '(') // indicates a value expression if (*next != '(') // indicates a value expression
post->amount.parse(stream, amount_t::PARSE_NO_REDUCE); post->amount.parse(stream, amount_t::PARSE_NO_REDUCE);
else else
parse_amount_expr(session_scope, stream, post->amount, post.get(), parse_amount_expr(scope, stream, post->amount, post.get(),
static_cast<uint_least8_t>(expr_t::PARSE_NO_REDUCE) | static_cast<uint_least8_t>(expr_t::PARSE_NO_REDUCE) |
static_cast<uint_least8_t>(expr_t::PARSE_SINGLE) | static_cast<uint_least8_t>(expr_t::PARSE_SINGLE) |
static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN)); static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
@ -913,7 +921,7 @@ post_t * instance_t::parse_post(char * line,
if (*p != '(') // indicates a value expression if (*p != '(') // indicates a value expression
post->cost->parse(cstream, amount_t::PARSE_NO_MIGRATE); post->cost->parse(cstream, amount_t::PARSE_NO_MIGRATE);
else else
parse_amount_expr(session_scope, cstream, *post->cost, post.get(), parse_amount_expr(scope, cstream, *post->cost, post.get(),
static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE) | static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE) |
static_cast<uint_least8_t>(expr_t::PARSE_SINGLE) | static_cast<uint_least8_t>(expr_t::PARSE_SINGLE) |
static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN)); static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
@ -966,7 +974,7 @@ post_t * instance_t::parse_post(char * line,
if (*p != '(') // indicates a value expression if (*p != '(') // indicates a value expression
post->assigned_amount->parse(stream, amount_t::PARSE_NO_MIGRATE); post->assigned_amount->parse(stream, amount_t::PARSE_NO_MIGRATE);
else else
parse_amount_expr(session_scope, stream, *post->assigned_amount, post.get(), parse_amount_expr(scope, stream, *post->assigned_amount, post.get(),
static_cast<uint_least8_t>(expr_t::PARSE_SINGLE) | static_cast<uint_least8_t>(expr_t::PARSE_SINGLE) |
static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE)); static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE));
@ -1233,11 +1241,11 @@ xact_t * instance_t::parse_xact(char * line,
expr_t::ptr_op_t instance_t::lookup(const string& name) expr_t::ptr_op_t instance_t::lookup(const string& name)
{ {
return session_scope.lookup(name); return scope.lookup(name);
} }
std::size_t journal_t::parse(std::istream& in, std::size_t journal_t::parse(std::istream& in,
scope_t& session_scope, scope_t& scope,
account_t * master, account_t * master,
const path * original_file, const path * original_file,
bool strict) bool strict)
@ -1254,7 +1262,7 @@ std::size_t journal_t::parse(std::istream& in,
#if defined(TIMELOG_SUPPORT) #if defined(TIMELOG_SUPPORT)
timelog, timelog,
#endif #endif
in, session_scope, *this, master, in, scope, *this, master,
original_file, strict); original_file, strict);
parsing_instance.parse(); parsing_instance.parse();

View file

@ -48,8 +48,10 @@ class LedgerHarness:
if columns: if columns:
insert += ' --columns=80' insert += ' --columns=80'
command = re.sub('\$ledger', '%s%s --args-only --no-color --pager=none' % \ command = re.sub('\$ledger', '%s%s %s %s %s %s' % \
(self.ledger, insert), command) (self.ledger, insert, '--args-only',
'--no-color', '--pager=none',
'--date-format=%y-%b-%d'), command)
return Popen(command, shell=True, close_fds=True, env=env, return Popen(command, shell=True, close_fds=True, env=env,
stdin=PIPE, stdout=PIPE, stderr=PIPE) stdin=PIPE, stdout=PIPE, stderr=PIPE)

View file

@ -1,4 +1,4 @@
bal --color bal --color --force-color
<<< <<<
2007/02/02 RD VMMXX 2007/02/02 RD VMMXX
Assets:Investments:Vanguard:VMMXX 0.350 VMMXX @ $1.00 Assets:Investments:Vanguard:VMMXX 0.350 VMMXX @ $1.00

View file

@ -4,8 +4,8 @@ reg --date-format='%Y'
Assets:Investments:Vanguard:VMMXX 0.350 VMMXX @ $1.00 Assets:Investments:Vanguard:VMMXX 0.350 VMMXX @ $1.00
Income:Dividends:Vanguard:VMMXX $-0.35 Income:Dividends:Vanguard:VMMXX $-0.35
>>>1 >>>1
2007 RD VMMXX As:In:Vanguard:VMMXX 0.350 VMMXX 0.350 VMMXX 2007 RD VMMXX As:In:Vanguard:VMMXX 0.350 VMMXX 0.350 VMMXX
In:Di:Vanguard:VMMXX $-0.35 $-0.35 In:Di:Vanguard:VMMXX $-0.35 $-0.35
0.350 VMMXX 0.350 VMMXX
>>>2 >>>2
=== 0 === 0

View file

@ -1,4 +1,4 @@
reg --color reg --color --force-color
<<< <<<
N $ N $