sassc 2.2.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +13 -0
- data/Rakefile +1 -3
- data/ext/extconf.rb +13 -5
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/base.h +2 -1
- data/ext/libsass/include/sass/context.h +1 -0
- data/ext/libsass/src/ast.cpp +49 -59
- data/ext/libsass/src/ast.hpp +263 -102
- data/ext/libsass/src/ast_def_macros.hpp +8 -0
- data/ext/libsass/src/ast_fwd_decl.cpp +2 -1
- data/ext/libsass/src/ast_fwd_decl.hpp +40 -116
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +209 -722
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +207 -212
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +559 -1001
- data/ext/libsass/src/ast_selectors.hpp +311 -367
- data/ext/libsass/src/ast_supports.cpp +1 -17
- data/ext/libsass/src/ast_values.cpp +216 -29
- data/ext/libsass/src/ast_values.hpp +42 -33
- data/ext/libsass/src/bind.cpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +5 -6
- data/ext/libsass/src/check_nesting.hpp +4 -0
- data/ext/libsass/src/color_maps.cpp +11 -10
- data/ext/libsass/src/color_maps.hpp +0 -8
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +30 -60
- data/ext/libsass/src/context.hpp +8 -20
- data/ext/libsass/src/cssize.cpp +36 -120
- data/ext/libsass/src/cssize.hpp +4 -10
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +364 -207
- data/ext/libsass/src/emitter.cpp +3 -4
- data/ext/libsass/src/emitter.hpp +0 -2
- data/ext/libsass/src/environment.hpp +5 -0
- data/ext/libsass/src/error_handling.cpp +21 -0
- data/ext/libsass/src/error_handling.hpp +25 -3
- data/ext/libsass/src/eval.cpp +33 -153
- data/ext/libsass/src/eval.hpp +11 -13
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +214 -167
- data/ext/libsass/src/expand.hpp +26 -6
- data/ext/libsass/src/extender.cpp +1186 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +15 -14
- data/ext/libsass/src/file.hpp +5 -12
- data/ext/libsass/src/fn_colors.cpp +12 -10
- data/ext/libsass/src/fn_lists.cpp +12 -11
- data/ext/libsass/src/fn_miscs.cpp +22 -34
- data/ext/libsass/src/fn_numbers.cpp +13 -6
- data/ext/libsass/src/fn_selectors.cpp +94 -124
- data/ext/libsass/src/fn_strings.cpp +16 -14
- data/ext/libsass/src/fn_utils.cpp +5 -6
- data/ext/libsass/src/fn_utils.hpp +9 -3
- data/ext/libsass/src/inspect.cpp +154 -117
- data/ext/libsass/src/inspect.hpp +10 -8
- data/ext/libsass/src/lexer.cpp +17 -81
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +22 -36
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/memory/SharedPtr.hpp +39 -5
- data/ext/libsass/src/operation.hpp +27 -17
- data/ext/libsass/src/operators.cpp +1 -0
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +30 -49
- data/ext/libsass/src/output.hpp +1 -1
- data/ext/libsass/src/parser.cpp +211 -381
- data/ext/libsass/src/parser.hpp +17 -15
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +140 -0
- data/ext/libsass/src/position.hpp +1 -1
- data/ext/libsass/src/prelexer.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.cpp +55 -56
- data/ext/libsass/src/remove_placeholders.hpp +21 -18
- data/ext/libsass/src/sass.hpp +1 -0
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +42 -91
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +1 -1
- data/ext/libsass/src/sass_values.cpp +0 -1
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +5 -3
- data/ext/libsass/src/util.cpp +10 -12
- data/ext/libsass/src/util.hpp +2 -3
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +61 -8
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +1 -1
- data/lib/sassc/script.rb +4 -4
- data/lib/sassc/version.rb +1 -1
- data/test/functions_test.rb +18 -1
- data/test/native_test.rb +1 -1
- metadata +17 -12
- data/ext/libsass/src/extend.cpp +0 -2132
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/node.cpp +0 -322
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -152
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -58
- data/ext/libsass/src/subset_map.hpp +0 -76
data/ext/libsass/src/parser.hpp
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#ifndef SASS_PARSER_H
|
|
2
2
|
#define SASS_PARSER_H
|
|
3
3
|
|
|
4
|
+
// sass.hpp must go before all system headers to get the
|
|
5
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
4
6
|
#include "sass.hpp"
|
|
5
7
|
|
|
6
8
|
#include <string>
|
|
@@ -40,7 +42,6 @@ namespace Sass {
|
|
|
40
42
|
Context& ctx;
|
|
41
43
|
std::vector<Block_Obj> block_stack;
|
|
42
44
|
std::vector<Scope> stack;
|
|
43
|
-
Media_Block* last_media_block;
|
|
44
45
|
const char* source;
|
|
45
46
|
const char* position;
|
|
46
47
|
const char* end;
|
|
@@ -55,7 +56,7 @@ namespace Sass {
|
|
|
55
56
|
Token lexed;
|
|
56
57
|
|
|
57
58
|
Parser(Context& ctx, const ParserState& pstate, Backtraces traces, bool allow_parent = true)
|
|
58
|
-
: ParserState(pstate), ctx(ctx), block_stack(), stack(0),
|
|
59
|
+
: ParserState(pstate), ctx(ctx), block_stack(), stack(0),
|
|
59
60
|
source(0), position(0), end(0), before_token(pstate), after_token(pstate),
|
|
60
61
|
pstate(pstate), traces(traces), indentation(0), nestings(0), allow_parent(allow_parent)
|
|
61
62
|
{
|
|
@@ -67,7 +68,7 @@ namespace Sass {
|
|
|
67
68
|
static Parser from_c_str(const char* beg, const char* end, Context& ctx, Backtraces, ParserState pstate = ParserState("[CSTRING]"), const char* source = nullptr, bool allow_parent = true);
|
|
68
69
|
static Parser from_token(Token t, Context& ctx, Backtraces, ParserState pstate = ParserState("[TOKEN]"), const char* source = nullptr);
|
|
69
70
|
// special static parsers to convert strings into certain selectors
|
|
70
|
-
static
|
|
71
|
+
static SelectorListObj parse_selector(const char* src, Context& ctx, Backtraces, ParserState pstate = ParserState("[SELECTOR]"), const char* source = nullptr, bool allow_parent = true);
|
|
71
72
|
|
|
72
73
|
#ifdef __clang__
|
|
73
74
|
|
|
@@ -187,7 +188,7 @@ namespace Sass {
|
|
|
187
188
|
// update after_token position for current token
|
|
188
189
|
after_token.add(it_before_token, it_after_token);
|
|
189
190
|
|
|
190
|
-
// ToDo: could probably do this
|
|
191
|
+
// ToDo: could probably do this incremental on original object (API wants offset?)
|
|
191
192
|
pstate = ParserState(path, source, lexed, before_token, after_token - before_token);
|
|
192
193
|
|
|
193
194
|
// advance internal char iterator
|
|
@@ -259,20 +260,20 @@ namespace Sass {
|
|
|
259
260
|
Argument_Obj parse_argument();
|
|
260
261
|
Assignment_Obj parse_assignment();
|
|
261
262
|
Ruleset_Obj parse_ruleset(Lookahead lookahead);
|
|
262
|
-
|
|
263
|
-
|
|
263
|
+
SelectorListObj parseSelectorList(bool chroot);
|
|
264
|
+
ComplexSelectorObj parseComplexSelector(bool chroot);
|
|
264
265
|
Selector_Schema_Obj parse_selector_schema(const char* end_of_selector, bool chroot);
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
266
|
+
CompoundSelectorObj parseCompoundSelector();
|
|
267
|
+
SimpleSelectorObj parse_simple_selector();
|
|
268
|
+
Pseudo_Selector_Obj parse_negated_selector2();
|
|
269
|
+
Expression* parse_binominal();
|
|
270
|
+
SimpleSelectorObj parse_pseudo_selector();
|
|
269
271
|
Attribute_Selector_Obj parse_attribute_selector();
|
|
270
272
|
Block_Obj parse_block(bool is_root = false);
|
|
271
273
|
Block_Obj parse_css_block(bool is_root = false);
|
|
272
274
|
bool parse_block_nodes(bool is_root = false);
|
|
273
275
|
bool parse_block_node(bool is_root = false);
|
|
274
276
|
|
|
275
|
-
bool parse_number_prefix();
|
|
276
277
|
Declaration_Obj parse_declaration();
|
|
277
278
|
Expression_Obj parse_map();
|
|
278
279
|
Expression_Obj parse_bracket_list();
|
|
@@ -303,10 +304,13 @@ namespace Sass {
|
|
|
303
304
|
For_Obj parse_for_directive();
|
|
304
305
|
Each_Obj parse_each_directive();
|
|
305
306
|
While_Obj parse_while_directive();
|
|
307
|
+
MediaRule_Obj parseMediaRule();
|
|
308
|
+
std::vector<CssMediaQuery_Obj> parseCssMediaQueries();
|
|
309
|
+
std::string parseIdentifier();
|
|
310
|
+
CssMediaQuery_Obj parseCssMediaQuery();
|
|
306
311
|
Return_Obj parse_return_directive();
|
|
307
312
|
Content_Obj parse_content_directive();
|
|
308
313
|
void parse_charset_directive();
|
|
309
|
-
Media_Block_Obj parse_media_block();
|
|
310
314
|
List_Obj parse_media_queries();
|
|
311
315
|
Media_Query_Obj parse_media_query();
|
|
312
316
|
Media_Query_Expression_Obj parse_media_expression();
|
|
@@ -320,8 +324,6 @@ namespace Sass {
|
|
|
320
324
|
At_Root_Block_Obj parse_at_root_block();
|
|
321
325
|
At_Root_Query_Obj parse_at_root_query();
|
|
322
326
|
String_Schema_Obj parse_almost_any_value();
|
|
323
|
-
Directive_Obj parse_special_directive();
|
|
324
|
-
Directive_Obj parse_prefixed_directive();
|
|
325
327
|
Directive_Obj parse_directive();
|
|
326
328
|
Warning_Obj parse_warning();
|
|
327
329
|
Error_Obj parse_error();
|
|
@@ -340,7 +342,7 @@ namespace Sass {
|
|
|
340
342
|
Token lex_variable();
|
|
341
343
|
Token lex_identifier();
|
|
342
344
|
|
|
343
|
-
void parse_block_comments();
|
|
345
|
+
void parse_block_comments(bool store = true);
|
|
344
346
|
|
|
345
347
|
Lookahead lookahead_for_value(const char* start = 0);
|
|
346
348
|
Lookahead lookahead_for_selector(const char* start = 0);
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
|
|
5
|
+
#include "parser.hpp"
|
|
6
|
+
|
|
7
|
+
namespace Sass {
|
|
8
|
+
|
|
9
|
+
using namespace Prelexer;
|
|
10
|
+
using namespace Constants;
|
|
11
|
+
|
|
12
|
+
ComplexSelectorObj Parser::parseComplexSelector(bool chroot)
|
|
13
|
+
{
|
|
14
|
+
|
|
15
|
+
NESTING_GUARD(nestings);
|
|
16
|
+
|
|
17
|
+
lex < block_comment >();
|
|
18
|
+
advanceToNextToken();
|
|
19
|
+
|
|
20
|
+
ComplexSelectorObj sel = SASS_MEMORY_NEW(ComplexSelector, pstate);
|
|
21
|
+
|
|
22
|
+
if (peek < end_of_file >()) return sel;
|
|
23
|
+
|
|
24
|
+
while (true) {
|
|
25
|
+
|
|
26
|
+
lex < block_comment >();
|
|
27
|
+
advanceToNextToken();
|
|
28
|
+
|
|
29
|
+
// check for child (+) combinator
|
|
30
|
+
if (lex < exactly < selector_combinator_child > >()) {
|
|
31
|
+
sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::CHILD, peek_newline()));
|
|
32
|
+
}
|
|
33
|
+
// check for general sibling (~) combinator
|
|
34
|
+
else if (lex < exactly < selector_combinator_general > >()) {
|
|
35
|
+
sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::GENERAL, peek_newline()));
|
|
36
|
+
}
|
|
37
|
+
// check for adjecant sibling (+) combinator
|
|
38
|
+
else if (lex < exactly < selector_combinator_adjacent > >()) {
|
|
39
|
+
sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::ADJACENT, peek_newline()));
|
|
40
|
+
}
|
|
41
|
+
// check if we can parse a compound selector
|
|
42
|
+
else if (CompoundSelectorObj compound = parseCompoundSelector()) {
|
|
43
|
+
sel->append(compound);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (sel->empty()) return {};
|
|
51
|
+
|
|
52
|
+
// check if we parsed any parent references
|
|
53
|
+
sel->chroots(sel->has_real_parent_ref() || chroot);
|
|
54
|
+
|
|
55
|
+
sel->update_pstate(pstate);
|
|
56
|
+
|
|
57
|
+
return sel;
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
SelectorListObj Parser::parseSelectorList(bool chroot)
|
|
62
|
+
{
|
|
63
|
+
|
|
64
|
+
bool reloop;
|
|
65
|
+
bool had_linefeed = false;
|
|
66
|
+
NESTING_GUARD(nestings);
|
|
67
|
+
SelectorListObj list = SASS_MEMORY_NEW(SelectorList, pstate);
|
|
68
|
+
|
|
69
|
+
if (peek_css< alternatives < end_of_file, exactly <'{'>, exactly <','> > >()) {
|
|
70
|
+
css_error("Invalid CSS", " after ", ": expected selector, was ");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
do {
|
|
74
|
+
reloop = false;
|
|
75
|
+
|
|
76
|
+
had_linefeed = had_linefeed || peek_newline();
|
|
77
|
+
|
|
78
|
+
if (peek_css< alternatives < class_char < selector_list_delims > > >())
|
|
79
|
+
break; // in case there are superfluous commas at the end
|
|
80
|
+
|
|
81
|
+
// now parse the complex selector
|
|
82
|
+
ComplexSelectorObj complex = parseComplexSelector(chroot);
|
|
83
|
+
if (complex.isNull()) return list.detach();
|
|
84
|
+
complex->hasPreLineFeed(had_linefeed);
|
|
85
|
+
|
|
86
|
+
had_linefeed = false;
|
|
87
|
+
|
|
88
|
+
while (peek_css< exactly<','> >())
|
|
89
|
+
{
|
|
90
|
+
lex< css_comments >(false);
|
|
91
|
+
// consume everything up and including the comma separator
|
|
92
|
+
reloop = lex< exactly<','> >() != 0;
|
|
93
|
+
// remember line break (also between some commas)
|
|
94
|
+
had_linefeed = had_linefeed || peek_newline();
|
|
95
|
+
// remember line break (also between some commas)
|
|
96
|
+
}
|
|
97
|
+
list->append(complex);
|
|
98
|
+
|
|
99
|
+
} while (reloop);
|
|
100
|
+
|
|
101
|
+
while (lex_css< kwd_optional >()) {
|
|
102
|
+
list->is_optional(true);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// update for end position
|
|
106
|
+
list->update_pstate(pstate);
|
|
107
|
+
|
|
108
|
+
return list.detach();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// parse one compound selector, which is basically
|
|
112
|
+
// a list of simple selectors (directly adjacent)
|
|
113
|
+
// lex them exactly (without skipping white-space)
|
|
114
|
+
CompoundSelectorObj Parser::parseCompoundSelector()
|
|
115
|
+
{
|
|
116
|
+
// init an empty compound selector wrapper
|
|
117
|
+
CompoundSelectorObj seq = SASS_MEMORY_NEW(CompoundSelector, pstate);
|
|
118
|
+
|
|
119
|
+
// skip initial white-space
|
|
120
|
+
lex < block_comment >();
|
|
121
|
+
advanceToNextToken();
|
|
122
|
+
|
|
123
|
+
if (lex< exactly<'&'> >(false))
|
|
124
|
+
{
|
|
125
|
+
// ToDo: check the conditions and try to simplify flag passing
|
|
126
|
+
if (!allow_parent) error("Parent selectors aren't allowed here.");
|
|
127
|
+
// Create and append a new parent selector object
|
|
128
|
+
seq->hasRealParent(true);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// parse list
|
|
132
|
+
while (true)
|
|
133
|
+
{
|
|
134
|
+
// remove all block comments
|
|
135
|
+
// leaves trailing white-space
|
|
136
|
+
lex < block_comment >();
|
|
137
|
+
// parse parent selector
|
|
138
|
+
if (lex< exactly<'&'> >(false))
|
|
139
|
+
{
|
|
140
|
+
// parent selector only allowed at start
|
|
141
|
+
// upcoming Sass may allow also trailing
|
|
142
|
+
ParserState state(pstate);
|
|
143
|
+
std::string found("&");
|
|
144
|
+
if (lex < identifier >()) {
|
|
145
|
+
found += std::string(lexed);
|
|
146
|
+
}
|
|
147
|
+
std::string sel(seq->hasRealParent() ? "&" : "");
|
|
148
|
+
if (!seq->empty()) { sel = seq->last()->to_string({ NESTED, 5 }); }
|
|
149
|
+
// ToDo: parser should throw parser exceptions
|
|
150
|
+
error("Invalid CSS after \"" + sel + "\": expected \"{\", was \"" + found + "\"\n\n"
|
|
151
|
+
"\"" + found + "\" may only be used at the beginning of a compound selector.", state);
|
|
152
|
+
}
|
|
153
|
+
// parse functional
|
|
154
|
+
else if (match < re_functional >())
|
|
155
|
+
{
|
|
156
|
+
seq->append(parse_simple_selector());
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// parse type selector
|
|
160
|
+
else if (lex< re_type_selector >(false))
|
|
161
|
+
{
|
|
162
|
+
seq->append(SASS_MEMORY_NEW(Type_Selector, pstate, lexed));
|
|
163
|
+
}
|
|
164
|
+
// peek for abort conditions
|
|
165
|
+
else if (peek< spaces >()) break;
|
|
166
|
+
else if (peek< end_of_file >()) { break; }
|
|
167
|
+
else if (peek_css < class_char < selector_combinator_ops > >()) break;
|
|
168
|
+
else if (peek_css < class_char < complex_selector_delims > >()) break;
|
|
169
|
+
// otherwise parse another simple selector
|
|
170
|
+
else {
|
|
171
|
+
SimpleSelectorObj sel = parse_simple_selector();
|
|
172
|
+
if (!sel) return {};
|
|
173
|
+
seq->append(sel);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// EO while true
|
|
177
|
+
|
|
178
|
+
if (seq && !peek_css<alternatives<end_of_file,exactly<'{'>>>()) {
|
|
179
|
+
seq->hasPostLineBreak(peek_newline());
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// We may have set hasRealParent
|
|
183
|
+
if (seq && seq->empty() && !seq->hasRealParent()) return {};
|
|
184
|
+
|
|
185
|
+
return seq;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#ifndef SASS_PATHS_H
|
|
2
|
+
#define SASS_PATHS_H
|
|
3
|
+
|
|
4
|
+
#include <vector>
|
|
5
|
+
|
|
6
|
+
namespace Sass {
|
|
7
|
+
|
|
8
|
+
// Returns a list of all possible paths through the given lists.
|
|
9
|
+
//
|
|
10
|
+
// For example, given `[[1, 2], [3, 4], [5]]`, this returns:
|
|
11
|
+
//
|
|
12
|
+
// ```
|
|
13
|
+
// [[1, 3, 5],
|
|
14
|
+
// [2, 3, 5],
|
|
15
|
+
// [1, 4, 5],
|
|
16
|
+
// [2, 4, 5]]
|
|
17
|
+
// ```
|
|
18
|
+
//
|
|
19
|
+
// Note: called `paths` in dart-sass
|
|
20
|
+
template <class T>
|
|
21
|
+
std::vector<std::vector<T>> permutate(
|
|
22
|
+
const std::vector<std::vector<T>>& in)
|
|
23
|
+
{
|
|
24
|
+
|
|
25
|
+
size_t L = in.size(), n = 0;
|
|
26
|
+
|
|
27
|
+
// Exit early if any entry is empty
|
|
28
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
29
|
+
if (in[i].size() == 0) return {};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
size_t* state = new size_t[L + 1];
|
|
33
|
+
std::vector<std::vector<T>> out;
|
|
34
|
+
|
|
35
|
+
// First initialize all states for every permutation group
|
|
36
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
37
|
+
state[i] = in[i].size() - 1;
|
|
38
|
+
}
|
|
39
|
+
while (true) {
|
|
40
|
+
std::vector<T> perm;
|
|
41
|
+
// Create one permutation for state
|
|
42
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
43
|
+
perm.push_back(in.at(i).at(in[i].size() - state[i] - 1));
|
|
44
|
+
}
|
|
45
|
+
// Current group finished
|
|
46
|
+
if (state[n] == 0) {
|
|
47
|
+
// Find position of next decrement
|
|
48
|
+
while (n < L && state[++n] == 0) {}
|
|
49
|
+
|
|
50
|
+
if (n == L) {
|
|
51
|
+
out.push_back(perm);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
state[n] -= 1;
|
|
56
|
+
|
|
57
|
+
for (size_t p = 0; p < n; p += 1) {
|
|
58
|
+
state[p] = in[p].size() - 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Restart from front
|
|
62
|
+
n = 0;
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
state[n] -= 1;
|
|
67
|
+
}
|
|
68
|
+
out.push_back(perm);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
delete[] state;
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
// EO permutate
|
|
75
|
+
|
|
76
|
+
// ToDo: this variant is used in resolve_parent_refs
|
|
77
|
+
template <class T>
|
|
78
|
+
std::vector<std::vector<T>>
|
|
79
|
+
permutateAlt(const std::vector<std::vector<T>>& in) {
|
|
80
|
+
|
|
81
|
+
size_t L = in.size();
|
|
82
|
+
size_t n = in.size() - 1;
|
|
83
|
+
size_t* state = new size_t[L];
|
|
84
|
+
std::vector< std::vector<T>> out;
|
|
85
|
+
|
|
86
|
+
// First initialize all states for every permutation group
|
|
87
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
88
|
+
if (in[i].size() == 0) return {};
|
|
89
|
+
state[i] = in[i].size() - 1;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
while (true) {
|
|
93
|
+
/*
|
|
94
|
+
// std::cerr << "PERM: ";
|
|
95
|
+
for (size_t p = 0; p < L; p++)
|
|
96
|
+
{ // std::cerr << state[p] << " "; }
|
|
97
|
+
// std::cerr << "\n";
|
|
98
|
+
*/
|
|
99
|
+
std::vector<T> perm;
|
|
100
|
+
// Create one permutation for state
|
|
101
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
102
|
+
perm.push_back(in.at(i).at(in[i].size() - state[i] - 1));
|
|
103
|
+
}
|
|
104
|
+
// Current group finished
|
|
105
|
+
if (state[n] == 0) {
|
|
106
|
+
// Find position of next decrement
|
|
107
|
+
while (n > 0 && state[--n] == 0)
|
|
108
|
+
{
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
// Check for end condition
|
|
112
|
+
if (state[n] != 0) {
|
|
113
|
+
// Decrease next on the left side
|
|
114
|
+
state[n] -= 1;
|
|
115
|
+
// Reset all counters to the right
|
|
116
|
+
for (size_t p = n + 1; p < L; p += 1) {
|
|
117
|
+
state[p] = in[p].size() - 1;
|
|
118
|
+
}
|
|
119
|
+
// Restart from end
|
|
120
|
+
n = L - 1;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
out.push_back(perm);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
state[n] -= 1;
|
|
129
|
+
}
|
|
130
|
+
out.push_back(perm);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
delete[] state;
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
// EO permutateAlt
|
|
137
|
+
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
#endif
|
|
@@ -86,7 +86,7 @@ namespace Sass {
|
|
|
86
86
|
|
|
87
87
|
size_t length() const { return end - begin; }
|
|
88
88
|
std::string ws_before() const { return std::string(prefix, begin); }
|
|
89
|
-
|
|
89
|
+
std::string to_string() const { return std::string(begin, end); }
|
|
90
90
|
std::string time_wspace() const {
|
|
91
91
|
std::string str(to_string());
|
|
92
92
|
std::string whitespaces(" \t\f\v\n\r");
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// __EXTENSIONS__ fix on Solaris.
|
|
3
3
|
#include "sass.hpp"
|
|
4
4
|
|
|
5
|
-
#include <cctype>
|
|
6
5
|
#include <iostream>
|
|
7
6
|
#include <iomanip>
|
|
8
7
|
#include "util.hpp"
|
|
8
|
+
#include "util_string.hpp"
|
|
9
9
|
#include "position.hpp"
|
|
10
10
|
#include "prelexer.hpp"
|
|
11
11
|
#include "constants.hpp"
|
|
@@ -336,7 +336,7 @@ namespace Sass {
|
|
|
336
336
|
return alternatives<
|
|
337
337
|
unicode_seq,
|
|
338
338
|
alpha,
|
|
339
|
-
|
|
339
|
+
nonascii,
|
|
340
340
|
exactly<'-'>,
|
|
341
341
|
exactly<'_'>,
|
|
342
342
|
NONASCII,
|
|
@@ -351,7 +351,7 @@ namespace Sass {
|
|
|
351
351
|
return alternatives<
|
|
352
352
|
unicode_seq,
|
|
353
353
|
alnum,
|
|
354
|
-
|
|
354
|
+
nonascii,
|
|
355
355
|
exactly<'-'>,
|
|
356
356
|
exactly<'_'>,
|
|
357
357
|
NONASCII,
|
|
@@ -385,7 +385,7 @@ namespace Sass {
|
|
|
385
385
|
{
|
|
386
386
|
return alternatives <
|
|
387
387
|
alpha,
|
|
388
|
-
|
|
388
|
+
nonascii,
|
|
389
389
|
escape_seq,
|
|
390
390
|
exactly<'_'>
|
|
391
391
|
>(src);
|
|
@@ -395,7 +395,7 @@ namespace Sass {
|
|
|
395
395
|
{
|
|
396
396
|
return alternatives <
|
|
397
397
|
alnum,
|
|
398
|
-
|
|
398
|
+
nonascii,
|
|
399
399
|
escape_seq,
|
|
400
400
|
exactly<'_'>
|
|
401
401
|
>(src);
|
|
@@ -1400,7 +1400,7 @@ namespace Sass {
|
|
|
1400
1400
|
}*/
|
|
1401
1401
|
|
|
1402
1402
|
const char* H(const char* src) {
|
|
1403
|
-
return
|
|
1403
|
+
return Util::ascii_isxdigit(static_cast<unsigned char>(*src)) ? src+1 : 0;
|
|
1404
1404
|
}
|
|
1405
1405
|
|
|
1406
1406
|
const char* W(const char* src) {
|