diff options
Diffstat (limited to 'src/textual.cc')
-rw-r--r-- | src/textual.cc | 580 |
1 files changed, 290 insertions, 290 deletions
diff --git a/src/textual.cc b/src/textual.cc index dba31323..5308fa18 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -49,26 +49,26 @@ namespace ledger { namespace { - typedef std::pair<commodity_t *, amount_t> fixed_rate_t; + typedef std::pair<commodity_t *, amount_t> fixed_rate_t; typedef variant<account_t *, string, fixed_rate_t> state_t; class parse_context_t : public noncopyable { public: - journal_t& journal; - scope_t& scope; + journal_t& journal; + scope_t& scope; std::list<state_t> state_stack; #if defined(TIMELOG_SUPPORT) - time_log_t timelog; + time_log_t timelog; #endif - bool strict; - std::size_t count; - std::size_t errors; - std::size_t sequence; + bool strict; + std::size_t count; + std::size_t errors; + std::size_t sequence; parse_context_t(journal_t& _journal, scope_t& _scope) : journal(_journal), scope(_scope), timelog(journal), - strict(false), count(0), errors(0), sequence(1) {} + strict(false), count(0), errors(0), sequence(1) {} bool front_is_account() { return state_stack.front().type() == typeid(account_t *); @@ -82,8 +82,8 @@ namespace { account_t * top_account() { foreach (state_t& state, state_stack) - if (state.type() == typeid(account_t *)) - return boost::get<account_t *>(state); + if (state.type() == typeid(account_t *)) + return boost::get<account_t *>(state); return NULL; } }; @@ -97,9 +97,9 @@ namespace { instance_t * parent; accounts_map account_aliases; const path * original_file; - path pathname; + path pathname; std::istream& in; - char linebuf[MAX_LINE + 1]; + char linebuf[MAX_LINE + 1]; std::size_t linenum; istream_pos_type line_beg_pos; istream_pos_type curr_pos; @@ -107,9 +107,9 @@ namespace { optional<date_t::year_type> current_year; instance_t(parse_context_t& _context, - std::istream& _in, - const path * _original_file = NULL, - instance_t * _parent = NULL); + std::istream& _in, + const path * _original_file = NULL, + instance_t * _parent = NULL); ~instance_t(); @@ -117,7 +117,7 @@ namespace { std::streamsize read_line(char *& line); bool peek_whitespace_line() { return (in.good() && ! in.eof() && - (in.peek() == ' ' || in.peek() == '\t')); + (in.peek() == ' ' || in.peek() == '\t')); } void read_next_directive(); @@ -148,31 +148,31 @@ namespace { void define_directive(char * line); bool general_directive(char * line); - post_t * parse_post(char * line, - std::streamsize len, - account_t * account, - xact_t * xact, - bool defer_expr = false); + post_t * parse_post(char * line, + std::streamsize len, + account_t * account, + xact_t * xact, + bool defer_expr = false); bool parse_posts(account_t * account, - xact_base_t& xact, - const bool defer_expr = false); + xact_base_t& xact, + const bool defer_expr = false); - xact_t * parse_xact(char * line, - std::streamsize len, - account_t * account); + xact_t * parse_xact(char * line, + std::streamsize len, + account_t * account); virtual expr_t::ptr_op_t lookup(const symbol_t::kind_t kind, - const string& name); + const string& name); }; - void parse_amount_expr(std::istream& in, - scope_t& scope, - post_t& post, - amount_t& amount, - const parse_flags_t& flags = PARSE_DEFAULT, - const bool defer_expr = false, - optional<expr_t> * amount_expr = NULL) + void parse_amount_expr(std::istream& in, + scope_t& scope, + post_t& post, + amount_t& amount, + const parse_flags_t& flags = PARSE_DEFAULT, + const bool defer_expr = false, + optional<expr_t> * amount_expr = NULL) { expr_t expr(in, flags.plus_flags(PARSE_PARTIAL)); @@ -181,25 +181,25 @@ namespace { #if defined(DEBUG_ENABLED) DEBUG_IF("textual.parse") { if (_debug_stream) { - ledger::dump_value_expr(*_debug_stream, expr); - *_debug_stream << std::endl; + ledger::dump_value_expr(*_debug_stream, expr); + *_debug_stream << std::endl; } } #endif if (expr) { if (amount_expr) - *amount_expr = expr; + *amount_expr = expr; if (! defer_expr) - amount = post.resolve_expr(scope, expr); + amount = post.resolve_expr(scope, expr); } } } instance_t::instance_t(parse_context_t& _context, - std::istream& _in, - const path * _original_file, - instance_t * _parent) + std::istream& _in, + const path * _original_file, + instance_t * _parent) : context(_context), parent(_parent), original_file(_original_file), pathname(original_file ? *original_file : "/dev/stdin"), in(_in) { @@ -216,7 +216,7 @@ void instance_t::parse() INFO("Parsing file '" << pathname.string() << "'"); TRACE_START(instance_parse, 1, - "Done parsing file '" << pathname.string() << "'"); + "Done parsing file '" << pathname.string() << "'"); if (! in.good() || in.eof()) return; @@ -232,30 +232,30 @@ void instance_t::parse() string current_context = error_context(); if (parent) { - std::list<instance_t *> instances; + std::list<instance_t *> instances; - for (instance_t * instance = parent; - instance; - instance = instance->parent) - instances.push_front(instance); + for (instance_t * instance = parent; + instance; + instance = instance->parent) + instances.push_front(instance); - foreach (instance_t * instance, instances) - add_error_context(_("In file included from %1") - << file_context(instance->pathname, - instance->linenum)); + foreach (instance_t * instance, instances) + add_error_context(_("In file included from %1") + << file_context(instance->pathname, + instance->linenum)); } add_error_context(_("While parsing file %1") - << file_context(pathname, linenum)); + << file_context(pathname, linenum)); if (caught_signal != NONE_CAUGHT) - throw; + throw; string err_context = error_context(); if (! err_context.empty()) - std::cerr << err_context << std::endl; + std::cerr << err_context << std::endl; if (! current_context.empty()) - std::cerr << current_context << std::endl; + std::cerr << current_context << std::endl; std::cerr << _("Error: ") << err.what() << std::endl; context.errors++; @@ -268,7 +268,7 @@ void instance_t::parse() std::streamsize instance_t::read_line(char *& line) { assert(in.good()); - assert(! in.eof()); // no one should call us in that case + assert(! in.eof()); // no one should call us in that case line_beg_pos = curr_pos; @@ -283,7 +283,7 @@ std::streamsize instance_t::read_line(char *& line) else line = linebuf; - if (line[len - 1] == '\r') // strip Windows CRLF down to LF + if (line[len - 1] == '\r') // strip Windows CRLF down to LF line[--len] = '\0'; linenum++; @@ -291,7 +291,7 @@ std::streamsize instance_t::read_line(char *& line) curr_pos = line_beg_pos; curr_pos += len; - return len - 1; // LF is being silently dropped + return len - 1; // LF is being silently dropped } return 0; } @@ -306,7 +306,7 @@ void instance_t::read_next_directive() switch (line[0]) { case '\0': - assert(false); // shouldn't ever reach here + assert(false); // shouldn't ever reach here break; case ' ': @@ -314,13 +314,13 @@ void instance_t::read_next_directive() break; } - case ';': // comments + case ';': // comments case '#': case '*': case '|': break; - case '-': // option setting + case '-': // option setting option_directive(line); break; @@ -336,10 +336,10 @@ void instance_t::read_next_directive() case '9': xact_directive(line, len); break; - case '=': // automated xact + case '=': // automated xact automated_xact_directive(line); break; - case '~': // period xact + case '~': // period xact period_xact_directive(line); break; @@ -347,47 +347,47 @@ void instance_t::read_next_directive() case '!': line++; // fall through... - default: // some other directive + default: // some other directive if (! general_directive(line)) { switch (line[0]) { #if defined(TIMELOG_SUPPORT) case 'i': - clock_in_directive(line, false); - break; + clock_in_directive(line, false); + break; case 'I': - clock_in_directive(line, true); - break; + clock_in_directive(line, true); + break; case 'o': - clock_out_directive(line, false); - break; + clock_out_directive(line, false); + break; case 'O': - clock_out_directive(line, true); - break; + clock_out_directive(line, true); + break; case 'h': case 'b': - break; + break; #endif // TIMELOG_SUPPORT - case 'A': // a default account for unbalanced posts - default_account_directive(line); - break; - case 'C': // a set of conversions - price_conversion_directive(line); - break; - case 'D': // a default commodity for "xact" - default_commodity_directive(line); - break; - case 'N': // don't download prices - nomarket_directive(line); - break; - case 'P': // a pricing xact - price_xact_directive(line); - break; - case 'Y': // set the current year - year_directive(line); - break; + case 'A': // a default account for unbalanced posts + default_account_directive(line); + break; + case 'C': // a set of conversions + price_conversion_directive(line); + break; + case 'D': // a default commodity for "xact" + default_commodity_directive(line); + break; + case 'N': // don't download prices + nomarket_directive(line); + break; + case 'P': // a pricing xact + price_xact_directive(line); + break; + case 'Y': // set the current year + year_directive(line); + break; } } break; @@ -418,9 +418,9 @@ void instance_t::clock_in_directive(char * line, bool /*capitalized*/) position.sequence = context.sequence++; time_xact_t event(position, parse_datetime(datetime, current_year), - p ? context.top_account()->find_account(p) : NULL, - n ? n : "", - end ? end : ""); + p ? context.top_account()->find_account(p) : NULL, + n ? n : "", + end ? end : ""); context.timelog.clock_in(event); } @@ -447,9 +447,9 @@ void instance_t::clock_out_directive(char * line, bool /*capitalized*/) position.sequence = context.sequence++; time_xact_t event(position, parse_datetime(datetime, current_year), - p ? context.top_account()->find_account(p) : NULL, - n ? n : "", - end ? end : ""); + p ? context.top_account()->find_account(p) : NULL, + n ? n : "", + end ? end : ""); context.timelog.clock_out(event); context.count++; @@ -526,8 +526,8 @@ void instance_t::automated_xact_directive(char * line) std::auto_ptr<auto_xact_t> ae (new auto_xact_t(query_t(string(skip_ws(line + 1)), - keep_details_t(true, true, true), false))); - ae->pos = position_t(); + keep_details_t(true, true, true), false))); + ae->pos = position_t(); ae->pos->pathname = pathname; ae->pos->beg_pos = line_beg_pos; ae->pos->beg_line = linenum; @@ -540,7 +540,7 @@ void instance_t::automated_xact_directive(char * line) context.journal.auto_xacts.push_back(ae.get()); - ae->journal = &context.journal; + ae->journal = &context.journal; ae->pos->end_pos = curr_pos; ae->pos->end_line = linenum; @@ -610,7 +610,7 @@ void instance_t::xact_directive(char * line, std::streamsize len) std::auto_ptr<xact_t> manager(xact); if (context.journal.add_xact(xact)) { - manager.release(); // it's owned by the journal now + manager.release(); // it's owned by the journal now context.count++; } // It's perfectly valid for the journal to reject the xact, which it will @@ -650,10 +650,10 @@ void instance_t::include_directive(char * line) mask_t glob; #if BOOST_VERSION >= 103700 - path parent_path = filename.parent_path(); + path parent_path = filename.parent_path(); glob.assign_glob(filename.filename()); #else // BOOST_VERSION >= 103700 - path parent_path = filename.branch_path(); + path parent_path = filename.branch_path(); glob.assign_glob(filename.leaf()); #endif // BOOST_VERSION >= 103700 @@ -661,33 +661,33 @@ void instance_t::include_directive(char * line) if (exists(parent_path)) { filesystem::directory_iterator end; for (filesystem::directory_iterator iter(parent_path); - iter != end; - ++iter) { + iter != end; + ++iter) { #if BOOST_VERSION <= 103500 if (is_regular(*iter)) #else if (is_regular_file(*iter)) #endif - { + { #if BOOST_VERSION >= 103700 - string base = (*iter).filename(); + string base = (*iter).filename(); #else // BOOST_VERSION >= 103700 - string base = (*iter).leaf(); + string base = (*iter).leaf(); #endif // BOOST_VERSION >= 103700 - if (glob.match(base)) { - path inner_file(*iter); - ifstream stream(inner_file); - instance_t instance(context, stream, &inner_file, this); - instance.parse(); - files_found = true; - } + if (glob.match(base)) { + path inner_file(*iter); + ifstream stream(inner_file); + instance_t instance(context, stream, &inner_file, this); + instance.parse(); + files_found = true; + } } } } if (! files_found) throw_(std::runtime_error, - _("File to include was not found: '%1'") << filename); + _("File to include was not found: '%1'") << filename); } @@ -707,17 +707,17 @@ void instance_t::end_directive(char * kind) if ((name.empty() || name == "account") && ! context.front_is_account()) throw_(std::runtime_error, - _("'end account' directive does not match open directive")); + _("'end account' directive does not match open directive")); else if (name == "tag" && ! context.front_is_string()) throw_(std::runtime_error, - _("'end tag' directive does not match open directive")); + _("'end tag' directive does not match open directive")); else if (name == "fixed" && ! context.front_is_fixed_rate()) throw_(std::runtime_error, - _("'end fixed' directive does not match open directive")); + _("'end fixed' directive does not match open directive")); if (context.state_stack.size() <= 1) throw_(std::runtime_error, - _("'end' found, but no enclosing tag or account directive")); + _("'end' found, but no enclosing tag or account directive")); else context.state_stack.pop_front(); } @@ -747,9 +747,9 @@ void instance_t::fixed_directive(char * line) { if (optional<std::pair<commodity_t *, price_point_t> > price_point = commodity_pool_t::current_pool->parse_price_directive(trim_ws(line), - true)) { + true)) { context.state_stack.push_front(fixed_rate_t(price_point->first, - price_point->second.price)); + price_point->second.price)); } else { throw_(std::runtime_error, _("Error in fixed directive")); } @@ -789,7 +789,7 @@ void instance_t::account_mapping_directive(char * line) if (payee_regex) context.journal.account_mappings.push_back (account_mapping_t(mask_t(payee_regex), - context.top_account()->find_account(account_name))); + context.top_account()->find_account(account_name))); while (peek_whitespace_line()) { #if defined(NO_ASSERTS) @@ -805,7 +805,7 @@ void instance_t::account_mapping_directive(char * line) context.journal.account_mappings.push_back (account_mapping_t(mask_t(payee_regex), - context.top_account()->find_account(account_name))); + context.top_account()->find_account(account_name))); } } @@ -822,7 +822,7 @@ void instance_t::tag_directive(char * line) void instance_t::define_directive(char * line) { expr_t def(skip_ws(line)); - def.compile(context.scope); // causes definitions to be established + def.compile(context.scope); // causes definitions to be established } bool instance_t::general_directive(char * line) @@ -923,18 +923,18 @@ bool instance_t::general_directive(char * line) return false; } -post_t * instance_t::parse_post(char * line, - std::streamsize len, - account_t * account, - xact_t * xact, - bool defer_expr) +post_t * instance_t::parse_post(char * line, + std::streamsize len, + account_t * account, + xact_t * xact, + bool defer_expr) { TRACE_START(post_details, 1, "Time spent parsing postings:"); std::auto_ptr<post_t> post(new post_t); - post->xact = xact; // this could be NULL - post->pos = position_t(); + post->xact = xact; // this could be NULL + post->pos = position_t(); post->pos->pathname = pathname; post->pos->beg_pos = line_beg_pos; post->pos->beg_line = linenum; @@ -958,14 +958,14 @@ post_t * instance_t::parse_post(char * line, post->set_state(item_t::CLEARED); p = skip_ws(p + 1); DEBUG("textual.parse", "line " << linenum << ": " - << "Parsed the CLEARED flag"); + << "Parsed the CLEARED flag"); break; case '!': post->set_state(item_t::PENDING); p = skip_ws(p + 1); DEBUG("textual.parse", "line " << linenum << ": " - << "Parsed the PENDING flag"); + << "Parsed the PENDING flag"); break; } @@ -988,19 +988,19 @@ post_t * instance_t::parse_post(char * line, if ((*p == '[' && *(e - 1) == ']') || (*p == '(' && *(e - 1) == ')')) { post->add_flags(POST_VIRTUAL); DEBUG("textual.parse", "line " << linenum << ": " - << "Parsed a virtual account name"); + << "Parsed a virtual account name"); if (*p == '[') { post->add_flags(POST_MUST_BALANCE); DEBUG("textual.parse", "line " << linenum << ": " - << "Posting must balance"); + << "Posting must balance"); } p++; e--; } string name(p, e - p); DEBUG("textual.parse", "line " << linenum << ": " - << "Parsed account name " << name); + << "Parsed account name " << name); if (account_aliases.size() > 0) { accounts_map::const_iterator i = account_aliases.find(name); @@ -1013,15 +1013,15 @@ post_t * instance_t::parse_post(char * line, if (context.strict && ! post->account->has_flags(ACCOUNT_KNOWN)) { if (post->_state == item_t::UNCLEARED) warning_(_("\"%1\", line %2: Unknown account '%3'") - << pathname << linenum << post->account->fullname()); + << pathname << linenum << post->account->fullname()); post->account->add_flags(ACCOUNT_KNOWN); } if (post->account->name == _("Unknown")) { foreach (account_mapping_t& value, context.journal.account_mappings) { if (value.first.match(xact->payee)) { - post->account = value.second; - break; + post->account = value.second; + break; } } } @@ -1036,39 +1036,39 @@ post_t * instance_t::parse_post(char * line, beg = next - line; ptristream stream(next, len - beg); - if (*next != '(') // indicates a value expression + if (*next != '(') // indicates a value expression post->amount.parse(stream, PARSE_NO_REDUCE); else parse_amount_expr(stream, context.scope, *post.get(), post->amount, - PARSE_NO_REDUCE | PARSE_SINGLE | PARSE_NO_ASSIGN, - defer_expr, &post->amount_expr); + PARSE_NO_REDUCE | PARSE_SINGLE | PARSE_NO_ASSIGN, + defer_expr, &post->amount_expr); if (! post->amount.is_null() && post->amount.has_commodity()) { if (context.strict && - ! post->amount.commodity().has_flags(COMMODITY_KNOWN)) { - if (post->_state == item_t::UNCLEARED) - warning_(_("\"%1\", line %2: Unknown commodity '%3'") - << pathname << linenum << post->amount.commodity()); - post->amount.commodity().add_flags(COMMODITY_KNOWN); + ! post->amount.commodity().has_flags(COMMODITY_KNOWN)) { + if (post->_state == item_t::UNCLEARED) + warning_(_("\"%1\", line %2: Unknown commodity '%3'") + << pathname << linenum << post->amount.commodity()); + post->amount.commodity().add_flags(COMMODITY_KNOWN); } if (! post->amount.has_annotation()) { - foreach (state_t& state, context.state_stack) { - if (state.type() == typeid(fixed_rate_t)) { - fixed_rate_t& rate(boost::get<fixed_rate_t>(state)); - if (*rate.first == post->amount.commodity()) { - annotation_t details(rate.second); - details.add_flags(ANNOTATION_PRICE_FIXATED); - post->amount.annotate(details); - break; - } - } - } + foreach (state_t& state, context.state_stack) { + if (state.type() == typeid(fixed_rate_t)) { + fixed_rate_t& rate(boost::get<fixed_rate_t>(state)); + if (*rate.first == post->amount.commodity()) { + annotation_t details(rate.second); + details.add_flags(ANNOTATION_PRICE_FIXATED); + post->amount.annotate(details); + break; + } + } + } } } DEBUG("textual.parse", "line " << linenum << ": " - << "post amount = " << post->amount); + << "post amount = " << post->amount); if (stream.eof()) { next = NULL; @@ -1078,73 +1078,73 @@ post_t * instance_t::parse_post(char * line, // Parse the optional cost (@ PER-UNIT-COST, @@ TOTAL-COST) if (*next == '@') { - DEBUG("textual.parse", "line " << linenum << ": " - << "Found a price indicator"); - - bool per_unit = true; - - if (*++next == '@') { - per_unit = false; - post->add_flags(POST_COST_IN_FULL); - DEBUG("textual.parse", "line " << linenum << ": " - << "And it's for a total price"); - } - - beg = ++next - line; - - p = skip_ws(next); - if (*p) { - post->cost = amount_t(); - - bool fixed_cost = false; - if (*p == '=') { - p++; - fixed_cost = true; - if (*p == '\0') - throw parse_error(_("Posting is missing a cost amount")); - } - - beg = p - line; - ptristream cstream(p, len - beg); - - if (*p != '(') // indicates a value expression - post->cost->parse(cstream, PARSE_NO_MIGRATE); - else - parse_amount_expr(cstream, context.scope, *post.get(), *post->cost, - PARSE_NO_MIGRATE | PARSE_SINGLE | PARSE_NO_ASSIGN); - - if (post->cost->sign() < 0) - throw parse_error(_("A posting's cost may not be negative")); - - post->cost->in_place_unround(); - - if (per_unit) { - // For the sole case where the cost might be uncommoditized, - // guarantee that the commodity of the cost after multiplication - // is the same as it was before. - commodity_t& cost_commodity(post->cost->commodity()); - *post->cost *= post->amount; - post->cost->set_commodity(cost_commodity); - } - else if (post->amount.sign() < 0) { - post->cost->in_place_negate(); - } - - if (fixed_cost) - post->add_flags(POST_COST_FIXATED); - - DEBUG("textual.parse", "line " << linenum << ": " - << "Total cost is " << *post->cost); - DEBUG("textual.parse", "line " << linenum << ": " - << "Annotated amount is " << post->amount); - - if (cstream.eof()) - next = NULL; - else - next = skip_ws(p + static_cast<std::ptrdiff_t>(cstream.tellg())); - } else { - throw parse_error(_("Expected a cost amount")); - } + DEBUG("textual.parse", "line " << linenum << ": " + << "Found a price indicator"); + + bool per_unit = true; + + if (*++next == '@') { + per_unit = false; + post->add_flags(POST_COST_IN_FULL); + DEBUG("textual.parse", "line " << linenum << ": " + << "And it's for a total price"); + } + + beg = ++next - line; + + p = skip_ws(next); + if (*p) { + post->cost = amount_t(); + + bool fixed_cost = false; + if (*p == '=') { + p++; + fixed_cost = true; + if (*p == '\0') + throw parse_error(_("Posting is missing a cost amount")); + } + + beg = p - line; + ptristream cstream(p, len - beg); + + if (*p != '(') // indicates a value expression + post->cost->parse(cstream, PARSE_NO_MIGRATE); + else + parse_amount_expr(cstream, context.scope, *post.get(), *post->cost, + PARSE_NO_MIGRATE | PARSE_SINGLE | PARSE_NO_ASSIGN); + + if (post->cost->sign() < 0) + throw parse_error(_("A posting's cost may not be negative")); + + post->cost->in_place_unround(); + + if (per_unit) { + // For the sole case where the cost might be uncommoditized, + // guarantee that the commodity of the cost after multiplication + // is the same as it was before. + commodity_t& cost_commodity(post->cost->commodity()); + *post->cost *= post->amount; + post->cost->set_commodity(cost_commodity); + } + else if (post->amount.sign() < 0) { + post->cost->in_place_negate(); + } + + if (fixed_cost) + post->add_flags(POST_COST_FIXATED); + + DEBUG("textual.parse", "line " << linenum << ": " + << "Total cost is " << *post->cost); + DEBUG("textual.parse", "line " << linenum << ": " + << "Annotated amount is " << post->amount); + + if (cstream.eof()) + next = NULL; + else + next = skip_ws(p + static_cast<std::ptrdiff_t>(cstream.tellg())); + } else { + throw parse_error(_("Expected a cost amount")); + } } } } @@ -1153,7 +1153,7 @@ post_t * instance_t::parse_post(char * line, if (xact && next && *next == '=') { DEBUG("textual.parse", "line " << linenum << ": " - << "Found a balance assignment indicator"); + << "Found a balance assignment indicator"); beg = ++next - line; @@ -1164,70 +1164,70 @@ post_t * instance_t::parse_post(char * line, beg = p - line; ptristream stream(p, len - beg); - if (*p != '(') // indicates a value expression - post->assigned_amount->parse(stream, PARSE_NO_MIGRATE); + if (*p != '(') // indicates a value expression + post->assigned_amount->parse(stream, PARSE_NO_MIGRATE); else - parse_amount_expr(stream, context.scope, *post.get(), - *post->assigned_amount, - PARSE_SINGLE | PARSE_NO_MIGRATE); + parse_amount_expr(stream, context.scope, *post.get(), + *post->assigned_amount, + PARSE_SINGLE | PARSE_NO_MIGRATE); if (post->assigned_amount->is_null()) { - if (post->amount.is_null()) - throw parse_error(_("Balance assignment must evaluate to a constant")); - else - throw parse_error(_("Balance assertion must evaluate to a constant")); + if (post->amount.is_null()) + throw parse_error(_("Balance assignment must evaluate to a constant")); + else + throw parse_error(_("Balance assertion must evaluate to a constant")); } DEBUG("textual.parse", "line " << linenum << ": " - << "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->amount(false).strip_annotations(keep_details_t())); + (post->account->amount(false).strip_annotations(keep_details_t())); DEBUG("post.assign", - "line " << linenum << ": " "account balance = " << account_total); + "line " << linenum << ": " "account balance = " << account_total); DEBUG("post.assign", - "line " << linenum << ": " "post amount = " << amt); + "line " << linenum << ": " "post amount = " << amt); amount_t diff = amt; switch (account_total.type()) { case value_t::AMOUNT: - diff -= account_total.as_amount(); - break; + diff -= account_total.as_amount(); + break; case value_t::BALANCE: - if (optional<amount_t> comm_bal = - account_total.as_balance().commodity_amount(amt.commodity())) - diff -= *comm_bal; - break; + if (optional<amount_t> comm_bal = + account_total.as_balance().commodity_amount(amt.commodity())) + diff -= *comm_bal; + break; default: - break; + break; } DEBUG("post.assign", - "line " << linenum << ": " << "diff = " << diff); + "line " << linenum << ": " << "diff = " << diff); DEBUG("textual.parse", - "line " << linenum << ": " << "POST assign: diff = " << diff); + "line " << linenum << ": " << "POST assign: diff = " << diff); if (! diff.is_zero()) { - if (! post->amount.is_null()) { - diff -= post->amount; - if (! diff.is_zero()) - throw_(parse_error, _("Balance assertion off by %1") << diff); - } else { - post->amount = diff; - DEBUG("textual.parse", "line " << linenum << ": " - << "Overwrite null posting"); - } + if (! post->amount.is_null()) { + diff -= post->amount; + if (! diff.is_zero()) + throw_(parse_error, _("Balance assertion off by %1") << diff); + } else { + post->amount = diff; + DEBUG("textual.parse", "line " << linenum << ": " + << "Overwrite null posting"); + } } if (stream.eof()) - next = NULL; + next = NULL; else - next = skip_ws(p + static_cast<std::ptrdiff_t>(stream.tellg())); + next = skip_ws(p + static_cast<std::ptrdiff_t>(stream.tellg())); } else { throw parse_error(_("Expected an balance assignment/assertion amount")); } @@ -1239,15 +1239,15 @@ post_t * instance_t::parse_post(char * line, post->append_note(++next, true, current_year); next = line + len; DEBUG("textual.parse", "line " << linenum << ": " - << "Parsed a posting note"); + << "Parsed a posting note"); } // There should be nothing more to read if (next && *next) throw_(parse_error, - _("Unexpected char '%1' (Note: inline math requires parentheses)") - << *next); + _("Unexpected char '%1' (Note: inline math requires parentheses)") + << *next); post->pos->end_pos = curr_pos; post->pos->end_line = linenum; @@ -1255,7 +1255,7 @@ post_t * instance_t::parse_post(char * line, if (! context.state_stack.empty()) { foreach (const state_t& state, context.state_stack) if (state.type() == typeid(string)) - post->parse_tags(boost::get<string>(state).c_str(), true); + post->parse_tags(boost::get<string>(state).c_str(), true); } TRACE_STOP(post_details, 1); @@ -1271,8 +1271,8 @@ post_t * instance_t::parse_post(char * line, } bool instance_t::parse_posts(account_t * account, - xact_base_t& xact, - const bool defer_expr) + xact_base_t& xact, + const bool defer_expr) { TRACE_START(xact_posts, 1, "Time spent parsing postings:"); @@ -1294,15 +1294,15 @@ bool instance_t::parse_posts(account_t * account, return added; } -xact_t * instance_t::parse_xact(char * line, - std::streamsize len, - account_t * account) +xact_t * instance_t::parse_xact(char * line, + std::streamsize len, + account_t * account) { TRACE_START(xact_text, 1, "Time spent parsing transaction text:"); std::auto_ptr<xact_t> xact(new xact_t); - xact->pos = position_t(); + xact->pos = position_t(); xact->pos->pathname = pathname; xact->pos->beg_pos = line_beg_pos; xact->pos->beg_line = linenum; @@ -1353,8 +1353,8 @@ xact_t * instance_t::parse_xact(char * line, char * p = next_element(next, true); foreach (payee_mapping_t& value, context.journal.payee_mappings) { if (value.first.match(next)) { - xact->payee = value.second; - break; + xact->payee = value.second; + break; } } if (xact->payee.empty()) @@ -1387,9 +1387,9 @@ xact_t * instance_t::parse_xact(char * line, if (*p == ';') { item_t * item; if (last_post) - item = last_post; + item = last_post; else - item = xact.get(); + item = xact.get(); // This is a trailing note, and possibly a metadata info tag item->append_note(p + 1, true, current_year); @@ -1399,9 +1399,9 @@ xact_t * instance_t::parse_xact(char * line, reveal_context = false; if (post_t * post = - parse_post(p, len - (p - line), account, xact.get())) { - xact->add_post(post); - last_post = post; + parse_post(p, len - (p - line), account, xact.get())) { + xact->add_post(post); + last_post = post; } } } @@ -1411,11 +1411,11 @@ xact_t * instance_t::parse_xact(char * line, foreach (post_t * post, xact->posts) { if (post->_state == item_t::UNCLEARED) { - result = item_t::UNCLEARED; - break; + result = item_t::UNCLEARED; + break; } else if (post->_state == item_t::PENDING) { - result = item_t::PENDING; + result = item_t::PENDING; } } } @@ -1426,7 +1426,7 @@ xact_t * instance_t::parse_xact(char * line, if (! context.state_stack.empty()) { foreach (const state_t& state, context.state_stack) if (state.type() == typeid(string)) - xact->parse_tags(boost::get<string>(state).c_str(), false); + xact->parse_tags(boost::get<string>(state).c_str(), false); } TRACE_STOP(xact_details, 1); @@ -1438,23 +1438,23 @@ xact_t * instance_t::parse_xact(char * line, if (reveal_context) { add_error_context(_("While parsing transaction:")); add_error_context(source_context(xact->pos->pathname, - xact->pos->beg_pos, curr_pos, "> ")); + xact->pos->beg_pos, curr_pos, "> ")); } throw; } } expr_t::ptr_op_t instance_t::lookup(const symbol_t::kind_t kind, - const string& name) + const string& name) { return context.scope.lookup(kind, name); } std::size_t journal_t::parse(std::istream& in, - scope_t& scope, - account_t * master, - const path * original_file, - bool strict) + scope_t& scope, + account_t * master, + const path * original_file, + bool strict) { TRACE_START(parsing_total, 1, "Total time spent parsing text:"); |