diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/amount.cc | 25 | ||||
-rw-r--r-- | src/commodity.cc | 1 | ||||
-rw-r--r-- | src/commodity.h | 2 | ||||
-rw-r--r-- | src/context.h | 2 | ||||
-rw-r--r-- | src/csv.cc | 8 | ||||
-rw-r--r-- | src/error.cc | 2 | ||||
-rw-r--r-- | src/filters.cc | 3 | ||||
-rw-r--r-- | src/global.cc | 57 | ||||
-rw-r--r-- | src/global.h | 8 | ||||
-rw-r--r-- | src/item.cc | 5 | ||||
-rw-r--r-- | src/journal.cc | 13 | ||||
-rw-r--r-- | src/report.cc | 15 | ||||
-rw-r--r-- | src/session.cc | 12 | ||||
-rw-r--r-- | src/session.h | 5 | ||||
-rw-r--r-- | src/xact.cc | 10 |
15 files changed, 119 insertions, 49 deletions
diff --git a/src/amount.cc b/src/amount.cc index 4e658212..ee03827e 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -195,7 +195,10 @@ namespace { for (const char * p = buf; *p; p++) { if (*p == '.') { - if (commodity_t::decimal_comma_by_default || + if (commodity_t::time_colon_by_default || + (comm && comm->has_flags(COMMODITY_STYLE_TIME_COLON))) + out << ':'; + else if (commodity_t::decimal_comma_by_default || (comm && comm->has_flags(COMMODITY_STYLE_DECIMAL_COMMA))) out << ','; else @@ -209,7 +212,10 @@ namespace { out << *p; if (integer_digits > 3 && --integer_digits % 3 == 0) { - if (commodity_t::decimal_comma_by_default || + if (commodity_t::time_colon_by_default || + (comm && comm->has_flags(COMMODITY_STYLE_TIME_COLON))) + out << ':'; + else if (commodity_t::decimal_comma_by_default || (comm && comm->has_flags(COMMODITY_STYLE_DECIMAL_COMMA))) out << '.'; else @@ -684,7 +690,7 @@ void amount_t::in_place_ceiling() throw_(amount_error, _("Cannot ceiling an uninitialized amount")); _dup(); - + mpz_t quot; mpz_init(quot); mpz_cdiv_q(quot, mpq_numref(MP(quantity)), mpq_denref(MP(quantity))); @@ -737,6 +743,16 @@ void amount_t::in_place_unreduce() } if (shifted) { + if ("h" == comm->symbol() && commodity_t::time_colon_by_default) { + amount_t floored = tmp.floored(); + amount_t precision = tmp - floored; + if (precision < 0.0) { + precision += 1.0; + floored -= 1.0; + } + tmp = floored + (precision * (comm->smaller()->number() / 100.0)); + } + *this = tmp; commodity_ = comm; } @@ -1090,6 +1106,9 @@ bool amount_t::parse(std::istream& in, const parse_flags_t& flags) bool decimal_comma_style = (commodity_t::decimal_comma_by_default || commodity().has_flags(COMMODITY_STYLE_DECIMAL_COMMA)); + bool time_colon_style + = (commodity_t::time_colon_by_default || + commodity().has_flags(COMMODITY_STYLE_TIME_COLON)); new_quantity->prec = 0; diff --git a/src/commodity.cc b/src/commodity.cc index 05d465ca..ffeac10d 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -40,6 +40,7 @@ namespace ledger { bool commodity_t::decimal_comma_by_default = false; +bool commodity_t::time_colon_by_default = false; void commodity_t::add_price(const datetime_t& date, const amount_t& price, const bool reflexive) diff --git a/src/commodity.h b/src/commodity.h index ab496850..1d69b689 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -107,6 +107,7 @@ protected: #define COMMODITY_SAW_ANNOTATED 0x200 #define COMMODITY_SAW_ANN_PRICE_FLOAT 0x400 #define COMMODITY_SAW_ANN_PRICE_FIXATED 0x800 +#define COMMODITY_STYLE_TIME_COLON 0x1000 string symbol; optional<std::size_t> graph_index; @@ -176,6 +177,7 @@ protected: public: static bool decimal_comma_by_default; + static bool time_colon_by_default; virtual ~commodity_t() { TRACE_DTOR(commodity_t); diff --git a/src/context.h b/src/context.h index 7373be39..9fe0613b 100644 --- a/src/context.h +++ b/src/context.h @@ -121,7 +121,7 @@ inline parse_context_t open_for_reading(const path& pathname, throw_(std::runtime_error, _f("Cannot read journal file %1%") % filename); - path parent(pathname.parent_path()); + path parent(filename.parent_path()); shared_ptr<std::istream> stream(new ifstream(filename)); parse_context_t context(stream, parent); context.pathname = filename; @@ -166,7 +166,7 @@ xact_t * csv_reader::read_xact(bool rich_data) string total; string field; - while (instr.good() && ! instr.eof()) { + while (instr.good() && ! instr.eof() && n < index.size()) { field = read_field(instr); switch (index[n]) { @@ -175,7 +175,8 @@ xact_t * csv_reader::read_xact(bool rich_data) break; case FIELD_DATE_AUX: - xact->_date_aux = parse_date(field); + if (! field.empty()) + xact->_date_aux = parse_date(field); break; case FIELD_CODE: @@ -224,7 +225,8 @@ xact_t * csv_reader::read_xact(bool rich_data) break; case FIELD_NOTE: - xact->note = field; + if (! field.empty()) + xact->note = field; break; case FIELD_UNKNOWN: diff --git a/src/error.cc b/src/error.cc index 58339db7..8aa1d3d6 100644 --- a/src/error.cc +++ b/src/error.cc @@ -84,7 +84,7 @@ string source_context(const path& file, const string& prefix) { const std::streamoff len = end_pos - pos; - if (! len || file == path("/dev/stdin")) + if (! len || file.empty()) return _("<no source context>"); assert(len > 0); diff --git a/src/filters.cc b/src/filters.cc index 5e2bf983..7570809a 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -983,7 +983,8 @@ void interval_posts::flush() sort_posts_by_date()); // Determine the beginning interval by using the earliest post - if (! interval.find_period(all_posts.front()->date())) + if (all_posts.front() && + ! interval.find_period(all_posts.front()->date())) throw_(std::logic_error, _("Failed to find period for interval report")); // Walk the interval forward reporting all posts within each one diff --git a/src/global.cc b/src/global.cc index 3e83ba04..5fc10f02 100644 --- a/src/global.cc +++ b/src/global.cc @@ -107,32 +107,53 @@ global_scope_t::~global_scope_t() #endif } +void global_scope_t::parse_init(path init_file) +{ + TRACE_START(init, 1, "Read initialization file"); + + parse_context_stack_t parsing_context; + parsing_context.push(init_file); + parsing_context.get_current().journal = session().journal.get(); + parsing_context.get_current().scope = &report(); + + if (session().journal->read(parsing_context) > 0 || + session().journal->auto_xacts.size() > 0 || + session().journal->period_xacts.size() > 0) { + throw_(parse_error, _f("Transactions found in initialization file '%1%'") + % init_file); + } + + TRACE_FINISH(init, 1); +} + void global_scope_t::read_init() { + // if specified on the command line init_file_ is filled in + // global_scope_t::handle_debug_options. If it was specified on the command line + // fail is the file doesn't exist. If no init file was specified + // on the command-line then try the default values, but don't fail if there + // isn't one. + path init_file; if (HANDLED(init_file_)) { - path init_file(HANDLER(init_file_).str()); + init_file=HANDLER(init_file_).str(); if (exists(init_file)) { - TRACE_START(init, 1, "Read initialization file"); - - parse_context_stack_t parsing_context; - parsing_context.push(init_file); - parsing_context.get_current().journal = session().journal.get(); - parsing_context.get_current().scope = &report(); - - if (session().journal->read(parsing_context) > 0 || - session().journal->auto_xacts.size() > 0 || - session().journal->period_xacts.size() > 0) { - throw_(parse_error, _f("Transactions found in initialization file '%1%'") - % init_file); - } - - TRACE_FINISH(init, 1); + parse_init(init_file); } else { throw_(parse_error, _f("Could not find specified init file %1%") % init_file); } + } else { + if (const char * home_var = std::getenv("HOME")){ + init_file = (path(home_var) / ".ledgerrc"); + } else { + init_file = ("./.ledgerrc"); + } + } + if(exists(init_file)){ + parse_init(init_file); } } + char * global_scope_t::prompt_string() { static char prompt[32]; @@ -477,8 +498,8 @@ void handle_debug_options(int argc, char * argv[]) #endif } else if (i + 1 < argc && std::strcmp(argv[i], "--init-file") == 0) { - _init_file = argv[i + 1]; - i++; + _init_file = argv[i + 1]; + i++; } else if (i + 1 < argc && std::strcmp(argv[i], "--debug") == 0) { #if DEBUG_ON diff --git a/src/global.h b/src/global.h index d37043fc..11459529 100644 --- a/src/global.h +++ b/src/global.h @@ -67,6 +67,7 @@ public: return _("global scope"); } + void parse_init(path init_file); void read_init(); void read_environment_settings(char * envp[]); strings_list read_command_arguments(scope_t& scope, strings_list args); @@ -153,14 +154,9 @@ See LICENSE file included with the distribution for details and disclaimer."); OPTION__ (global_scope_t, init_file_, // -i CTOR(global_scope_t, init_file_) { - if(!_init_file.empty()) + if (!_init_file.empty()) // _init_file is filled during handle_debug_options on(none, _init_file); - else - if (const char * home_var = std::getenv("HOME")) - on(none, (path(home_var) / ".ledgerrc").string()); - else - on(none, path("./.ledgerrc").string()); }); OPTION(global_scope_t, options); diff --git a/src/item.cc b/src/item.cc index 24d03ba1..4e2a487c 100644 --- a/src/item.cc +++ b/src/item.cc @@ -476,7 +476,6 @@ expr_t::ptr_op_t item_t::lookup(const symbol_t::kind_t kind, else if (name == "filepath") return WRAP_FUNCTOR(get_wrapper<&get_filepath>); break; - break; case 'h': if (name == "has_tag") @@ -583,8 +582,8 @@ string item_context(const item_t& item, const string& desc) std::ostringstream out; - if (item.pos->pathname == path("/dev/stdin")) { - out << desc << _(" from standard input:"); + if (item.pos->pathname.empty()) { + out << desc << _(" from streamed input:"); return out.str(); } diff --git a/src/journal.cc b/src/journal.cc index e6c09125..68939be6 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -127,8 +127,19 @@ account_t * journal_t::register_account(const string& name, post_t * post, // object. if (account_aliases.size() > 0) { accounts_map::const_iterator i = account_aliases.find(name); - if (i != account_aliases.end()) + if (i != account_aliases.end()) { result = (*i).second; + } else { + // only check the very first account for alias expansion, in case + // that can be expanded successfully + size_t colon = name.find(':'); + if(colon != string::npos) { + accounts_map::const_iterator i = account_aliases.find(name.substr(0, colon)); + if (i != account_aliases.end()) { + result = find_account((*i).second->fullname() + name.substr(colon)); + } + } + } } // Create the account object and associate it with the journal; this diff --git a/src/report.cc b/src/report.cc index 08365a6b..d4beaf2a 100644 --- a/src/report.cc +++ b/src/report.cc @@ -1089,6 +1089,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT(anon); else OPT_ALT(color, ansi); else OPT(auto_match); + else OPT(aux_date); else OPT(average); else OPT(account_width_); else OPT(amount_width_); @@ -1096,7 +1097,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) case 'b': OPT(balance_format_); else OPT(base); - else OPT_ALT(basis, cost); + else OPT(basis); else OPT_(begin_); else OPT(bold_if_); else OPT(budget); @@ -1105,6 +1106,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) break; case 'c': OPT(csv_format_); + else OPT_ALT(gain, change); else OPT(cleared); else OPT(collapse); else OPT(collapse_if_zero); @@ -1122,6 +1124,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT(dc); else OPT(depth_); else OPT(deviation); + else OPT_ALT(rich_data, detail); else OPT_(display_); else OPT(display_amount_); else OPT(display_total_); @@ -1146,7 +1149,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT_ALT(head_, first_); break; case 'g': - OPT_ALT(gain, change); + OPT(gain); else OPT(group_by_); else OPT(group_title_format_); else OPT(generated); @@ -1173,7 +1176,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT_ALT(tail_, last_); break; case 'm': - OPT_ALT(market, value); + OPT(market); else OPT(monthly); else OPT(meta_); else OPT(meta_width_); @@ -1203,6 +1206,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT(price); else OPT(prices_format_); else OPT(pricedb_format_); + else OPT(primary_date); else OPT(payee_width_); else OPT(prepend_format_); else OPT(prepend_width_); @@ -1220,7 +1224,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT(revalued); else OPT(revalued_only); else OPT(revalued_total_); - else OPT_ALT(rich_data, detail); + else OPT(rich_data); break; case 's': OPT(sort_); @@ -1247,6 +1251,9 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT(unrealized_losses_); else OPT(unround); break; + case 'v': + OPT_ALT(market, value); + break; case 'w': OPT(weekly); else OPT_(wide); diff --git a/src/session.cc b/src/session.cc index b6153203..632002d4 100644 --- a/src/session.cc +++ b/src/session.cc @@ -98,8 +98,12 @@ std::size_t session_t::read_data(const string& master_account) acct = journal->find_account(master_account); optional<path> price_db_path; - if (HANDLED(price_db_)) + if (HANDLED(price_db_)){ price_db_path = resolve_path(HANDLER(price_db_).str()); + if (!exists(price_db_path.get())){ + throw_(parse_error, _f("Could not find specified price file %1%") % price_db_path); + } + } if (HANDLED(explicit)) journal->force_checking = true; @@ -143,7 +147,7 @@ std::size_t session_t::read_data(const string& master_account) } foreach (const path& pathname, HANDLER(file_).data_files) { - if (pathname == "-") { + if (pathname == "-" || pathname == "/dev/stdin") { // To avoid problems with stdin and pipes, etc., we read the entire // file in beforehand into a memory buffer, and then parcel it out // from there. @@ -348,9 +352,11 @@ option_t<session_t> * session_t::lookup_option(const char * p) case 's': OPT(strict); break; + case 't': + OPT(time_colon); + break; case 'v': OPT(value_expr_); - break; } return NULL; } diff --git a/src/session.h b/src/session.h index a0aba91b..74aeab5f 100644 --- a/src/session.h +++ b/src/session.h @@ -100,6 +100,7 @@ public: HANDLER(day_break).report(out); HANDLER(download).report(out); HANDLER(decimal_comma).report(out); + HANDLER(time_colon).report(out); HANDLER(file_).report(out); HANDLER(input_date_format_).report(out); HANDLER(explicit).report(out); @@ -130,6 +131,10 @@ public: commodity_t::decimal_comma_by_default = true; }); + OPTION_(session_t, time_colon, DO() { + commodity_t::time_colon_by_default = true; + }); + OPTION__ (session_t, price_exp_, // -Z CTOR(session_t, price_exp_) { value = "24"; }); diff --git a/src/xact.cc b/src/xact.cc index 7888dadf..7ac7a9e9 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -803,12 +803,12 @@ void auto_xact_t::extend_xact(xact_base_t& xact, parse_context_t& context) post_t * new_post = new post_t(account, amt); new_post->copy_details(*post); - // A Cleared transaction implies all of its automatic posting are cleared + // A Cleared transaction implies all of its automatic posting are cleared // CPR 2012/10/23 - if(xact.state() == item_t::CLEARED){ - DEBUG("xact.extend.cleared", "CLEARED"); - new_post->set_state(item_t::CLEARED); - } + if (xact.state() == item_t::CLEARED) { + DEBUG("xact.extend.cleared", "CLEARED"); + new_post->set_state(item_t::CLEARED); + } new_post->add_flags(ITEM_GENERATED); new_post->account = |