aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver/css/css_tokeniser.cxx
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2021-01-25 16:35:23 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2021-01-25 16:35:38 +0000
commitfcfaab40b8ea772ce9d72773930c329a6277da6d (patch)
tree27073dbe13f8cd8d9f7a1c5a35a9d44dd23533e0 /src/libserver/css/css_tokeniser.cxx
parent50e3e98a741cf2946ec0b3e4cf396d53cc9e4ae4 (diff)
downloadrspamd-fcfaab40b8ea772ce9d72773930c329a6277da6d.tar.gz
rspamd-fcfaab40b8ea772ce9d72773930c329a6277da6d.zip
[Project] Css: Rework tokens structure
Diffstat (limited to 'src/libserver/css/css_tokeniser.cxx')
-rw-r--r--src/libserver/css/css_tokeniser.cxx72
1 files changed, 51 insertions, 21 deletions
diff --git a/src/libserver/css/css_tokeniser.cxx b/src/libserver/css/css_tokeniser.cxx
index 40f202b01..058f7504e 100644
--- a/src/libserver/css/css_tokeniser.cxx
+++ b/src/libserver/css/css_tokeniser.cxx
@@ -19,8 +19,46 @@
namespace rspamd::css {
+/* Helpers to create tokens */
-auto css_tokeniser::next_token (void) -> std::pair<css_parser_token, std::string_view>
+/*
+ * This helper is intended to create tokens either with a tag and value
+ * or with just a tag.
+ */
+template<css_parser_token::token_type T, typename ...Args>
+auto make_token(const Args&... args) -> css_parser_token;
+
+template<>
+auto make_token<css_parser_token::token_type::string_token, std::string_view>(const std::string_view &s)
+ -> css_parser_token
+{
+ return css_parser_token{css_parser_token::token_type::string_token, s};
+}
+
+template<>
+auto make_token<css_parser_token::token_type::whitespace_token, std::string_view>(const std::string_view &s)
+ -> css_parser_token
+{
+ return css_parser_token{css_parser_token::token_type::whitespace_token, s};
+}
+
+template<>
+auto make_token<css_parser_token::token_type::delim_token, char>(const char &c)
+ -> css_parser_token
+{
+ return css_parser_token{css_parser_token::token_type::delim_token, c};
+}
+
+/*
+ * Generic tokens with no value (non-terminals)
+ */
+template<css_parser_token::token_type T>
+auto make_token(void) -> css_parser_token
+{
+ return css_parser_token{T, css_parser_token_placeholder()};
+}
+
+auto css_tokeniser::next_token(void) -> struct css_parser_token
{
/* Helpers */
@@ -29,7 +67,7 @@ auto css_tokeniser::next_token (void) -> std::pair<css_parser_token, std::string
* offset is set to the next character after a comment (or eof)
* Nothing is returned
*/
- auto consume_comment = [this] () {
+ auto consume_comment = [this]() {
auto i = offset;
auto nested = 0;
@@ -64,7 +102,7 @@ auto css_tokeniser::next_token (void) -> std::pair<css_parser_token, std::string
* is set one character after the string. Css unescaping is done automatically
* Accepts a quote char to find end of string
*/
- auto consume_string = [this] (auto quote_char) -> auto {
+ auto consume_string = [this](auto quote_char) -> auto {
auto i = offset;
bool need_unescape = false;
@@ -122,8 +160,7 @@ auto css_tokeniser::next_token (void) -> std::pair<css_parser_token, std::string
}
else {
offset = i + 1;
- return std::make_pair (css_parser_token::delim_token,
- std::string_view (&input[offset - 1], 1));
+ return make_token<css_parser_token::token_type::delim_token>(c);
}
break;
case ' ':
@@ -136,48 +173,41 @@ auto css_tokeniser::next_token (void) -> std::pair<css_parser_token, std::string
c = input[++i];
} while (i < input.size () && g_ascii_isspace (c));
- auto ret = std::make_pair (css_parser_token::whitespace_token,
- std::string_view (&input[offset], i - offset));
+ auto ret = make_token<css_parser_token::token_type::whitespace_token>(
+ std::string_view(&input[offset], i - offset));
offset = i;
return ret;
}
case '"':
case '\'':
offset = i + 1;
- return std::make_pair (css_parser_token::string_token,
- consume_string (c));
+ return make_token<css_parser_token::token_type::string_token>(consume_string(c));
case '(':
offset = i + 1;
- return std::make_pair (css_parser_token::obrace_token,
- std::string_view (&input[offset - 1], 1));
+ return make_token<css_parser_token::token_type::obrace_token>();
case ')':
offset = i + 1;
- return std::make_pair (css_parser_token::ebrace_token,
- std::string_view (&input[offset - 1], 1));
+ return make_token<css_parser_token::token_type::ebrace_token>();
case ',':
- offset = i + 1;
- return std::make_pair (css_parser_token::comma_token,
- std::string_view (&input[offset - 1], 1));
+ return make_token<css_parser_token::token_type::comma_token>();
case '<':
/* Maybe an xml like comment */
if (i + 3 < input.size () && input[i + 1] == '!'
&& input[i + 2] == '-' && input[i + 3] == '-') {
offset += 3;
- return std::make_pair (css_parser_token::cdo_token,
- std::string_view (&input[offset - 3], 3));
+ return make_token<css_parser_token::token_type::cdo_token>();
}
else {
offset = i + 1;
- return std::make_pair (css_parser_token::delim_token,
- std::string_view (&input[offset - 1], 1));
+ return make_token<css_parser_token::token_type::delim_token>(c);
}
break;
}
}
- return std::make_pair (css_parser_token::eof_token, std::string_view ());
+ return make_token<css_parser_token::token_type::eof_token>();
}
} \ No newline at end of file