summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-02-14 05:37:53 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-02-14 05:37:53 -0400
commitee5e0600aaa63859b9452d981ea9dd29b581b216 (patch)
tree91f087a8c701f6dca8ddf2e35a4bba107866bb3e
parent67d63366cb1c7e1bc528f625c28437ca19ab927e (diff)
downloadfork-ledger-ee5e0600aaa63859b9452d981ea9dd29b581b216.tar.gz
fork-ledger-ee5e0600aaa63859b9452d981ea9dd29b581b216.tar.bz2
fork-ledger-ee5e0600aaa63859b9452d981ea9dd29b581b216.zip
xact metadata searches get passed up to the entry
That is, if a metadata tag cannot be found in a transaction, look in the parent entry to see if it was set there. Transactions "inherit" notational details from their entries.
-rw-r--r--src/item.cc94
-rw-r--r--src/item.h7
-rw-r--r--src/value.cc3
-rw-r--r--src/xact.cc38
-rw-r--r--src/xact.h8
5 files changed, 108 insertions, 42 deletions
diff --git a/src/item.cc b/src/item.cc
index 48694727..e997d13e 100644
--- a/src/item.cc
+++ b/src/item.cc
@@ -37,18 +37,61 @@ bool item_t::use_effective_date = false;
bool item_t::has_tag(const string& tag) const
{
- if (! metadata)
+ DEBUG("item.meta", "Checking if item has tag: " << tag);
+ if (! metadata) {
+ DEBUG("item.meta", "Item has no metadata at all");
return false;
+ }
string_map::const_iterator i = metadata->find(tag);
+ if (SHOW_DEBUG("item.meta")) {
+ if (i == metadata->end())
+ DEBUG("item.meta", "Item does not have this tag");
+ else
+ DEBUG("item.meta", "Item has the tag!");
+ }
return i != metadata->end();
}
+bool item_t::has_tag(const mask_t& tag_mask,
+ const optional<mask_t>& value_mask) const
+{
+ if (metadata) {
+ foreach (const string_map::value_type& data, *metadata) {
+ if (tag_mask.match(data.first)) {
+ if (! value_mask)
+ return true;
+ else if (data.second)
+ return value_mask->match(*data.second);
+ }
+ }
+ }
+ return false;
+}
+
optional<string> item_t::get_tag(const string& tag) const
{
+ DEBUG("item.meta", "Getting item tag: " << tag);
if (metadata) {
+ DEBUG("item.meta", "Item has metadata");
string_map::const_iterator i = metadata->find(tag);
- if (i != metadata->end())
+ if (i != metadata->end()) {
+ DEBUG("item.meta", "Found the item!");
return (*i).second;
+ }
+ }
+ return none;
+}
+
+optional<string> item_t::get_tag(const mask_t& tag_mask,
+ const optional<mask_t>& value_mask) const
+{
+ if (metadata) {
+ foreach (const string_map::value_type& data, *metadata) {
+ if (tag_mask.match(data.first) &&
+ (! value_mask ||
+ (data.second && value_mask->match(*data.second))))
+ return data.second;
+ }
}
return none;
}
@@ -146,48 +189,15 @@ namespace {
value_t has_tag(call_scope_t& args) {
item_t& item(find_scope<item_t>(args));
- if (! item.metadata)
- return false;
-
- IF_DEBUG("item.meta") {
- foreach (const item_t::string_map::value_type& data, *item.metadata) {
- *_log_stream << " Tag: " << data.first << "\n";
- *_log_stream << "Value: ";
- if (data.second)
- *_log_stream << *data.second << "\n";
- else
- *_log_stream << "<none>\n";
- }
- }
-
- value_t& arg(args[0]);
- if (arg.is_string()) {
- if (args.size() == 1) {
+ if (args.size() == 1) {
+ if (args[0].is_string())
return item.has_tag(args[0].as_string());
- }
- else if (optional<string> tag = item.get_tag(args[0].as_string())) {
- if (args[1].is_string()) {
- return args[1].as_string() == *tag;
- }
- else if (args[1].is_mask()) {
- return args[1].as_mask().match(*tag);
- }
- }
- }
- else if (arg.is_mask()) {
- foreach (const item_t::string_map::value_type& data, *item.metadata) {
- if (arg.as_mask().match(data.first)) {
- if (args.size() == 1)
- return true;
- else if (data.second) {
- if (args[1].is_string())
- return args[1].as_string() == *data.second;
- else if (args[1].is_mask())
- return args[1].as_mask().match(*data.second);
- }
- }
- }
+ else if (args[0].is_mask())
+ return item.has_tag(args[0].as_mask());
+ } else {
+ return item.has_tag(args[0].to_mask(),
+ args[1].to_mask());
}
return false;
}
diff --git a/src/item.h b/src/item.h
index 9621b541..96e0899b 100644
--- a/src/item.h
+++ b/src/item.h
@@ -120,9 +120,16 @@ public:
}
virtual bool has_tag(const string& tag) const;
+ virtual bool has_tag(const mask_t& tag_mask,
+ const optional<mask_t>& value_mask = none) const;
+
virtual optional<string> get_tag(const string& tag) const;
+ virtual optional<string> get_tag(const mask_t& tag_mask,
+ const optional<mask_t>& value_mask = none) const;
+
virtual void set_tag(const string& tag,
const optional<string>& value = none);
+
virtual void parse_tags(const char * p, int current_year = -1);
virtual void append_note(const char * p, int current_year = -1);
diff --git a/src/value.cc b/src/value.cc
index cb45660e..6e4574ca 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -943,6 +943,9 @@ void value_t::in_place_cast(type_t cast_type)
case AMOUNT:
set_amount(amount_t(as_string()));
return;
+ case MASK:
+ set_mask(as_string());
+ return;
default:
break;
}
diff --git a/src/xact.cc b/src/xact.cc
index 24846cf2..0e287962 100644
--- a/src/xact.cc
+++ b/src/xact.cc
@@ -36,6 +36,44 @@
namespace ledger {
+bool xact_t::has_tag(const string& tag) const
+{
+ if (item_t::has_tag(tag))
+ return true;
+ if (entry)
+ return entry->has_tag(tag);
+ return false;
+}
+
+bool xact_t::has_tag(const mask_t& tag_mask,
+ const optional<mask_t>& value_mask) const
+{
+ if (item_t::has_tag(tag_mask, value_mask))
+ return true;
+ if (entry)
+ return entry->has_tag(tag_mask, value_mask);
+ return false;
+}
+
+optional<string> xact_t::get_tag(const string& tag) const
+{
+ if (optional<string> value = item_t::get_tag(tag))
+ return value;
+ if (entry)
+ return entry->get_tag(tag);
+ return none;
+}
+
+optional<string> xact_t::get_tag(const mask_t& tag_mask,
+ const optional<mask_t>& value_mask) const
+{
+ if (optional<string> value = item_t::get_tag(tag_mask, value_mask))
+ return value;
+ if (entry)
+ return entry->get_tag(tag_mask, value_mask);
+ return none;
+}
+
date_t xact_t::date() const
{
if (item_t::use_effective_date) {
diff --git a/src/xact.h b/src/xact.h
index cb89b512..11bd289d 100644
--- a/src/xact.h
+++ b/src/xact.h
@@ -107,6 +107,14 @@ public:
TRACE_DTOR(xact_t);
}
+ virtual bool has_tag(const string& tag) const;
+ virtual bool has_tag(const mask_t& tag_mask,
+ const optional<mask_t>& value_mask = none) const;
+
+ virtual optional<string> get_tag(const string& tag) const;
+ virtual optional<string> get_tag(const mask_t& tag_mask,
+ const optional<mask_t>& value_mask = none) const;
+
virtual date_t date() const;
virtual optional<date_t> effective_date() const;