further reorganization
This commit is contained in:
parent
dd5680c267
commit
d7dd02276c
5 changed files with 230 additions and 242 deletions
|
|
@ -200,6 +200,10 @@ bool constraints_t::operator ()(const item_t * item) const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
// jww (2004-07-26): It shouldn't be necessary to check against the
|
||||||
|
// account here, since this is always done during initial compiling
|
||||||
|
// of the item_t tree.
|
||||||
|
|
||||||
if (! account_masks.empty()) {
|
if (! account_masks.empty()) {
|
||||||
bool match = false;
|
bool match = false;
|
||||||
|
|
||||||
|
|
|
||||||
37
item.cc
37
item.cc
|
|
@ -8,8 +8,7 @@ namespace ledger {
|
||||||
// subaccounts, empty balanced or no
|
// subaccounts, empty balanced or no
|
||||||
|
|
||||||
item_t * walk_accounts(const account_t * account,
|
item_t * walk_accounts(const account_t * account,
|
||||||
const constraints_t& constraints,
|
const constraints_t& constraints)
|
||||||
const bool compute_subtotals)
|
|
||||||
{
|
{
|
||||||
item_t * item = new item_t;
|
item_t * item = new item_t;
|
||||||
item->account = account;
|
item->account = account;
|
||||||
|
|
@ -21,64 +20,60 @@ item_t * walk_accounts(const account_t * account,
|
||||||
i != account->transactions.end();
|
i != account->transactions.end();
|
||||||
i++) {
|
i++) {
|
||||||
item->value += *(*i);
|
item->value += *(*i);
|
||||||
if (compute_subtotals)
|
if (constraints.show_subtotals)
|
||||||
item->total += *(*i);
|
item->total += *(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (accounts_map::const_iterator i = account->accounts.begin();
|
for (accounts_map::const_iterator i = account->accounts.begin();
|
||||||
i != account->accounts.end();
|
i != account->accounts.end();
|
||||||
i++) {
|
i++) {
|
||||||
item_t * subitem = walk_accounts((*i).second, constraints,
|
item_t * subitem = walk_accounts((*i).second, constraints);
|
||||||
compute_subtotals);
|
|
||||||
subitem->parent = item;
|
subitem->parent = item;
|
||||||
|
|
||||||
if (compute_subtotals)
|
if (constraints.show_subtotals)
|
||||||
item->total += subitem->total;
|
item->total += subitem->total;
|
||||||
|
|
||||||
if (compute_subtotals ? subitem->total : subitem->value)
|
if (constraints.show_subtotals ? subitem->total : subitem->value)
|
||||||
item->subitems.push_back(subitem);
|
item->subitems.push_back(subitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sum_items(const item_t * top,
|
static inline void sum_items(const item_t * top,
|
||||||
item_t * item,
|
const constraints_t& constraints,
|
||||||
const bool compute_subtotals)
|
item_t * item)
|
||||||
{
|
{
|
||||||
if (top->account == item->account) {
|
if (top->account == item->account) {
|
||||||
item->value += top->value;
|
item->value += top->value;
|
||||||
if (compute_subtotals)
|
if (constraints.show_subtotals)
|
||||||
item->total += top->value;
|
item->total += top->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (items_deque::const_iterator i = top->subitems.begin();
|
for (items_deque::const_iterator i = top->subitems.begin();
|
||||||
i != top->subitems.end();
|
i != top->subitems.end();
|
||||||
i++)
|
i++)
|
||||||
sum_items(*i, item, compute_subtotals);
|
sum_items(*i, constraints, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
item_t * walk_items(const item_t * top,
|
item_t * walk_items(const item_t * top, const account_t * account,
|
||||||
const account_t * account,
|
const constraints_t& constraints)
|
||||||
const constraints_t& constraints,
|
|
||||||
const bool compute_subtotals)
|
|
||||||
{
|
{
|
||||||
item_t * item = new item_t;
|
item_t * item = new item_t;
|
||||||
item->account = account;
|
item->account = account;
|
||||||
|
|
||||||
sum_items(top, item, compute_subtotals);
|
sum_items(top, constraints, item);
|
||||||
|
|
||||||
for (accounts_map::const_iterator i = account->accounts.begin();
|
for (accounts_map::const_iterator i = account->accounts.begin();
|
||||||
i != account->accounts.end();
|
i != account->accounts.end();
|
||||||
i++) {
|
i++) {
|
||||||
item_t * subitem = walk_items(top, (*i).second, constraints,
|
item_t * subitem = walk_items(top, (*i).second, constraints);
|
||||||
compute_subtotals);
|
|
||||||
subitem->parent = item;
|
subitem->parent = item;
|
||||||
|
|
||||||
if (compute_subtotals)
|
if (constraints.show_subtotals)
|
||||||
item->total += subitem->total;
|
item->total += subitem->total;
|
||||||
|
|
||||||
if (compute_subtotals ? subitem->total : subitem->value)
|
if (constraints.show_subtotals ? subitem->total : subitem->value)
|
||||||
item->subitems.push_back(subitem);
|
item->subitems.push_back(subitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
15
item.h
15
item.h
|
|
@ -15,6 +15,8 @@ typedef std::deque<item_t *> items_deque;
|
||||||
struct item_t
|
struct item_t
|
||||||
{
|
{
|
||||||
struct item_t * parent;
|
struct item_t * parent;
|
||||||
|
items_deque subitems;
|
||||||
|
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
std::time_t date;
|
std::time_t date;
|
||||||
std::string payee;
|
std::string payee;
|
||||||
|
|
@ -22,8 +24,6 @@ struct item_t
|
||||||
balance_pair_t value;
|
balance_pair_t value;
|
||||||
balance_pair_t total;
|
balance_pair_t total;
|
||||||
|
|
||||||
items_deque subitems;
|
|
||||||
|
|
||||||
item_t() : parent(NULL), index(0), date(-1), account(NULL) {}
|
item_t() : parent(NULL), index(0), date(-1), account(NULL) {}
|
||||||
|
|
||||||
~item_t() {
|
~item_t() {
|
||||||
|
|
@ -38,14 +38,11 @@ struct item_t
|
||||||
|
|
||||||
class constraints_t;
|
class constraints_t;
|
||||||
|
|
||||||
item_t * walk_accounts(const account_t * account,
|
item_t * walk_accounts(const account_t * account,
|
||||||
const constraints_t& constraints,
|
const constraints_t& constraints);
|
||||||
const bool compute_subtotals);
|
|
||||||
|
|
||||||
item_t * walk_items(const item_t * top,
|
item_t * walk_items(const item_t * top, const account_t * account,
|
||||||
const account_t * account,
|
const constraints_t& constraints);
|
||||||
const constraints_t& constraints,
|
|
||||||
const bool compute_subtotals);
|
|
||||||
|
|
||||||
item_t * walk_entries(entries_list::const_iterator begin,
|
item_t * walk_entries(entries_list::const_iterator begin,
|
||||||
entries_list::const_iterator end,
|
entries_list::const_iterator end,
|
||||||
|
|
|
||||||
17
main.cc
17
main.cc
|
|
@ -504,10 +504,10 @@ static void show_help(std::ostream& out)
|
||||||
|
|
||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
std::list<std::string> files;
|
std::list<std::string> files;
|
||||||
ledger::ledger_t * book = NULL;
|
ledger::ledger_t * book = NULL;
|
||||||
ledger::constraints_t constraints;
|
ledger::constraints_t constraints;
|
||||||
ledger::format_t format;
|
ledger::format_t format;
|
||||||
|
|
||||||
std::string sort_order;
|
std::string sort_order;
|
||||||
std::string value_style = "a";
|
std::string value_style = "a";
|
||||||
|
|
@ -826,8 +826,7 @@ int main(int argc, char * argv[])
|
||||||
else if (command == "equity") {
|
else if (command == "equity") {
|
||||||
#if 0
|
#if 0
|
||||||
ledger::item_t * top
|
ledger::item_t * top
|
||||||
= ledger::walk_accounts(book->master, constraints,
|
= ledger::walk_accounts(book->master, constraints);
|
||||||
constraints.show_subtotals);
|
|
||||||
|
|
||||||
ledger::entry_report(std::cout, top, constraints, format);
|
ledger::entry_report(std::cout, top, constraints, format);
|
||||||
|
|
||||||
|
|
@ -843,8 +842,7 @@ int main(int argc, char * argv[])
|
||||||
format.format_string = ledger::bal_fmt;
|
format.format_string = ledger::bal_fmt;
|
||||||
|
|
||||||
if (ledger::item_t * top
|
if (ledger::item_t * top
|
||||||
= ledger::walk_accounts(book->master, constraints,
|
= ledger::walk_accounts(book->master, constraints)) {
|
||||||
constraints.show_subtotals)) {
|
|
||||||
ledger::balance_report(std::cout, top, constraints, format);
|
ledger::balance_report(std::cout, top, constraints, format);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
delete top;
|
delete top;
|
||||||
|
|
@ -859,8 +857,7 @@ int main(int argc, char * argv[])
|
||||||
= ledger::walk_entries(book->entries.begin(),
|
= ledger::walk_entries(book->entries.begin(),
|
||||||
book->entries.end(), constraints))
|
book->entries.end(), constraints))
|
||||||
if (ledger::item_t * top
|
if (ledger::item_t * top
|
||||||
= ledger::walk_items(list, book->master, constraints,
|
= ledger::walk_items(list, book->master, constraints)) {
|
||||||
constraints.show_subtotals)) {
|
|
||||||
ledger::balance_report(std::cout, top, constraints, format);
|
ledger::balance_report(std::cout, top, constraints, format);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
delete top;
|
delete top;
|
||||||
|
|
|
||||||
399
textual.cc
399
textual.cc
|
|
@ -1,6 +1,6 @@
|
||||||
#include "ledger.h"
|
|
||||||
#include "constraint.h"
|
|
||||||
#include "textual.h"
|
#include "textual.h"
|
||||||
|
#include "constraint.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static const std::string entry1_fmt = "%?10d %p";
|
static const std::string entry1_fmt = "%10d %p";
|
||||||
static const std::string entryn_fmt = " %-30a %15t";
|
static const std::string entryn_fmt = " %-30a %15t";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -360,13 +360,11 @@ void parse_automated_transactions(std::istream& in, ledger_t * ledger,
|
||||||
|
|
||||||
while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t')) {
|
while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t')) {
|
||||||
if (transaction_t * xact = parse_transaction(in, ledger, account, NULL)) {
|
if (transaction_t * xact = parse_transaction(in, ledger, account, NULL)) {
|
||||||
if (! xact->amount) {
|
if (! xact->amount)
|
||||||
std::cerr << "Error in " << path << ", line " << (linenum - 1)
|
throw parse_error(path, linenum,
|
||||||
<< ": All automated transactions must have a value."
|
"All automated transactions must have a value");
|
||||||
<< std::endl;
|
else
|
||||||
} else {
|
|
||||||
xacts.push_back(xact);
|
xacts.push_back(xact);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,11 +459,8 @@ entry_t * parse_entry(std::istream& in, ledger_t * ledger,
|
||||||
|
|
||||||
char * next = next_element(line);
|
char * next = next_element(line);
|
||||||
|
|
||||||
if (! quick_parse_date(line, &curr->date)) {
|
if (! quick_parse_date(line, &curr->date))
|
||||||
std::cerr << "Error in " << path << ", line " << (linenum - 1)
|
throw parse_error(path, linenum, "Failed to parse date");
|
||||||
<< ": Failed to parse date: " << line << std::endl;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the optional cleared flag: *
|
// Parse the optional cleared flag: *
|
||||||
|
|
||||||
|
|
@ -532,241 +527,241 @@ unsigned int parse_textual_ledger(std::istream& in, ledger_t *& ledger,
|
||||||
linenum = 1;
|
linenum = 1;
|
||||||
|
|
||||||
while (! in.eof()) {
|
while (! in.eof()) {
|
||||||
switch (in.peek()) {
|
try {
|
||||||
case -1: // end of file
|
switch (in.peek()) {
|
||||||
goto done;
|
case -1: // end of file
|
||||||
|
goto done;
|
||||||
|
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
if (peek_next_nonws(in) != '\n') {
|
if (peek_next_nonws(in) != '\n') {
|
||||||
std::cerr << "Error in " << path << ", line " << (linenum - 1)
|
in.getline(line, MAX_LINE);
|
||||||
<< ": Ignoring entry beginning with whitespace."
|
linenum++;
|
||||||
<< std::endl;
|
throw parse_error(path, linenum,
|
||||||
in.getline(line, MAX_LINE);
|
"Ignoring entry beginning with whitespace");
|
||||||
|
}
|
||||||
|
// fall through...
|
||||||
|
|
||||||
|
case '\n':
|
||||||
linenum++;
|
linenum++;
|
||||||
|
case '\r': // skip blank lines
|
||||||
|
in.get(c);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
// fall through...
|
|
||||||
|
|
||||||
case '\n':
|
|
||||||
linenum++;
|
|
||||||
case '\r': // skip blank lines
|
|
||||||
in.get(c);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef TIMELOG_SUPPORT
|
#ifdef TIMELOG_SUPPORT
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'I': {
|
case 'I': {
|
||||||
std::string date, time;
|
|
||||||
|
|
||||||
in >> c;
|
|
||||||
in >> date;
|
|
||||||
in >> time;
|
|
||||||
date += " ";
|
|
||||||
date += time;
|
|
||||||
|
|
||||||
in.getline(line, MAX_LINE);
|
|
||||||
linenum++;
|
|
||||||
|
|
||||||
char * p = skip_ws(line);
|
|
||||||
char * n = next_element(p, true);
|
|
||||||
last_desc = n ? n : "";
|
|
||||||
|
|
||||||
static struct std::tm when;
|
|
||||||
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
|
|
||||||
time_in = std::mktime(&when);
|
|
||||||
last_account = account_stack.front()->find_account(p);
|
|
||||||
} else {
|
|
||||||
std::cerr << "Error in " << path << ", line " << (linenum - 1)
|
|
||||||
<< ": Cannot parse timelog entry date." << std::endl;
|
|
||||||
last_account = NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'o':
|
|
||||||
case 'O':
|
|
||||||
if (last_account) {
|
|
||||||
std::string date, time;
|
std::string date, time;
|
||||||
|
|
||||||
in >> c;
|
in >> c;
|
||||||
in >> date;
|
in >> date;
|
||||||
in >> time;
|
in >> time;
|
||||||
|
|
||||||
in.getline(line, MAX_LINE);
|
|
||||||
linenum++;
|
|
||||||
|
|
||||||
date += " ";
|
date += " ";
|
||||||
date += time;
|
date += time;
|
||||||
|
|
||||||
|
in.getline(line, MAX_LINE);
|
||||||
|
linenum++;
|
||||||
|
|
||||||
|
char * p = skip_ws(line);
|
||||||
|
char * n = next_element(p, true);
|
||||||
|
last_desc = n ? n : "";
|
||||||
|
|
||||||
static struct std::tm when;
|
static struct std::tm when;
|
||||||
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
|
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
|
||||||
entry_t * curr = new entry_t;
|
time_in = std::mktime(&when);
|
||||||
curr->date = std::mktime(&when);
|
last_account = account_stack.front()->find_account(p);
|
||||||
curr->state = entry_t::CLEARED;
|
|
||||||
curr->code = "";
|
|
||||||
curr->payee = last_desc;
|
|
||||||
|
|
||||||
double diff = std::difftime(curr->date, time_in) / 60.0 / 60.0;
|
|
||||||
char buf[32];
|
|
||||||
std::sprintf(buf, "%fh", diff);
|
|
||||||
amount_t amt;
|
|
||||||
amt.parse(buf, ledger);
|
|
||||||
time_commodity = amt.commodity;
|
|
||||||
|
|
||||||
transaction_t * xact = new transaction_t(curr, last_account, amt, amt,
|
|
||||||
TRANSACTION_VIRTUAL);
|
|
||||||
curr->add_transaction(xact);
|
|
||||||
|
|
||||||
if (! finalize_entry(curr) || ! ledger->add_entry(curr))
|
|
||||||
assert(0);
|
|
||||||
|
|
||||||
count++;
|
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Error in " << path << ", line " << (linenum - 1)
|
last_account = NULL;
|
||||||
<< ": Cannot parse timelog entry date." << std::endl;
|
throw parse_error(path, linenum, "Cannot parse timelog entry date");
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
last_account = NULL;
|
|
||||||
} else {
|
|
||||||
in.getline(line, MAX_LINE);
|
|
||||||
linenum++;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
if (last_account) {
|
||||||
|
std::string date, time;
|
||||||
|
|
||||||
|
in >> c;
|
||||||
|
in >> date;
|
||||||
|
in >> time;
|
||||||
|
|
||||||
|
in.getline(line, MAX_LINE);
|
||||||
|
linenum++;
|
||||||
|
|
||||||
|
date += " ";
|
||||||
|
date += time;
|
||||||
|
|
||||||
|
static struct std::tm when;
|
||||||
|
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
|
||||||
|
entry_t * curr = new entry_t;
|
||||||
|
curr->date = std::mktime(&when);
|
||||||
|
curr->state = entry_t::CLEARED;
|
||||||
|
curr->code = "";
|
||||||
|
curr->payee = last_desc;
|
||||||
|
|
||||||
|
double diff = std::difftime(curr->date, time_in) / 60.0 / 60.0;
|
||||||
|
char buf[32];
|
||||||
|
std::sprintf(buf, "%fh", diff);
|
||||||
|
amount_t amt;
|
||||||
|
amt.parse(buf, ledger);
|
||||||
|
time_commodity = amt.commodity;
|
||||||
|
|
||||||
|
transaction_t * xact = new transaction_t(curr, last_account, amt, amt,
|
||||||
|
TRANSACTION_VIRTUAL);
|
||||||
|
curr->add_transaction(xact);
|
||||||
|
|
||||||
|
if (! finalize_entry(curr) || ! ledger->add_entry(curr))
|
||||||
|
assert(0);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
throw parse_error(path, linenum, "Cannot parse timelog entry date");
|
||||||
|
}
|
||||||
|
|
||||||
|
last_account = NULL;
|
||||||
|
} else {
|
||||||
|
in.getline(line, MAX_LINE);
|
||||||
|
linenum++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif // TIMELOG_SUPPORT
|
#endif // TIMELOG_SUPPORT
|
||||||
|
|
||||||
case 'P': { // a pricing entry
|
case 'P': { // a pricing entry
|
||||||
in >> c;
|
in >> c;
|
||||||
|
|
||||||
std::time_t date;
|
std::time_t date;
|
||||||
std::string symbol;
|
std::string symbol;
|
||||||
|
|
||||||
in >> line; // the date
|
in >> line; // the date
|
||||||
if (! quick_parse_date(line, &date)) {
|
if (! quick_parse_date(line, &date))
|
||||||
std::cerr << "Error in " << path << ", line " << (linenum - 1)
|
throw parse_error(path, linenum, "Failed to parse date");
|
||||||
<< ": Failed to parse date: " << line << std::endl;
|
|
||||||
|
int hour, min, sec;
|
||||||
|
|
||||||
|
in >> hour; // the time
|
||||||
|
in >> c;
|
||||||
|
in >> min;
|
||||||
|
in >> c;
|
||||||
|
in >> sec;
|
||||||
|
|
||||||
|
date = std::time_t(((unsigned long) date) +
|
||||||
|
hour * 3600 + min * 60 + sec);
|
||||||
|
|
||||||
|
amount_t price;
|
||||||
|
|
||||||
|
parse_commodity(in, symbol);
|
||||||
|
in >> line; // the price
|
||||||
|
price.parse(line, ledger);
|
||||||
|
|
||||||
|
commodity_t * commodity = ledger->find_commodity(symbol, true);
|
||||||
|
commodity->add_price(date, price);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hour, min, sec;
|
case 'N': { // don't download prices
|
||||||
|
std::string symbol;
|
||||||
|
|
||||||
in >> hour; // the time
|
in >> c;
|
||||||
in >> c;
|
parse_commodity(in, symbol);
|
||||||
in >> min;
|
|
||||||
in >> c;
|
|
||||||
in >> sec;
|
|
||||||
|
|
||||||
date = std::time_t(((unsigned long) date) +
|
commodity_t * commodity = ledger->find_commodity(line, true);
|
||||||
hour * 3600 + min * 60 + sec);
|
commodity->flags |= (COMMODITY_STYLE_CONSULTED |
|
||||||
|
COMMODITY_STYLE_NOMARKET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
amount_t price;
|
case 'C': { // a flat conversion
|
||||||
|
in >> c;
|
||||||
|
|
||||||
parse_commodity(in, symbol);
|
std::string symbol;
|
||||||
in >> line; // the price
|
amount_t price;
|
||||||
price.parse(line, ledger);
|
|
||||||
|
|
||||||
commodity_t * commodity = ledger->find_commodity(symbol, true);
|
parse_commodity(in, symbol);
|
||||||
commodity->add_price(date, price);
|
in >> line; // the price
|
||||||
break;
|
price.parse(line, ledger);
|
||||||
}
|
|
||||||
|
|
||||||
case 'N': { // don't download prices
|
commodity_t * commodity = ledger->find_commodity(symbol, true);
|
||||||
std::string symbol;
|
commodity->set_conversion(price);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
in >> c;
|
case 'Y': // set the current year
|
||||||
parse_commodity(in, symbol);
|
in >> c;
|
||||||
|
in >> now_tm->tm_year;
|
||||||
commodity_t * commodity = ledger->find_commodity(line, true);
|
now_tm->tm_year -= 1900;
|
||||||
commodity->flags |= (COMMODITY_STYLE_CONSULTED |
|
break;
|
||||||
COMMODITY_STYLE_NOMARKET);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'C': { // a flat conversion
|
|
||||||
in >> c;
|
|
||||||
|
|
||||||
std::string symbol;
|
|
||||||
amount_t price;
|
|
||||||
|
|
||||||
parse_commodity(in, symbol);
|
|
||||||
in >> line; // the price
|
|
||||||
price.parse(line, ledger);
|
|
||||||
|
|
||||||
commodity_t * commodity = ledger->find_commodity(symbol, true);
|
|
||||||
commodity->set_conversion(price);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'Y': // set the current year
|
|
||||||
in >> c;
|
|
||||||
in >> now_tm->tm_year;
|
|
||||||
now_tm->tm_year -= 1900;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef TIMELOG_SUPPORT
|
#ifdef TIMELOG_SUPPORT
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'b':
|
case 'b':
|
||||||
#endif
|
#endif
|
||||||
case ';': // a comment line
|
case ';': // a comment line
|
||||||
in.getline(line, MAX_LINE);
|
in.getline(line, MAX_LINE);
|
||||||
linenum++;
|
linenum++;
|
||||||
break;
|
|
||||||
|
|
||||||
case '=': // automated transactions
|
|
||||||
parse_automated_transactions(in, ledger, account_stack.front(),
|
|
||||||
auto_xacts);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '@': { // account specific
|
|
||||||
in >> c;
|
|
||||||
if (in.peek() == '@') {
|
|
||||||
in.get(c);
|
|
||||||
account_stack.pop_front();
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
in.getline(line, MAX_LINE);
|
case '=': // automated transactions
|
||||||
linenum++;
|
parse_automated_transactions(in, ledger, account_stack.front(),
|
||||||
|
auto_xacts);
|
||||||
|
break;
|
||||||
|
|
||||||
account_t * acct = account_stack.front()->find_account(skip_ws(line));
|
case '@': { // account specific
|
||||||
account_stack.push_front(acct);
|
in >> c;
|
||||||
break;
|
if (in.peek() == '@') {
|
||||||
}
|
in.get(c);
|
||||||
|
account_stack.pop_front();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case '!': // directive
|
|
||||||
in >> line;
|
|
||||||
if (std::string(line) == "!include") {
|
|
||||||
in.getline(line, MAX_LINE);
|
in.getline(line, MAX_LINE);
|
||||||
linenum++;
|
linenum++;
|
||||||
|
|
||||||
char * path = skip_ws(line);
|
account_t * acct = account_stack.front()->find_account(skip_ws(line));
|
||||||
std::ifstream stream(path);
|
account_stack.push_front(acct);
|
||||||
|
break;
|
||||||
ledger->sources.push_back(path);
|
|
||||||
|
|
||||||
unsigned int curr_linenum = linenum;
|
|
||||||
count += parse_textual_ledger(stream, ledger, account_stack.front());
|
|
||||||
linenum = curr_linenum;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default: {
|
case '!': // directive
|
||||||
unsigned int first_line = linenum;
|
in >> line;
|
||||||
if (entry_t * entry = parse_entry(in, ledger, account_stack.front())) {
|
if (std::string(line) == "!include") {
|
||||||
if (! auto_xacts.automated_transactions.empty())
|
in.getline(line, MAX_LINE);
|
||||||
auto_xacts.extend_entry(entry);
|
linenum++;
|
||||||
|
|
||||||
if (ledger->add_entry(entry))
|
char * p = skip_ws(line);
|
||||||
count++;
|
std::ifstream stream(p);
|
||||||
else
|
|
||||||
std::cerr << "Error in " << path << ", line " << first_line
|
ledger->sources.push_back(p);
|
||||||
<< ": Entry does not balance." << std::endl;
|
|
||||||
} else {
|
unsigned int curr_linenum = linenum;
|
||||||
std::cerr << "Error in " << path << ", line " << first_line
|
std::string curr_path = path;
|
||||||
<< ": Failed to parse entry." << std::endl;
|
|
||||||
|
count += parse_textual_ledger(stream, ledger, account_stack.front());
|
||||||
|
|
||||||
|
linenum = curr_linenum;
|
||||||
|
path = curr_path;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
unsigned int first_line = linenum;
|
||||||
|
if (entry_t * entry = parse_entry(in, ledger, account_stack.front())) {
|
||||||
|
if (! auto_xacts.automated_transactions.empty())
|
||||||
|
auto_xacts.extend_entry(entry);
|
||||||
|
|
||||||
|
if (ledger->add_entry(entry))
|
||||||
|
count++;
|
||||||
|
else
|
||||||
|
throw parse_error(path, first_line, "Entry does not balance");
|
||||||
|
} else {
|
||||||
|
throw parse_error(path, first_line, "Failed to parse entry");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
catch (const parse_error& err) {
|
||||||
|
std::cerr << err.what() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue