Skip to content

Commit

Permalink
[Porject] Css: Rework functions parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
vstakhov committed Mar 3, 2021
1 parent 25a8f48 commit 7954b67
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 26 deletions.
33 changes: 30 additions & 3 deletions src/libserver/css/css_parser.cxx
Expand Up @@ -27,11 +27,11 @@ namespace rspamd::css {
const css_consumed_block css_parser_eof_block{};

auto css_consumed_block::attach_block(consumed_block_ptr &&block) -> bool {
if (content.index() == 0) {
if (std::holds_alternative<std::monostate>(content)) {
/* Switch from monostate */
content = std::vector<consumed_block_ptr>();
}
else if (content.index() == 2) {
else if (!std::holds_alternative<std::vector<consumed_block_ptr>>(content)) {
/* A single component, cannot attach a block ! */
return false;
}
Expand All @@ -42,6 +42,17 @@ auto css_consumed_block::attach_block(consumed_block_ptr &&block) -> bool {
return true;
}

auto css_consumed_block::add_function_argument(consumed_block_ptr &&block) -> bool {
if (!std::holds_alternative<css_function_block>(content)) {
return false;
}

auto &&func_bloc = std::get<css_function_block>(content);
func_bloc.args.push_back(std::move(block));

return true;
}

auto css_consumed_block::token_type_str(void) const -> const char *
{
const auto *ret = "";
Expand Down Expand Up @@ -106,6 +117,18 @@ auto css_consumed_block::debug_str(void) -> std::string {
/* Empty block */
ret += R"("empty")";
}
else if constexpr (std::is_same_v<T, css_function_block>) {
/* Empty block */
ret += R"({ "function:" {"name": )";
ret += "\"" + arg.function.debug_token_str() + "\"";
ret += R"("arguments:" [)";
for (const auto &block : arg.args) {
ret += "{";
ret += block->debug_str();
ret += "}, ";
}
ret += "]}";
}
else {
/* Single element block */
ret += "\"" + arg.debug_token_str() + "\"";
Expand Down Expand Up @@ -214,9 +237,13 @@ auto css_parser::function_consumer(std::unique_ptr<css_consumed_block> &top) ->
ret = true;
want_more = false;
break;
case css_parser_token::token_type::comma_token:
case css_parser_token::token_type::delim_token:
case css_parser_token::token_type::obrace_token:
break;
default:
/* Attach everything to the function block */
top->attach_block(std::make_unique<css_consumed_block>(
top->add_function_argument(std::make_unique<css_consumed_block>(
css::css_consumed_block::parser_tag_type::css_function_arg,
std::move(next_token)));
break;
Expand Down
22 changes: 20 additions & 2 deletions src/libserver/css/css_parser.hxx
Expand Up @@ -51,6 +51,14 @@ public:
};
using consumed_block_ptr = std::unique_ptr<css_consumed_block>;

struct css_function_block {
css_parser_token function;
std::vector<consumed_block_ptr> args;

css_function_block(css_parser_token &&tok) :
function(std::forward<css_parser_token>(tok)) {}
};

css_consumed_block() : tag(parser_tag_type::css_eof_block) {}
css_consumed_block(parser_tag_type tag) : tag(tag) {
if (tag == parser_tag_type::css_top_block ||
Expand All @@ -64,10 +72,19 @@ public:
}
/* Construct a block from a single lexer token (for trivial blocks) */
explicit css_consumed_block(parser_tag_type tag, css_parser_token &&tok) :
tag(tag), content(std::move(tok)) {}
tag(tag) {
if (tag == parser_tag_type::css_function) {
content = css_function_block{std::move(tok)};
}
else {
content = std::move(tok);
}
}

/* Attach a new block to the compound block, consuming block inside */
auto attach_block(consumed_block_ptr &&block) -> bool;
/* Attach a new argument to the compound function block, consuming block inside */
auto add_function_argument(consumed_block_ptr &&block) -> bool;

auto assign_token(css_parser_token &&tok) -> void {
content = std::move(tok);
Expand Down Expand Up @@ -137,7 +154,8 @@ public:
private:
std::variant<std::monostate,
std::vector<consumed_block_ptr>,
css_parser_token> content;
css_parser_token,
css_function_block> content;
};

extern const css_consumed_block css_parser_eof_block;
Expand Down
51 changes: 30 additions & 21 deletions src/libserver/css/css_tokeniser.cxx
Expand Up @@ -246,34 +246,43 @@ auto css_tokeniser::consume_ident() -> struct css_parser_token
auto j = i + 1;

while (j < input.size() && g_ascii_isspace(input[j])) {
j ++;
j++;
}

if (input[j] == '"' || input[j] == '\'') {
/* Function token */
return maybe_escape_sv(j + 1,
css_parser_token::token_type::function_token);
}
else {
/* Consume URL token */
while (j < input.size() && input[j] != ')') {
j ++;
}

if (input[j] == ')') {
/* Valid url token */
return maybe_escape_sv(j + 1,
css_parser_token::token_type::url_token);
if (input.size() > 3 && input.substr(0, 3) == "url") {
if (input[j] == '"' || input[j] == '\'') {
/* Function token */
auto ret = maybe_escape_sv(i,
css_parser_token::token_type::function_token);
return ret;
}
else {
/* Incomplete url token */
auto ret = maybe_escape_sv(j,
css_parser_token::token_type::url_token);
/* Consume URL token */
while (j < input.size() && input[j] != ')') {
j++;
}

ret.flags |= css_parser_token::flag_bad_string;
return ret;
if (input[j] == ')') {
/* Valid url token */
auto ret = maybe_escape_sv(j + 1,
css_parser_token::token_type::url_token);
return ret;
}
else {
/* Incomplete url token */
auto ret = maybe_escape_sv(j,
css_parser_token::token_type::url_token);

ret.flags |= css_parser_token::flag_bad_string;
return ret;
}
}
}
else {
auto ret = maybe_escape_sv(i,
css_parser_token::token_type::function_token);
return ret;
}
}
else if (c == '-' && allow_middle_minus) {
i++;
Expand Down
25 changes: 25 additions & 0 deletions test/lua/unit/css.lua
Expand Up @@ -97,6 +97,31 @@ body {
width: 100%;
}
}
]],
[[
/* Colors */
* { color: hsl(0, 100%, 50%) } /* red */
* { color: hsl(120, 100%, 50%) } /* lime */
* { color: hsl(120, 100%, 25%) } /* dark green */
* { color: hsl(120, 100%, 75%) } /* light green */
* { color: hsl(120, 75%, 75%) } /* pastel green, and so on */
em { color: #f00 } /* #rgb */
em { color: #ff0000 } /* #rrggbb */
em { color: rgb(255,0,0) }
em { color: rgb(100%, 0%, 0%) }
body {color: black; background: white }
h1 { color: maroon }
h2 { color: olive }
em { color: rgb(255,0,0) } /* integer range 0 - 255 */
em { color: rgb(300,0,0) } /* clipped to rgb(255,0,0) */
em { color: rgb(255,-10,0) } /* clipped to rgb(255,0,0) */
em { color: rgb(110%, 0%, 0%) } /* clipped to rgb(100%,0%,0%) */
em { color: rgb(255,0,0) } /* integer range 0 - 255 */
em { color: rgba(255,0,0,1) /* the same, with explicit opacity of 1 */
em { color: rgb(100%,0%,0%) } /* float range 0.0% - 100.0% */
em { color: rgba(100%,0%,0%,1) } /* the same, with explicit opacity of 1 */
p { color: rgba(0,0,255,0.5) } /* semi-transparent solid blue */
p { color: rgba(100%, 50%, 0%, 0.1) } /* very transparent solid orange */
]]
}
local NULL = ffi.new 'void*'
Expand Down

0 comments on commit 7954b67

Please sign in to comment.