Simplified the textual parser, and improved metadata support.

This commit is contained in:
John Wiegley 2009-02-04 03:34:37 -04:00
parent 28da097fc2
commit 1cc33531ea
9 changed files with 451 additions and 548 deletions

View file

@ -50,21 +50,21 @@ string file_context(const path& file, std::size_t line)
return buf.str();
}
string line_context(const string& line,
istream_pos_type pos,
istream_pos_type end_pos)
string line_context(const string& line,
std::size_t pos,
std::size_t end_pos)
{
std::ostringstream buf;
buf << " " << line << "\n";
if (pos != istream_pos_type(0)) {
if (pos != 0) {
buf << " ";
if (end_pos == istream_pos_type(0)) {
for (istream_pos_type i = 0; i < pos; i += 1)
if (end_pos == 0) {
for (std::size_t i = 0; i < pos; i += 1)
buf << " ";
buf << "^";
} else {
for (istream_pos_type i = 0; i < end_pos; i += 1) {
for (std::size_t i = 0; i < end_pos; i += 1) {
if (i >= pos)
buf << "^";
else

View file

@ -68,9 +68,9 @@ extern std::ostringstream _ctxt_buffer;
string error_context();
string file_context(const path& file, std::size_t line);
string line_context(const string& line,
istream_pos_type pos = istream_pos_type(0),
istream_pos_type end_pos = istream_pos_type(0));
string line_context(const string& line,
std::size_t pos = 0,
std::size_t end_pos = 0);
#define DECLARE_EXCEPTION(name, kind) \
class name : public kind { \

View file

@ -71,6 +71,21 @@ void item_t::set_tag(const string& tag,
void item_t::parse_tags(const char * p)
{
if (char * b = std::strchr(p, '[')) {
if (char * e = std::strchr(p, ']')) {
char buf[256];
std::strncpy(buf, b + 1, e - b - 1);
buf[e - b - 1] = '\0';
if (char * p = std::strchr(buf, '=')) {
*p++ = '\0';
_date_eff = parse_date(p);
}
if (buf[0])
_date = parse_date(buf);
}
}
if (! std::strchr(p, ':'))
return;
@ -99,6 +114,17 @@ void item_t::parse_tags(const char * p)
}
}
void item_t::append_note(const char * p)
{
if (note)
*note += p;
else
note = p;
*note += '\n';
parse_tags(p);
}
namespace {
value_t get_status(item_t& item) {
return long(item.state());
@ -325,9 +351,9 @@ string item_context(const item_t& item)
out << "While balancing item from \"" << item.pathname.string()
<< "\"";
if (item.beg_line != (item.end_line - 1))
if (item.beg_line != item.end_line)
out << ", lines " << item.beg_line << "-"
<< (item.end_line - 1) << ":\n";
<< item.end_line << ":\n";
else
out << ", line " << item.beg_line << ":\n";

View file

@ -127,13 +127,7 @@ public:
virtual void set_tag(const string& tag,
const optional<string>& value = none);
virtual void parse_tags(const char * p);
virtual void append_note(const char * p) {
if (note)
*note += p;
else
note = p;
}
virtual void append_note(const char * p);
virtual optional<date_t> actual_date() const {
return _date;

View file

@ -113,7 +113,9 @@ public:
TRACE_DTOR(journal_t::parser_t);
}
#if defined(TEST_FOR_PARSER)
virtual bool test(std::istream& in) const = 0;
#endif
virtual std::size_t parse(std::istream& in,
session_t& session,
@ -122,18 +124,6 @@ public:
const path * original_file = NULL) = 0;
};
class binary_parser_t : public parser_t
{
public:
virtual bool test(std::istream& in) const;
virtual std::size_t parse(std::istream& in,
session_t& session,
journal_t& journal,
account_t * master = NULL,
const path * original_file = NULL);
};
bool valid() const;
};

View file

@ -148,7 +148,9 @@ std::size_t session_t::read_journal(journal_t& journal,
master = journal.master;
foreach (journal_t::parser_t& parser, parsers)
#if defined(TEST_FOR_PARSER)
if (parser.test(in))
#endif
return parser.parse(in, *this, journal, master, &pathname);
return 0;

File diff suppressed because it is too large Load diff

View file

@ -65,7 +65,9 @@ class time_log_t;
class textual_parser_t : public journal_t::parser_t
{
public:
#if defined(TEST_FOR_PARSER)
virtual bool test(std::istream& in) const;
#endif
virtual std::size_t parse(std::istream& in,
session_t& session,
@ -93,15 +95,13 @@ protected:
accounts_map account_aliases;
path pathname;
char linebuf[MAX_LINE + 1];
std::size_t linenum;
istream_pos_type beg_pos;
std::size_t beg_line;
istream_pos_type end_pos;
istream_pos_type line_beg_pos;
istream_pos_type curr_pos;
std::size_t count;
std::size_t errors;
char linebuf[MAX_LINE + 1];
scoped_ptr<auto_entry_finalizer_t> auto_entry_finalizer;
instance_t(std::list<account_t *>& _account_stack,
@ -118,6 +118,11 @@ protected:
~instance_t();
void parse();
std::streamsize read_line(char *& line);
bool peek_whitespace_line() {
return (in.good() && ! in.eof() &&
(in.peek() == ' ' || in.peek() == '\t'));
}
void read_next_directive();
#if defined(TIMELOG_SUPPORT)
@ -134,7 +139,7 @@ protected:
void option_directive(char * line);
void automated_entry_directive(char * line);
void period_entry_directive(char * line);
void entry_directive(char * line);
void entry_directive(char * line, std::streamsize len);
void include_directive(char * line);
void account_directive(char * line);
void end_directive(char * line);
@ -142,20 +147,18 @@ protected:
void define_directive(char * line);
void general_directive(char * line);
xact_t * parse_xact(char * line,
account_t * account,
entry_t * entry);
xact_t * parse_xact(char * line,
std::streamsize len,
account_t * account,
entry_t * entry);
bool parse_xacts(std::istream& in,
account_t * account,
entry_base_t& entry,
const string& kind,
istream_pos_type beg_pos);
bool parse_xacts(account_t * account,
entry_base_t& entry,
const string& kind);
entry_t * parse_entry(std::istream& in,
char * line,
account_t * master,
istream_pos_type& pos);
entry_t * parse_entry(char * line,
std::streamsize len,
account_t * account);
virtual expr_t::ptr_op_t lookup(const string& name);
};

View file

@ -73,17 +73,8 @@ public:
account_t * account;
amount_t amount; // can be null until finalization
#if defined(STORE_XACT_EXPRS)
optional<expr_t> amount_expr;
#endif
optional<amount_t> cost;
#if defined(STORE_XACT_EXPRS)
optional<expr_t> cost_expr;
#endif
optional<amount_t> assigned_amount;
#if defined(STORE_XACT_EXPRS)
optional<expr_t> assigned_amount_expr;
#endif
xact_t(account_t * _account = NULL,
flags_t _flags = ITEM_NORMAL)