diff options
Diffstat (limited to 'src/item.cc')
-rw-r--r-- | src/item.cc | 55 |
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 { |