summaryrefslogtreecommitdiff
path: root/ledger.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2004-05-13 18:37:12 -0400
committerjohnw <johnw@newartisans.com>2004-05-13 18:37:12 -0400
commit9ca1d24d30a485300b9486b18c068660da630cc1 (patch)
tree50d29d69278934be7e318a565d6223a6a0ab2c36 /ledger.cc
parent31dafc3c163e4ceae42b1477c4eaeb4425b2b883 (diff)
downloadfork-ledger-9ca1d24d30a485300b9486b18c068660da630cc1.tar.gz
fork-ledger-9ca1d24d30a485300b9486b18c068660da630cc1.tar.bz2
fork-ledger-9ca1d24d30a485300b9486b18c068660da630cc1.zip
initial import into Darcs
Diffstat (limited to 'ledger.cc')
-rw-r--r--ledger.cc108
1 files changed, 42 insertions, 66 deletions
diff --git a/ledger.cc b/ledger.cc
index cc295e04..8df3392a 100644
--- a/ledger.cc
+++ b/ledger.cc
@@ -213,9 +213,9 @@ bool entry::finalize(bool do_compute)
(*x)->acct->balance.credit((*x)->cost);
}
- // If virtual accounts are being supported, walk through the
- // transactions and create new virtual transactions for all that
- // apply.
+ // If automated transactions are being used, walk through the
+ // current transaction lines and create new transactions for all
+ // that match.
for (book::virtual_map_iterator m = ledger->virtual_mapping.begin();
m != ledger->virtual_mapping.end();
@@ -278,7 +278,7 @@ bool entry::finalize(bool do_compute)
return true;
}
-bool entry::matches(const regexps_map& regexps) const
+bool entry::matches(const regexps_list& regexps) const
{
if (regexps.empty() || (ledger::matches(regexps, code) ||
ledger::matches(regexps, desc))) {
@@ -290,7 +290,7 @@ bool entry::matches(const regexps_map& regexps) const
for (std::list<transaction *>::const_iterator x = xacts.begin();
x != xacts.end();
x++) {
- if (ledger::matches(regexps, (*x)->acct->name) ||
+ if (ledger::matches(regexps, (*x)->acct->as_str()) ||
ledger::matches(regexps, (*x)->note)) {
match = true;
break;
@@ -331,6 +331,12 @@ void totals::credit(const totals& other)
credit((*i).second);
}
+void totals::negate()
+{
+ for (const_iterator i = amounts.begin(); i != amounts.end(); i++)
+ (*i).second->negate();
+}
+
bool totals::is_zero() const
{
for (const_iterator i = amounts.begin(); i != amounts.end(); i++)
@@ -339,6 +345,19 @@ bool totals::is_zero() const
return true;
}
+bool totals::is_negative() const
+{
+ bool all_negative = true;
+ bool some_negative = false;
+ for (const_iterator i = amounts.begin(); i != amounts.end(); i++) {
+ if ((*i).second->is_negative())
+ some_negative = true;
+ else if (! (*i).second->is_zero())
+ all_negative = false;
+ }
+ return some_negative && all_negative;
+}
+
void totals::print(std::ostream& out, int width) const
{
bool first = true;
@@ -365,10 +384,12 @@ account::~account()
delete (*i).second;
}
-const std::string account::as_str() const
+const std::string account::as_str(const account * stop) const
{
- if (! parent)
+ if (! parent || this == stop)
return name;
+ else if (stop)
+ return parent->as_str(stop) + ":" + name;
else if (full_name.empty())
full_name = parent->as_str() + ":" + name;
@@ -409,20 +430,6 @@ mask::mask(const mask& m) : exclude(m.exclude), pattern(m.pattern)
assert(regexp);
}
-void read_regexps(const std::string& path, regexps_map& regexps)
-{
- if (access(path.c_str(), R_OK) != -1) {
- std::ifstream file(path.c_str());
-
- while (! file.eof()) {
- char buf[80];
- file.getline(buf, 79);
- if (*buf && ! std::isspace(*buf))
- regexps.push_back(mask(buf));
- }
- }
-}
-
bool mask::match(const std::string& str) const
{
static int ovec[30];
@@ -431,67 +438,36 @@ bool mask::match(const std::string& str) const
return result >= 0 && ! exclude;
}
-bool matches(const regexps_map& regexps, const std::string& str,
+bool matches(const regexps_list& regexps, const std::string& str,
bool * by_exclusion)
{
- assert(! regexps.empty());
+ if (regexps.empty())
+ return false;
bool match = false;
bool definite = false;
-// std::ofstream out("regex.out", std::ios_base::app);
-// out << "Matching against: " << str << std::endl;
-
- for (regexps_map_const_iterator r = regexps.begin();
+ for (regexps_list_const_iterator r = regexps.begin();
r != regexps.end();
r++) {
-// out << " Trying: " << (*r).pattern << std::endl;
-
static int ovec[30];
int result = pcre_exec((*r).regexp, NULL, str.c_str(), str.length(),
0, 0, ovec, 30);
if (result >= 0) {
-// out << " Definite ";
-
- match = ! (*r).exclude;
-// if (match)
-// out << "match";
-// else
-// out << "unmatch";
-
- definite = true;
- } else {
- assert(result == -1);
-
-// out << " failure code = " << result << std::endl;
-
- if ((*r).exclude) {
- if (! match) {
- match = ! definite;
-// if (match)
-// out << " indefinite match by exclusion" << std::endl;
- }
- } else {
- definite = true;
- }
+ match = ! (*r).exclude;
+ definite = true;
}
-
-// out << " Current status: "
-// << (definite ? "definite " : "")
-// << (match ? "match" : "not match") << std::endl;
- }
-
- if (by_exclusion) {
- if (match && ! definite && by_exclusion) {
-// out << " Note: Matched by exclusion rule" << std::endl;
- *by_exclusion = true;
- } else {
- *by_exclusion = false;
+ else if ((*r).exclude) {
+ if (! match)
+ match = ! definite;
+ }
+ else {
+ definite = true;
}
}
-// out << " Final result: " << (match ? "match" : "not match")
-// << std::endl;
+ if (by_exclusion)
+ *by_exclusion = match && ! definite && by_exclusion;
return match;
}