Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Shalnev <c.shalnev@corp.mail.ru>2015-09-10 17:02:54 +0300
committerConstantin Shalnev <c.shalnev@corp.mail.ru>2015-09-23 13:44:17 +0300
commit2ed83972365ab46dedcd456d088e4b8310fd0e1f (patch)
tree7f65501ac68666fccdc56a4ee9274c57a61c0402 /indexer/drules_selector_parser.cpp
parent1acbb7bcdf9a7b424e318941658c31914a22b98a (diff)
Added processing of apply_if in the kernel
Diffstat (limited to 'indexer/drules_selector_parser.cpp')
-rw-r--r--indexer/drules_selector_parser.cpp124
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