diff options
author | Constantin Shalnev <c.shalnev@corp.mail.ru> | 2015-09-10 17:02:54 +0300 |
---|---|---|
committer | Constantin Shalnev <c.shalnev@corp.mail.ru> | 2015-09-23 13:44:17 +0300 |
commit | 2ed83972365ab46dedcd456d088e4b8310fd0e1f (patch) | |
tree | 7f65501ac68666fccdc56a4ee9274c57a61c0402 /indexer/drules_selector_parser.cpp | |
parent | 1acbb7bcdf9a7b424e318941658c31914a22b98a (diff) |
Added processing of apply_if in the kernel
Diffstat (limited to 'indexer/drules_selector_parser.cpp')
-rw-r--r-- | indexer/drules_selector_parser.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/indexer/drules_selector_parser.cpp b/indexer/drules_selector_parser.cpp new file mode 100644 index 0000000000..0433e33fb6 --- /dev/null +++ b/indexer/drules_selector_parser.cpp @@ -0,0 +1,124 @@ +#include "indexer/drules_selector_parser.hpp" + +#include "base/assert.hpp" + +#include "std/algorithm.hpp" + +namespace drule +{ + +namespace +{ + +bool IsTag(string const & str) +{ + // tag consists of a-z or A-Z letters and not empty + for (auto const c : str) + { + if (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z')) + return false; + } + return !str.empty(); +} + +} // namespace + +bool ParseSelector(string const & str, SelectorExpression & e) +{ + // See http://wiki.openstreetmap.org/wiki/MapCSS/0.2 + // Now we support following expressions + // [tag!=value] + // [tag>=value] + // [tag<=value] + // [tag=value] + // [tag>value] + // [tag<value] + // [!tag] + // [tag] + + if (str.empty()) + return false; // invalid format + + // [!tag] + if (str[0] == '!') + { + string tag(str.begin() + 1, str.end()); + if (!IsTag(tag)) + return false; // invalid format + + e.m_operator = SelectorOperatorIsNotSet; + e.m_tag = move(tag); + e.m_value = move(string()); + return true; + } + + // [tag] + if (IsTag(str)) + { + e.m_operator = SelectorOperatorIsSet; + e.m_tag = str; + e.m_value = move(string()); + return true; + } + + // Find first entrance of >, < or = + size_t pos = string::npos; + size_t len = 0; + char const c[] = { '>', '<', '=', 0 }; + for (size_t i = 0; c[i] != 0; ++i) + { + size_t p = str.find(c[i]); + if (p != string::npos) + { + pos = (pos == string::npos) ? p : min(p, pos); + len = 1; + } + } + + // If there is no entrance or no space for tag or value then it is invalid format + if (pos == 0 || len == 0 || pos == str.length()-1) + return false; // invalid format + + // Dedicate the operator type, real operator position and length + SelectorOperatorType op = SelectorOperatorUnknown; + if (str[pos] == '>') + { + op = SelectorOperatorGreater; + if (str[pos+1] == '=') + { + ++len; + op = SelectorOperatorGreaterOrEqual; + } + } + else if (str[pos] == '<') + { + op = SelectorOperatorLess; + if (str[pos+1] == '=') + { + ++len; + op = SelectorOperatorLessOrEqual; + } + } + else + { + ASSERT(str[pos] == '=', ()); + op = SelectorOperatorEqual; + if (str[pos-1] == '!') + { + --pos; + ++len; + op = SelectorOperatorNotEqual; + } + } + + string tag(str.begin(), str.begin() + pos); + if (!IsTag(tag)) + return false; // invalid format + + e.m_operator = op; + e.m_tag = move(tag); + e.m_value = string(str.begin() + pos + len, str.end()); + return true; +} + +} // namespace drule |