summaryrefslogtreecommitdiff
path: root/src/item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/item.cc')
-rw-r--r--src/item.cc55
1 files changed, 37 insertions, 18 deletions
diff --git a/src/item.cc b/src/item.cc
index 8d1ba34f..14a0896f 100644
--- a/src/item.cc
+++ b/src/item.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2009, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2010, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -65,8 +65,8 @@ bool item_t::has_tag(const mask_t& tag_mask,
if (tag_mask.match(data.first)) {
if (! value_mask)
return true;
- else if (data.second)
- return value_mask->match(*data.second);
+ else if (data.second.first)
+ return value_mask->match(*data.second.first);
}
}
}
@@ -81,7 +81,7 @@ optional<string> item_t::get_tag(const string& tag) const
string_map::const_iterator i = metadata->find(tag);
if (i != metadata->end()) {
DEBUG("item.meta", "Found the item!");
- return (*i).second;
+ return (*i).second.first;
}
}
return none;
@@ -94,28 +94,44 @@ optional<string> item_t::get_tag(const mask_t& tag_mask,
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;
+ (data.second.first && value_mask->match(*data.second.first))))
+ return data.second.first;
}
}
return none;
}
-void item_t::set_tag(const string& tag,
- const optional<string>& value)
+item_t::string_map::iterator
+item_t::set_tag(const string& tag,
+ const optional<string>& value,
+ const bool overwrite_existing)
{
+ assert(! tag.empty());
+
if (! metadata)
metadata = string_map();
DEBUG("item.meta", "Setting tag '" << tag << "' to value '"
<< (value ? *value : string("<none>")) << "'");
- std::pair<string_map::iterator, bool> result
- = metadata->insert(string_map::value_type(tag, value));
- assert(result.second);
+ optional<string> data = value;
+ if (data && data->empty())
+ data = none;
+
+ string_map::iterator i = metadata->find(tag);
+ if (i == metadata->end()) {
+ std::pair<string_map::iterator, bool> result
+ = metadata->insert(string_map::value_type(tag, tag_data_t(data, false)));
+ assert(result.second);
+ return result.first;
+ } else {
+ if (overwrite_existing)
+ (*i).second = tag_data_t(data, false);
+ return i;
+ }
}
-void item_t::parse_tags(const char * p,
+void item_t::parse_tags(const char * p, bool overwrite_existing,
optional<date_t::year_type> current_year)
{
if (const char * b = std::strchr(p, '[')) {
@@ -149,15 +165,18 @@ void item_t::parse_tags(const char * p,
q = std::strtok(NULL, " \t")) {
const string::size_type len = std::strlen(q);
if (! tag.empty()) {
- if (! has_tag(tag))
- set_tag(tag, string(p + (q - buf.get())));
+ string_map::iterator i = set_tag(tag, string(p + (q - buf.get())),
+ overwrite_existing);
+ (*i).second.second = true;
break;
}
else if (q[0] == ':' && q[len - 1] == ':') { // a series of tags
for (char * r = std::strtok(q + 1, ":");
r;
- r = std::strtok(NULL, ":"))
- set_tag(r);
+ r = std::strtok(NULL, ":")) {
+ string_map::iterator i = set_tag(r, none, overwrite_existing);
+ (*i).second.second = true;
+ }
}
else if (q[len - 1] == ':') { // a metadata setting
tag = string(q, len - 1);
@@ -165,7 +184,7 @@ void item_t::parse_tags(const char * p,
}
}
-void item_t::append_note(const char * p,
+void item_t::append_note(const char * p, bool overwrite_existing,
optional<date_t::year_type> current_year)
{
if (note) {
@@ -175,7 +194,7 @@ void item_t::append_note(const char * p,
note = p;
}
- parse_tags(p, current_year);
+ parse_tags(p, overwrite_existing, current_year);
}
namespace {