diff options
Diffstat (limited to 'src/expr.cc')
-rw-r--r-- | src/expr.cc | 106 |
1 files changed, 77 insertions, 29 deletions
diff --git a/src/expr.cc b/src/expr.cc index f3a30de6..b3d4abcd 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -33,11 +33,12 @@ #include "expr.h" #include "parser.h" +#include "scope.h" namespace ledger { void expr_t::parse(std::istream& in, const parse_flags_t& flags, - const optional<string>& original_string) + const optional<string>& original_string) { parser_t parser; istream_pos_type start_pos = in.tellg(); @@ -52,8 +53,9 @@ void expr_t::parse(std::istream& in, const parse_flags_t& flags, in.seekg(start_pos, std::ios::beg); scoped_array<char> buf (new char[static_cast<std::size_t>(end_pos - start_pos) + 1]); - in.read(buf.get(), end_pos - start_pos); - buf[end_pos - start_pos] = '\0'; + int len = static_cast<int>(end_pos) - static_cast<int>(start_pos); + in.read(buf.get(), len); + buf[len] = '\0'; set_text(buf.get()); } else { @@ -76,33 +78,38 @@ value_t expr_t::real_calc(scope_t& scope) try { return ptr->calc(scope, &locus); } - catch (const std::exception& err) { + catch (const std::exception&) { if (locus) { - add_error_context(_("While evaluating value expression:")); - add_error_context(op_context(ptr, locus)); - - if (SHOW_INFO()) { - add_error_context(_("The value expression tree was:")); - std::ostringstream buf; - ptr->dump(buf, 0); - - std::istringstream in(buf.str()); - std::ostringstream out; - char linebuf[1024]; - bool first = true; - while (in.good() && ! in.eof()) { - in.getline(linebuf, 1023); - std::streamsize len = in.gcount(); - if (len > 0) { - if (first) - first = false; - else - out << '\n'; - out << " " << linebuf; - } - } - add_error_context(out.str()); - } + string current_context = error_context(); + + add_error_context(_("While evaluating value expression:")); + add_error_context(op_context(ptr, locus)); + + if (SHOW_INFO()) { + add_error_context(_("The value expression tree was:")); + std::ostringstream buf; + ptr->dump(buf, 0); + + std::istringstream in(buf.str()); + std::ostringstream out; + char linebuf[1024]; + bool first = true; + while (in.good() && ! in.eof()) { + in.getline(linebuf, 1023); + std::streamsize len = in.gcount(); + if (len > 0) { + if (first) + first = false; + else + out << '\n'; + out << " " << linebuf; + } + } + add_error_context(out.str()); + } + + if (! current_context.empty()) + add_error_context(current_context); } throw; } @@ -156,4 +163,45 @@ void expr_t::dump(std::ostream& out) const if (ptr) ptr->dump(out, 0); } +value_t source_command(call_scope_t& args) +{ + std::istream * in = NULL; + scoped_ptr<ifstream> stream; + string pathname; + + if (args.has(0)) { + pathname = args.get<string>(0); + stream.reset(new ifstream(path(pathname))); + in = stream.get(); + } else { + pathname = "<stdin>"; + in = &std::cin; + } + + symbol_scope_t file_locals(args); + std::size_t linenum = 0; + char buf[4096]; + istream_pos_type pos; + + while (in->good() && ! in->eof()) { + pos = in->tellg(); + in->getline(buf, 4095); + linenum++; + + char * p = skip_ws(buf); + if (*p && *p != ';') { + try { + expr_t(p).calc(file_locals); + } + catch (const std::exception&) { + add_error_context(_("While parsing value expression on line %1:") + << linenum); + add_error_context(source_context(pathname, pos, in->tellg(), "> ")); + } + } + } + + return true; +} + } // namespace ledger |