]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Project] Css: Add some logical skeleton for declarations parser
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 17 Feb 2021 21:16:45 +0000 (21:16 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 17 Feb 2021 21:16:45 +0000 (21:16 +0000)
src/libserver/css/CMakeLists.txt
src/libserver/css/css_parser.cxx
src/libserver/css/css_parser.hxx
src/libserver/css/css_rule.cxx [new file with mode: 0644]
src/libserver/css/css_rule.hxx
src/libserver/css/css_selector.cxx
src/libserver/css/css_selector.hxx
src/libserver/css/css_tokeniser.hxx

index 84ed2cf8bd34c82b8b4a20a4095573895cfe9698..e0eab20d70b7485486d878a957c9742aead0f389 100644 (file)
@@ -16,6 +16,7 @@ SET(LIBCSSSRC    "${CMAKE_CURRENT_SOURCE_DIR}/css.cxx"
                  "${CMAKE_CURRENT_SOURCE_DIR}/css_selector.cxx"
                  "${CMAKE_CURRENT_SOURCE_DIR}/css_tokeniser.cxx"
                  "${CMAKE_CURRENT_SOURCE_DIR}/css_util.cxx"
+                 "${CMAKE_CURRENT_SOURCE_DIR}/css_rule.cxx"
                  "${CMAKE_CURRENT_SOURCE_DIR}/css_parser.cxx"
                  "${RAGEL_ragel_css_selector_parser_OUTPUTS}"
                  "${RAGEL_ragel_css_rule_parser_OUTPUTS}"
index a0a9d8847fa50929dd4d75929caba0b37b3584bc..1a9231700d46d0eb3929e29d06ead43466dda265 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "css_parser.hxx"
 #include "css_tokeniser.hxx"
+#include "css_selector.hxx"
+#include "css_rule.hxx"
 #include <vector>
 #include <unicode/utf8.h>
 
@@ -94,6 +96,14 @@ struct css_consumed_block {
                return empty_block_vec;
        }
 
+       auto get_token_or_empty() const -> const css_parser_token& {
+               if (content.index() == 2) {
+                       return std::get<css_parser_token>(content);
+               }
+
+               return css_parser_eof_token();
+       }
+
        auto token_type_str(void) const -> const char *
        {
                const auto *ret = "";
@@ -604,13 +614,53 @@ bool css_parser::consume_input(const std::string_view &sv)
                        if (simple_block != children.end()) {
                                /*
                                 * We have a component and a simple block,
-                                * so we can parse a declaration
+                                * so we can parse a selector and then extract
+                                * declarations from a simple block
                                 */
 
                                /* First, tag all components as preamble */
-                               for (auto it = children.begin(); it != simple_block; ++it) {
-                                       (*it)->tag = css_consumed_block::parser_tag_type::css_selector;
-                               }
+                               auto selector_it = children.cbegin();
+
+                               auto selector_token_functor = [&selector_it,&simple_block](void)
+                                               -> const css_parser_token & {
+                                       for (;;) {
+                                               if (selector_it == simple_block) {
+                                                       return css_parser_eof_token();
+                                               }
+
+                                               const auto &ret = (*selector_it)->get_token_or_empty();
+
+                                               ++selector_it;
+
+                                               if (ret.type != css_parser_token::token_type::eof_token) {
+                                                       return ret;
+                                               }
+                                       }
+                               };
+
+                               auto selectors_vec = process_selector_tokens(pool, selector_token_functor);
+
+                               auto decls_it = (*simple_block)->get_blocks_or_empty().cbegin();
+                               auto decls_end = (*simple_block)->get_blocks_or_empty().cend();
+                               auto declaration_token_functor = [&decls_it,&decls_end](void)
+                                               -> const css_parser_token & {
+                                       for (;;) {
+                                               if (decls_it == decls_end) {
+                                                       return css_parser_eof_token();
+                                               }
+
+                                               const auto &ret = (*decls_it)->get_token_or_empty();
+
+                                               ++decls_it;
+
+                                               if (ret.type != css_parser_token::token_type::eof_token) {
+                                                       return ret;
+                                               }
+                                       }
+                               };
+
+                               auto declarations_vec = process_declaration_tokens(pool,
+                                               declaration_token_functor);
                        }
                }
        }
index e009fef705da6fe1f28676ca09663f8cf6d6f878..2f10f994e29b6ac24e9150d25e329b62dc2da7d3 100644 (file)
@@ -26,8 +26,6 @@
 
 namespace rspamd::css {
 
-INIT_LOG_MODULE(chartable)
-
 auto parse_css (rspamd_mempool_t *pool, const std::string_view &st) ->
                tl::expected<std::unique_ptr<css_style_sheet>,css_parse_error>;
 
diff --git a/src/libserver/css/css_rule.cxx b/src/libserver/css/css_rule.cxx
new file mode 100644 (file)
index 0000000..44148b0
--- /dev/null
@@ -0,0 +1,29 @@
+/*-
+ * Copyright 2021 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "css_rule.hxx"
+
+namespace rspamd::css {
+
+auto process_declaration_tokens(rspamd_mempool_t *pool,
+                                                               const tokeniser_gen_functor &next_token_functor)
+       -> declarations_vec
+{
+       declarations_vec ret;
+
+       return ret; /* copy elision */
+}
+}
\ No newline at end of file
index 6afaa8bc6ea2ad49d0507e2842065b8d1dc926e3..725b6448bcd4f2a424346bc40103c30519009b83 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "css_value.hxx"
 #include "css_property.hxx"
+#include "css_tokeniser.hxx"
 #include <vector>
 #include <memory>
 
@@ -49,6 +50,12 @@ public:
        constexpr const css_property& get_prop(void) const { return prop; }
 };
 
+using declarations_vec = std::vector<std::unique_ptr<css_rule>>;
+
+auto process_declaration_tokens(rspamd_mempool_t *pool,
+                                                        const tokeniser_gen_functor &next_token_functor)
+       -> declarations_vec;
+
 }
 
 /* Make rules hashable by property */
index 2aeaaa8c966d590bf5606bb96b55d96be48131b9..1d6f727ea27313ec99710a5f85bf7d074292502b 100644 (file)
 
 namespace rspamd::css {
 
-tl::expected<css_selector,css_parse_error> css_selector::from_bytes (const char *input,
-                                                                                                                          size_t inlen)
+auto process_selector_tokens(rspamd_mempool_t *pool,
+                                                        const tokeniser_gen_functor &next_token_functor)
+       -> selectors_vec
 {
-       return tl::unexpected{css_parse_error(css_parse_error_type::PARSE_ERROR_NYI)};
+       selectors_vec ret;
+
+       return ret; /* copy elision */
 }
 
 }
index 8611630fd104621a17ff682f0d65d1d89e844453..1e5f5bb1305cb9da717d08133921d8183f15b6bd 100644 (file)
@@ -22,7 +22,8 @@
 #include <variant>
 #include <string>
 #include <optional>
-#include "contrib/expected/expected.hpp"
+#include <vector>
+#include <functional>
 #include "parse_error.hxx"
 #include "css_tokeniser.hxx"
 #include "html_tags.h"
@@ -54,13 +55,17 @@ struct css_selector {
                        return std::string_view(std::get<std::string>(value));
                }
                return std::nullopt;
-       }
-
-       static tl::expected<css_selector,css_parse_error> from_bytes (const char *input,
-                                                                                                                          size_t inlen);
+       };
 };
 
+using selectors_vec = std::vector<std::unique_ptr<css_selector>>;
 
+/*
+ * Consume selectors token and split them to the list of selectors
+ */
+auto process_selector_tokens(rspamd_mempool_t *pool,
+                                                        const tokeniser_gen_functor &next_token_functor)
+       -> selectors_vec;
 
 }
 
index f1e9d05fc188b8a52a413e365ffd74d04d65b920..e3ba47437a4d498240a0b8960d14d274691478d6 100644 (file)
@@ -23,6 +23,7 @@
 #include <utility>
 #include <variant>
 #include <list>
+#include <functional>
 #include "mem_pool.h"
 
 namespace rspamd::css {
@@ -101,6 +102,15 @@ struct css_parser_token {
        auto debug_token_str() -> std::string;
 };
 
+static auto css_parser_eof_token(void) -> const css_parser_token & {
+       static css_parser_token eof_tok {
+               css_parser_token::token_type::eof_token,
+                               css_parser_token_placeholder()
+       };
+
+       return eof_tok;
+}
+
 /* Ensure that parser tokens are simple enough */
 /*
  * compiler must implement P0602 "variant and optional should propagate copy/move triviality"
@@ -129,6 +139,8 @@ private:
        auto consume_ident() -> struct css_parser_token;
 };
 
+using tokeniser_gen_functor = std::function<const css_parser_token &(void)>;
+
 }