Add a position_t object for tracking item positions

It is also optional, which is useful for generated items.
This commit is contained in:
John Wiegley 2009-10-30 17:54:54 -04:00
parent 00886a32e7
commit cb6f7cd54e
7 changed files with 93 additions and 66 deletions

View file

@ -458,7 +458,7 @@ void account_t::xdata_t::details_t::update(post_t& post,
posts_virtuals_count++; posts_virtuals_count++;
if (gather_all) if (gather_all)
filenames.insert(post.pathname); filenames.insert(post.pos->pathname);
date_t date = post.date(); date_t date = post.date();

View file

@ -252,7 +252,7 @@ namespace {
if (tmpl.payee_mask.match((*j)->payee)) { if (tmpl.payee_mask.match((*j)->payee)) {
matching = *j; matching = *j;
DEBUG("derive.xact", DEBUG("derive.xact",
"Found payee match: transaction on line " << (*j)->beg_line); "Found payee match: transaction on line " << (*j)->pos->beg_line);
break; break;
} }
} }
@ -332,7 +332,7 @@ namespace {
if (post.account_mask->match(x->account->fullname())) { if (post.account_mask->match(x->account->fullname())) {
new_post.reset(new post_t(*x)); new_post.reset(new post_t(*x));
DEBUG("derive.xact", DEBUG("derive.xact",
"Founding posting from line " << x->beg_line); "Founding posting from line " << x->pos->beg_line);
break; break;
} }
} }

View file

@ -40,8 +40,8 @@ namespace ledger {
void format_emacs_posts::write_xact(xact_t& xact) void format_emacs_posts::write_xact(xact_t& xact)
{ {
out << "\"" << xact.pathname << "\" " out << "\"" << xact.pos->pathname << "\" "
<< (xact.beg_line + 1) << " "; << (xact.pos->beg_line + 1) << " ";
tm when = gregorian::to_tm(xact.date()); tm when = gregorian::to_tm(xact.date());
std::time_t date = std::mktime(&when); // jww (2008-04-20): Is this GMT or local? std::time_t date = std::mktime(&when); // jww (2008-04-20): Is this GMT or local?
@ -77,7 +77,7 @@ void format_emacs_posts::operator()(post_t& post)
out << "\n"; out << "\n";
} }
out << " (" << (post.beg_line + 1) << " "; out << " (" << (post.pos->beg_line + 1) << " ";
out << "\"" << post.reported_account()->fullname() << "\" \"" out << "\"" << post.reported_account()->fullname() << "\" \""
<< post.amount << "\""; << post.amount << "\"";

View file

@ -224,23 +224,26 @@ namespace {
} }
value_t get_pathname(item_t& item) { value_t get_pathname(item_t& item) {
return string_value(item.pathname.string()); if (item.pos)
return string_value(item.pos->pathname.string());
else
return string_value(empty_string);
} }
value_t get_beg_pos(item_t& item) { value_t get_beg_pos(item_t& item) {
return long(item.beg_pos); return item.pos ? long(item.pos->beg_pos) : 0L;
} }
value_t get_beg_line(item_t& item) { value_t get_beg_line(item_t& item) {
return long(item.beg_line); return item.pos ? long(item.pos->beg_line) : 0L;
} }
value_t get_end_pos(item_t& item) { value_t get_end_pos(item_t& item) {
return long(item.end_pos); return item.pos ? long(item.pos->end_pos) : 0L;
} }
value_t get_end_line(item_t& item) { value_t get_end_line(item_t& item) {
return long(item.end_line); return item.pos ? long(item.pos->end_line) : 0L;
} }
value_t get_depth(item_t&) { value_t get_depth(item_t&) {
@ -397,12 +400,13 @@ bool item_t::valid() const
void print_item(std::ostream& out, const item_t& item, const string& prefix) void print_item(std::ostream& out, const item_t& item, const string& prefix)
{ {
out << source_context(item.pathname, item.beg_pos, item.end_pos, prefix); out << source_context(item.pos->pathname, item.pos->beg_pos,
item.pos->end_pos, prefix);
} }
string item_context(const item_t& item, const string& desc) string item_context(const item_t& item, const string& desc)
{ {
std::streamoff len = item.end_pos - item.beg_pos; std::streamoff len = item.pos->end_pos - item.pos->beg_pos;
if (! len) if (! len)
return _("<no item context>"); return _("<no item context>");
@ -411,18 +415,18 @@ string item_context(const item_t& item, const string& desc)
std::ostringstream out; std::ostringstream out;
if (item.pathname == path("/dev/stdin")) { if (item.pos->pathname == path("/dev/stdin")) {
out << desc << _(" from standard input:"); out << desc << _(" from standard input:");
return out.str(); return out.str();
} }
out << desc << _(" from \"") << item.pathname.string() << "\""; out << desc << _(" from \"") << item.pos->pathname.string() << "\"";
if (item.beg_line != item.end_line) if (item.pos->beg_line != item.pos->end_line)
out << _(", lines ") << item.beg_line << "-" out << _(", lines ") << item.pos->beg_line << "-"
<< item.end_line << ":\n"; << item.pos->end_line << ":\n";
else else
out << _(", line ") << item.beg_line << ":\n"; out << _(", line ") << item.pos->beg_line << ":\n";
print_item(out, item, "> "); print_item(out, item, "> ");

View file

@ -50,6 +50,37 @@
namespace ledger { namespace ledger {
struct position_t
{
path pathname;
istream_pos_type beg_pos;
std::size_t beg_line;
istream_pos_type end_pos;
std::size_t end_line;
position_t() : beg_pos(0), beg_line(0), end_pos(0), end_line(0) {
TRACE_CTOR(position_t, "");
}
position_t(const position_t& pos) {
TRACE_CTOR(position_t, "copy");
*this = pos;
}
~position_t() throw() {
TRACE_DTOR(position_t);
}
position_t& operator=(const position_t& pos) {
if (this != &pos) {
pathname = pos.pathname;
beg_pos = pos.beg_pos;
beg_line = pos.beg_line;
end_pos = pos.end_pos;
end_line = pos.end_line;
}
return *this;
}
};
/** /**
* @brief Brief * @brief Brief
* *
@ -65,24 +96,17 @@ public:
enum state_t { UNCLEARED = 0, CLEARED, PENDING }; enum state_t { UNCLEARED = 0, CLEARED, PENDING };
state_t _state;
optional<date_t> _date;
optional<date_t> _date_eff;
optional<string> note;
typedef std::map<string, optional<string> > string_map; typedef std::map<string, optional<string> > string_map;
state_t _state;
optional<date_t> _date;
optional<date_t> _date_eff;
optional<string> note;
optional<position_t> pos;
optional<string_map> metadata; optional<string_map> metadata;
path pathname;
istream_pos_type beg_pos;
std::size_t beg_line;
istream_pos_type end_pos;
std::size_t end_line;
item_t(flags_t _flags = ITEM_NORMAL, const optional<string>& _note = none) item_t(flags_t _flags = ITEM_NORMAL, const optional<string>& _note = none)
: supports_flags<>(_flags), _state(UNCLEARED), note(_note), : supports_flags<>(_flags), _state(UNCLEARED), note(_note)
beg_pos(0), beg_line(0), end_pos(0), end_line(0)
{ {
TRACE_CTOR(item_t, "flags_t, const string&"); TRACE_CTOR(item_t, "flags_t, const string&");
} }
@ -103,12 +127,7 @@ public:
_date = item._date; _date = item._date;
_date_eff = item._date_eff; _date_eff = item._date_eff;
note = item.note; note = item.note;
pos = item.pos;
pathname = item.pathname;
beg_pos = item.beg_pos;
beg_line = item.beg_line;
end_pos = item.end_pos;
end_line = item.end_line;
} }
virtual bool operator==(const item_t& xact) { virtual bool operator==(const item_t& xact) {

View file

@ -525,11 +525,12 @@ void instance_t::automated_xact_directive(char * line)
journal.auto_xacts.push_back(ae.get()); journal.auto_xacts.push_back(ae.get());
ae->pathname = pathname; ae->pos = position_t();
ae->beg_pos = pos; ae->pos->pathname = pathname;
ae->beg_line = lnum; ae->pos->beg_pos = pos;
ae->end_pos = curr_pos; ae->pos->beg_line = lnum;
ae->end_line = linenum; ae->pos->end_pos = curr_pos;
ae->pos->end_line = linenum;
ae.release(); ae.release();
} }
@ -565,11 +566,12 @@ void instance_t::period_xact_directive(char * line)
journal.period_xacts.push_back(pe.get()); journal.period_xacts.push_back(pe.get());
pe->pathname = pathname; pe->pos = position_t();
pe->beg_pos = pos; pe->pos->pathname = pathname;
pe->beg_line = lnum; pe->pos->beg_pos = pos;
pe->end_pos = curr_pos; pe->pos->beg_line = lnum;
pe->end_line = linenum; pe->pos->end_pos = curr_pos;
pe->pos->end_line = linenum;
pe.release(); pe.release();
} else { } else {
@ -778,10 +780,11 @@ post_t * instance_t::parse_post(char * line,
std::auto_ptr<post_t> post(new post_t); std::auto_ptr<post_t> post(new post_t);
post->xact = xact; // this could be NULL post->xact = xact; // this could be NULL
post->pathname = pathname; post->pos = position_t();
post->beg_pos = line_beg_pos; post->pos->pathname = pathname;
post->beg_line = linenum; post->pos->beg_pos = line_beg_pos;
post->pos->beg_line = linenum;
char buf[MAX_LINE + 1]; char buf[MAX_LINE + 1];
std::strcpy(buf, line); std::strcpy(buf, line);
@ -1056,8 +1059,8 @@ post_t * instance_t::parse_post(char * line,
_("Unexpected char '%1' (Note: inline math requires parentheses)") _("Unexpected char '%1' (Note: inline math requires parentheses)")
<< *next); << *next);
post->end_pos = curr_pos; post->pos->end_pos = curr_pos;
post->end_line = linenum; post->pos->end_line = linenum;
if (! tag_stack.empty()) { if (! tag_stack.empty()) {
foreach (const string& tag, tag_stack) foreach (const string& tag, tag_stack)
@ -1107,9 +1110,10 @@ xact_t * instance_t::parse_xact(char * line,
std::auto_ptr<xact_t> xact(new xact_t); std::auto_ptr<xact_t> xact(new xact_t);
xact->pathname = pathname; xact->pos = position_t();
xact->beg_pos = line_beg_pos; xact->pos->pathname = pathname;
xact->beg_line = linenum; xact->pos->beg_pos = line_beg_pos;
xact->pos->beg_line = linenum;
bool reveal_context = true; bool reveal_context = true;
@ -1189,8 +1193,8 @@ xact_t * instance_t::parse_xact(char * line,
// This is a trailing note, and possibly a metadata info tag // This is a trailing note, and possibly a metadata info tag
item->append_note(p + 1, current_year); item->append_note(p + 1, current_year);
item->end_pos = curr_pos; item->pos->end_pos = curr_pos;
item->end_line++; item->pos->end_line++;
} else { } else {
reveal_context = false; reveal_context = false;
@ -1216,8 +1220,8 @@ xact_t * instance_t::parse_xact(char * line,
} }
} }
xact->end_pos = curr_pos; xact->pos->end_pos = curr_pos;
xact->end_line = linenum; xact->pos->end_line = linenum;
if (! tag_stack.empty()) { if (! tag_stack.empty()) {
foreach (const string& tag, tag_stack) foreach (const string& tag, tag_stack)
@ -1232,8 +1236,8 @@ xact_t * instance_t::parse_xact(char * line,
catch (const std::exception& err) { catch (const std::exception& err) {
if (reveal_context) { if (reveal_context) {
add_error_context(_("While parsing transaction:")); add_error_context(_("While parsing transaction:"));
add_error_context(source_context(xact->pathname, add_error_context(source_context(xact->pos->pathname,
xact->beg_pos, curr_pos, "> ")); xact->pos->beg_pos, curr_pos, "> "));
} }
throw; throw;
} }

View file

@ -499,7 +499,7 @@ void auto_xact_t::extend_xact(xact_base_t& xact, bool post_handler)
IF_DEBUG("xact.extend") { IF_DEBUG("xact.extend") {
DEBUG("xact.extend", DEBUG("xact.extend",
"Initial post on line " << initial_post->beg_line << ": " "Initial post on line " << initial_post->pos->beg_line << ": "
<< "amount " << initial_post->amount << " (precision " << "amount " << initial_post->amount << " (precision "
<< initial_post->amount.precision() << ")"); << initial_post->amount.precision() << ")");
@ -509,7 +509,7 @@ void auto_xact_t::extend_xact(xact_base_t& xact, bool post_handler)
#endif #endif
DEBUG("xact.extend", DEBUG("xact.extend",
"Posting on line " << post->beg_line << ": " "Posting on line " << post->pos->beg_line << ": "
<< "amount " << post->amount << ", amt " << amt << "amount " << post->amount << ", amt " << amt
<< " (precision " << post->amount.precision() << " (precision " << post->amount.precision()
<< " != " << amt.precision() << ")"); << " != " << amt.precision() << ")");