sassc 2.2.1 → 2.4.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 +2 -0
- data/CHANGELOG.md +18 -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 +4 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +158 -168
- data/ext/libsass/src/ast.hpp +389 -230
- data/ext/libsass/src/ast_def_macros.hpp +18 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
- 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 +594 -1026
- data/ext/libsass/src/ast_selectors.hpp +339 -385
- data/ext/libsass/src/ast_supports.cpp +36 -52
- data/ext/libsass/src/ast_supports.hpp +29 -29
- data/ext/libsass/src/ast_values.cpp +271 -84
- data/ext/libsass/src/ast_values.hpp +116 -107
- data/ext/libsass/src/backtrace.cpp +9 -9
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +2 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +18 -18
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/c2ast.cpp +3 -3
- data/ext/libsass/src/c2ast.hpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +40 -41
- data/ext/libsass/src/check_nesting.hpp +6 -2
- data/ext/libsass/src/color_maps.cpp +14 -13
- data/ext/libsass/src/color_maps.hpp +1 -9
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +92 -119
- data/ext/libsass/src/context.hpp +41 -53
- data/ext/libsass/src/cssize.cpp +66 -149
- data/ext/libsass/src/cssize.hpp +17 -23
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +451 -295
- data/ext/libsass/src/emitter.cpp +15 -16
- data/ext/libsass/src/emitter.hpp +10 -12
- data/ext/libsass/src/environment.cpp +27 -27
- data/ext/libsass/src/environment.hpp +29 -24
- data/ext/libsass/src/error_handling.cpp +62 -41
- data/ext/libsass/src/error_handling.hpp +61 -51
- data/ext/libsass/src/eval.cpp +167 -281
- data/ext/libsass/src/eval.hpp +27 -29
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +275 -222
- data/ext/libsass/src/expand.hpp +36 -16
- data/ext/libsass/src/extender.cpp +1188 -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 +81 -72
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +20 -18
- data/ext/libsass/src/fn_lists.cpp +30 -29
- data/ext/libsass/src/fn_maps.cpp +3 -3
- data/ext/libsass/src/fn_miscs.cpp +34 -46
- data/ext/libsass/src/fn_numbers.cpp +20 -13
- data/ext/libsass/src/fn_selectors.cpp +98 -128
- data/ext/libsass/src/fn_strings.cpp +47 -33
- data/ext/libsass/src/fn_utils.cpp +31 -29
- data/ext/libsass/src/fn_utils.hpp +17 -11
- data/ext/libsass/src/inspect.cpp +186 -148
- data/ext/libsass/src/inspect.hpp +31 -29
- data/ext/libsass/src/lexer.cpp +20 -82
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +23 -37
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
- data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +71 -61
- data/ext/libsass/src/operators.cpp +19 -18
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +45 -64
- data/ext/libsass/src/output.hpp +6 -6
- data/ext/libsass/src/parser.cpp +512 -700
- data/ext/libsass/src/parser.hpp +89 -97
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +7 -7
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +7 -26
- data/ext/libsass/src/position.hpp +44 -21
- 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.cpp +16 -15
- data/ext/libsass/src/sass.hpp +10 -5
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +91 -122
- 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 +8 -11
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +22 -18
- data/ext/libsass/src/source_map.hpp +12 -9
- 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 +24 -22
- data/ext/libsass/src/units.hpp +8 -8
- data/ext/libsass/src/utf8_string.cpp +9 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +48 -50
- data/ext/libsass/src/util.hpp +20 -21
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +62 -8
- data/ext/libsass/src/values.cpp +12 -12
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +4 -6
- 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 +4 -4
- metadata +29 -15
- 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/lib/sassc/native/lib_c.rb +0 -21
@@ -1,5 +1,8 @@
|
|
1
|
+
#include <numeric>
|
2
|
+
|
1
3
|
#include "parser.hpp"
|
2
|
-
#include "
|
4
|
+
#include "extender.hpp"
|
5
|
+
#include "listize.hpp"
|
3
6
|
#include "fn_utils.hpp"
|
4
7
|
#include "fn_selectors.hpp"
|
5
8
|
|
@@ -13,24 +16,28 @@ namespace Sass {
|
|
13
16
|
List* arglist = ARG("$selectors", List);
|
14
17
|
|
15
18
|
// Not enough parameters
|
16
|
-
if(
|
17
|
-
error(
|
19
|
+
if (arglist->length() == 0) {
|
20
|
+
error(
|
21
|
+
"$selectors: At least one selector must be passed for `selector-nest'",
|
22
|
+
pstate, traces);
|
23
|
+
}
|
18
24
|
|
19
25
|
// Parse args into vector of selectors
|
20
26
|
SelectorStack parsedSelectors;
|
21
27
|
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
22
|
-
|
28
|
+
ExpressionObj exp = Cast<Expression>(arglist->value_at_index(i));
|
23
29
|
if (exp->concrete_type() == Expression::NULL_VAL) {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
30
|
+
error(
|
31
|
+
"$selectors: null is not a valid selector: it must be a string,\n"
|
32
|
+
"a list of strings, or a list of lists of strings for 'selector-nest'",
|
33
|
+
pstate, traces);
|
28
34
|
}
|
29
35
|
if (String_Constant_Obj str = Cast<String_Constant>(exp)) {
|
30
36
|
str->quote_mark(0);
|
31
37
|
}
|
32
|
-
|
33
|
-
|
38
|
+
sass::string exp_src = exp->to_string(ctx.c_options);
|
39
|
+
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
40
|
+
SelectorListObj sel = Parser::parse_selector(source, ctx, traces);
|
34
41
|
parsedSelectors.push_back(sel);
|
35
42
|
}
|
36
43
|
|
@@ -39,25 +46,21 @@ namespace Sass {
|
|
39
46
|
return SASS_MEMORY_NEW(Null, pstate);
|
40
47
|
}
|
41
48
|
|
42
|
-
// Set the first element as the `result`, keep
|
49
|
+
// Set the first element as the `result`, keep
|
50
|
+
// appending to as we go down the parsedSelector vector.
|
43
51
|
SelectorStack::iterator itr = parsedSelectors.begin();
|
44
|
-
|
52
|
+
SelectorListObj& result = *itr;
|
45
53
|
++itr;
|
46
54
|
|
47
55
|
for(;itr != parsedSelectors.end(); ++itr) {
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
for (size_t m = 0, mLen = rv->length(); m < mLen; ++m) {
|
54
|
-
exploded.push_back((*rv)[m]);
|
55
|
-
}
|
56
|
-
result->elements(exploded);
|
56
|
+
SelectorListObj& child = *itr;
|
57
|
+
original_stack.push_back(result);
|
58
|
+
SelectorListObj rv = child->resolve_parent_refs(original_stack, traces);
|
59
|
+
result->elements(rv->elements());
|
60
|
+
original_stack.pop_back();
|
57
61
|
}
|
58
62
|
|
59
|
-
Listize
|
60
|
-
return Cast<Value>(result->perform(&listize));
|
63
|
+
return Cast<Value>(Listize::perform(result));
|
61
64
|
}
|
62
65
|
|
63
66
|
Signature selector_append_sig = "selector-append($selectors...)";
|
@@ -66,113 +69,95 @@ namespace Sass {
|
|
66
69
|
List* arglist = ARG("$selectors", List);
|
67
70
|
|
68
71
|
// Not enough parameters
|
69
|
-
if(
|
70
|
-
error(
|
72
|
+
if (arglist->empty()) {
|
73
|
+
error(
|
74
|
+
"$selectors: At least one selector must be "
|
75
|
+
"passed for `selector-append'",
|
76
|
+
pstate, traces);
|
77
|
+
}
|
71
78
|
|
72
79
|
// Parse args into vector of selectors
|
73
80
|
SelectorStack parsedSelectors;
|
81
|
+
parsedSelectors.push_back({});
|
74
82
|
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
75
|
-
|
83
|
+
Expression* exp = Cast<Expression>(arglist->value_at_index(i));
|
76
84
|
if (exp->concrete_type() == Expression::NULL_VAL) {
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
85
|
+
error(
|
86
|
+
"$selectors: null is not a valid selector: it must be a string,\n"
|
87
|
+
"a list of strings, or a list of lists of strings for 'selector-append'",
|
88
|
+
pstate, traces);
|
81
89
|
}
|
82
90
|
if (String_Constant* str = Cast<String_Constant>(exp)) {
|
83
91
|
str->quote_mark(0);
|
84
92
|
}
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
/*allow_parent=*/false);
|
89
|
-
|
90
|
-
parsedSelectors.push_back(sel);
|
91
|
-
}
|
93
|
+
sass::string exp_src = exp->to_string();
|
94
|
+
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
95
|
+
SelectorListObj sel = Parser::parse_selector(source, ctx, traces, true);
|
92
96
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
for(;itr != parsedSelectors.end(); ++itr) {
|
104
|
-
Selector_List_Obj child = *itr;
|
105
|
-
std::vector<Complex_Selector_Obj> newElements;
|
106
|
-
|
107
|
-
// For every COMPLEX_SELECTOR in `result`
|
108
|
-
// For every COMPLEX_SELECTOR in `child`
|
109
|
-
// let parentSeqClone equal a copy of result->elements[i]
|
110
|
-
// let childSeq equal child->elements[j]
|
111
|
-
// Append all of childSeq head elements into parentSeqClone
|
112
|
-
// Set the innermost tail of parentSeqClone, to childSeq's tail
|
113
|
-
// Replace result->elements with newElements
|
114
|
-
for (size_t i = 0, resultLen = result->length(); i < resultLen; ++i) {
|
115
|
-
for (size_t j = 0, childLen = child->length(); j < childLen; ++j) {
|
116
|
-
Complex_Selector_Obj parentSeqClone = SASS_MEMORY_CLONE((*result)[i]);
|
117
|
-
Complex_Selector_Obj childSeq = (*child)[j];
|
118
|
-
Complex_Selector_Obj base = childSeq->tail();
|
119
|
-
|
120
|
-
// Must be a simple sequence
|
121
|
-
if( childSeq->combinator() != Complex_Selector::Combinator::ANCESTOR_OF ) {
|
122
|
-
error("Can't append \"" + childSeq->to_string() + "\" to \"" +
|
123
|
-
parentSeqClone->to_string() + "\" for `selector-append'", pstate, traces);
|
124
|
-
}
|
125
|
-
|
126
|
-
// Cannot be a Universal selector
|
127
|
-
Type_Selector_Obj pType = Cast<Type_Selector>(childSeq->head()->first());
|
128
|
-
if(pType && pType->name() == "*") {
|
129
|
-
error("Can't append \"" + childSeq->to_string() + "\" to \"" +
|
130
|
-
parentSeqClone->to_string() + "\" for `selector-append'", pstate, traces);
|
131
|
-
}
|
97
|
+
for (auto& complex : sel->elements()) {
|
98
|
+
if (complex->empty()) {
|
99
|
+
complex->append(SASS_MEMORY_NEW(CompoundSelector, "[phony]"));
|
100
|
+
}
|
101
|
+
if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {
|
102
|
+
comp->hasRealParent(true);
|
103
|
+
complex->chroots(true);
|
104
|
+
}
|
105
|
+
}
|
132
106
|
|
133
|
-
|
107
|
+
if (parsedSelectors.size() > 1) {
|
134
108
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
109
|
+
if (!sel->has_real_parent_ref()) {
|
110
|
+
auto parent = parsedSelectors.back();
|
111
|
+
for (auto& complex : parent->elements()) {
|
112
|
+
if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {
|
113
|
+
comp->hasRealParent(false);
|
114
|
+
}
|
139
115
|
}
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
newElements.push_back(parentSeqClone);
|
116
|
+
error("Can't append \"" + sel->to_string() + "\" to \"" +
|
117
|
+
parent->to_string() + "\" for `selector-append'",
|
118
|
+
pstate, traces);
|
144
119
|
}
|
120
|
+
|
121
|
+
// Build the resolved stack from the left. It's cheaper to directly
|
122
|
+
// calculate and update each resolved selcted from the left, than to
|
123
|
+
// recursively calculate them from the right side, as we would need
|
124
|
+
// to go through the whole stack depth to build the final results.
|
125
|
+
// E.g. 'a', 'b', 'x, y' => 'a' => 'a b' => 'a b x, a b y'
|
126
|
+
// vs 'a', 'b', 'x, y' => 'x' => 'b x' => 'a b x', 'y' ...
|
127
|
+
parsedSelectors.push_back(sel->resolve_parent_refs(parsedSelectors, traces, true));
|
145
128
|
}
|
129
|
+
else {
|
130
|
+
parsedSelectors.push_back(sel);
|
131
|
+
}
|
132
|
+
}
|
146
133
|
|
147
|
-
|
134
|
+
// Nothing to do
|
135
|
+
if( parsedSelectors.empty() ) {
|
136
|
+
return SASS_MEMORY_NEW(Null, pstate);
|
148
137
|
}
|
149
138
|
|
150
|
-
Listize
|
151
|
-
return Cast<Value>(result->perform(&listize));
|
139
|
+
return Cast<Value>(Listize::perform(parsedSelectors.back()));
|
152
140
|
}
|
153
141
|
|
154
142
|
Signature selector_unify_sig = "selector-unify($selector1, $selector2)";
|
155
143
|
BUILT_IN(selector_unify)
|
156
144
|
{
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
Listize listize;
|
162
|
-
return Cast<Value>(result->perform(&listize));
|
145
|
+
SelectorListObj selector1 = ARGSELS("$selector1");
|
146
|
+
SelectorListObj selector2 = ARGSELS("$selector2");
|
147
|
+
SelectorListObj result = selector1->unifyWith(selector2);
|
148
|
+
return Cast<Value>(Listize::perform(result));
|
163
149
|
}
|
164
150
|
|
165
151
|
Signature simple_selectors_sig = "simple-selectors($selector)";
|
166
152
|
BUILT_IN(simple_selectors)
|
167
153
|
{
|
168
|
-
|
154
|
+
CompoundSelectorObj sel = ARGSEL("$selector");
|
169
155
|
|
170
156
|
List* l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA);
|
171
157
|
|
172
158
|
for (size_t i = 0, L = sel->length(); i < L; ++i) {
|
173
|
-
|
174
|
-
|
175
|
-
|
159
|
+
const SimpleSelectorObj& ss = sel->get(i);
|
160
|
+
sass::string ss_string = ss->to_string() ;
|
176
161
|
l->append(SASS_MEMORY_NEW(String_Quoted, ss->pstate(), ss_string));
|
177
162
|
}
|
178
163
|
|
@@ -182,51 +167,36 @@ namespace Sass {
|
|
182
167
|
Signature selector_extend_sig = "selector-extend($selector, $extendee, $extender)";
|
183
168
|
BUILT_IN(selector_extend)
|
184
169
|
{
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
extender->populate_extends(extendee, subset_map);
|
191
|
-
Extend extend(subset_map);
|
192
|
-
|
193
|
-
Selector_List_Obj result = extend.extendSelectorList(selector, false);
|
194
|
-
|
195
|
-
Listize listize;
|
196
|
-
return Cast<Value>(result->perform(&listize));
|
170
|
+
SelectorListObj selector = ARGSELS("$selector");
|
171
|
+
SelectorListObj target = ARGSELS("$extendee");
|
172
|
+
SelectorListObj source = ARGSELS("$extender");
|
173
|
+
SelectorListObj result = Extender::extend(selector, source, target, traces);
|
174
|
+
return Cast<Value>(Listize::perform(result));
|
197
175
|
}
|
198
176
|
|
199
177
|
Signature selector_replace_sig = "selector-replace($selector, $original, $replacement)";
|
200
178
|
BUILT_IN(selector_replace)
|
201
179
|
{
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
Extend extend(subset_map);
|
208
|
-
|
209
|
-
Selector_List_Obj result = extend.extendSelectorList(selector, true);
|
210
|
-
|
211
|
-
Listize listize;
|
212
|
-
return Cast<Value>(result->perform(&listize));
|
180
|
+
SelectorListObj selector = ARGSELS("$selector");
|
181
|
+
SelectorListObj target = ARGSELS("$original");
|
182
|
+
SelectorListObj source = ARGSELS("$replacement");
|
183
|
+
SelectorListObj result = Extender::replace(selector, source, target, traces);
|
184
|
+
return Cast<Value>(Listize::perform(result));
|
213
185
|
}
|
214
186
|
|
215
187
|
Signature selector_parse_sig = "selector-parse($selector)";
|
216
188
|
BUILT_IN(selector_parse)
|
217
189
|
{
|
218
|
-
|
219
|
-
|
220
|
-
Listize listize;
|
221
|
-
return Cast<Value>(sel->perform(&listize));
|
190
|
+
SelectorListObj selector = ARGSELS("$selector");
|
191
|
+
return Cast<Value>(Listize::perform(selector));
|
222
192
|
}
|
223
193
|
|
224
194
|
Signature is_superselector_sig = "is-superselector($super, $sub)";
|
225
195
|
BUILT_IN(is_superselector)
|
226
196
|
{
|
227
|
-
|
228
|
-
|
229
|
-
bool result = sel_sup->
|
197
|
+
SelectorListObj sel_sup = ARGSELS("$super");
|
198
|
+
SelectorListObj sel_sub = ARGSELS("$sub");
|
199
|
+
bool result = sel_sup->isSuperselectorOf(sel_sub);
|
230
200
|
return SASS_MEMORY_NEW(Boolean, pstate, result);
|
231
201
|
}
|
232
202
|
|
@@ -2,31 +2,31 @@
|
|
2
2
|
// __EXTENSIONS__ fix on Solaris.
|
3
3
|
#include "sass.hpp"
|
4
4
|
|
5
|
-
#include <cctype>
|
6
5
|
#include "utf8.h"
|
7
6
|
#include "ast.hpp"
|
8
7
|
#include "fn_utils.hpp"
|
9
8
|
#include "fn_strings.hpp"
|
9
|
+
#include "util_string.hpp"
|
10
10
|
|
11
11
|
namespace Sass {
|
12
12
|
|
13
13
|
namespace Functions {
|
14
14
|
|
15
|
-
void handle_utf8_error (const
|
15
|
+
void handle_utf8_error (const SourceSpan& pstate, Backtraces traces)
|
16
16
|
{
|
17
17
|
try {
|
18
18
|
throw;
|
19
19
|
}
|
20
20
|
catch (utf8::invalid_code_point&) {
|
21
|
-
|
21
|
+
sass::string msg("utf8::invalid_code_point");
|
22
22
|
error(msg, pstate, traces);
|
23
23
|
}
|
24
24
|
catch (utf8::not_enough_room&) {
|
25
|
-
|
25
|
+
sass::string msg("utf8::not_enough_room");
|
26
26
|
error(msg, pstate, traces);
|
27
27
|
}
|
28
28
|
catch (utf8::invalid_utf8&) {
|
29
|
-
|
29
|
+
sass::string msg("utf8::invalid_utf8");
|
30
30
|
error(msg, pstate, traces);
|
31
31
|
}
|
32
32
|
catch (...) { throw; }
|
@@ -52,7 +52,7 @@ namespace Sass {
|
|
52
52
|
else if (Value* ex = Cast<Value>(arg)) {
|
53
53
|
Sass_Output_Style oldstyle = ctx.c_options.output_style;
|
54
54
|
ctx.c_options.output_style = SASS_STYLE_NESTED;
|
55
|
-
|
55
|
+
sass::string val(arg->to_string(ctx.c_options));
|
56
56
|
val = Cast<Null>(arg) ? "null" : val;
|
57
57
|
ctx.c_options.output_style = oldstyle;
|
58
58
|
|
@@ -76,7 +76,7 @@ namespace Sass {
|
|
76
76
|
Signature str_length_sig = "str-length($string)";
|
77
77
|
BUILT_IN(str_length)
|
78
78
|
{
|
79
|
-
size_t len =
|
79
|
+
size_t len = sass::string::npos;
|
80
80
|
try {
|
81
81
|
String_Constant* s = ARG("$string", String_Constant);
|
82
82
|
len = UTF_8::code_point_count(s->value(), 0, s->value().size());
|
@@ -92,13 +92,20 @@ namespace Sass {
|
|
92
92
|
Signature str_insert_sig = "str-insert($string, $insert, $index)";
|
93
93
|
BUILT_IN(str_insert)
|
94
94
|
{
|
95
|
-
|
95
|
+
sass::string str;
|
96
96
|
try {
|
97
97
|
String_Constant* s = ARG("$string", String_Constant);
|
98
98
|
str = s->value();
|
99
99
|
String_Constant* i = ARG("$insert", String_Constant);
|
100
|
-
|
100
|
+
sass::string ins = i->value();
|
101
101
|
double index = ARGVAL("$index");
|
102
|
+
if (index != (int)index) {
|
103
|
+
sass::ostream strm;
|
104
|
+
strm << "$index: ";
|
105
|
+
strm << std::to_string(index);
|
106
|
+
strm << " is not an int";
|
107
|
+
error(strm.str(), pstate, traces);
|
108
|
+
}
|
102
109
|
size_t len = UTF_8::code_point_count(str, 0, str.size());
|
103
110
|
|
104
111
|
if (index > 0 && index <= len) {
|
@@ -135,15 +142,15 @@ namespace Sass {
|
|
135
142
|
Signature str_index_sig = "str-index($string, $substring)";
|
136
143
|
BUILT_IN(str_index)
|
137
144
|
{
|
138
|
-
size_t index =
|
145
|
+
size_t index = sass::string::npos;
|
139
146
|
try {
|
140
147
|
String_Constant* s = ARG("$string", String_Constant);
|
141
148
|
String_Constant* t = ARG("$substring", String_Constant);
|
142
|
-
|
143
|
-
|
149
|
+
sass::string str = s->value();
|
150
|
+
sass::string substr = t->value();
|
144
151
|
|
145
152
|
size_t c_index = str.find(substr);
|
146
|
-
if(c_index ==
|
153
|
+
if(c_index == sass::string::npos) {
|
147
154
|
return SASS_MEMORY_NEW(Null, pstate);
|
148
155
|
}
|
149
156
|
index = UTF_8::code_point_count(str, 0, c_index) + 1;
|
@@ -158,14 +165,23 @@ namespace Sass {
|
|
158
165
|
Signature str_slice_sig = "str-slice($string, $start-at, $end-at:-1)";
|
159
166
|
BUILT_IN(str_slice)
|
160
167
|
{
|
161
|
-
|
168
|
+
sass::string newstr;
|
162
169
|
try {
|
163
170
|
String_Constant* s = ARG("$string", String_Constant);
|
164
171
|
double start_at = ARGVAL("$start-at");
|
165
172
|
double end_at = ARGVAL("$end-at");
|
173
|
+
|
174
|
+
if (start_at != (int)start_at) {
|
175
|
+
sass::ostream strm;
|
176
|
+
strm << "$start-at: ";
|
177
|
+
strm << std::to_string(start_at);
|
178
|
+
strm << " is not an int";
|
179
|
+
error(strm.str(), pstate, traces);
|
180
|
+
}
|
181
|
+
|
166
182
|
String_Quoted* ss = Cast<String_Quoted>(s);
|
167
183
|
|
168
|
-
|
184
|
+
sass::string str(s->value());
|
169
185
|
|
170
186
|
size_t size = utf8::distance(str.begin(), str.end());
|
171
187
|
|
@@ -173,6 +189,14 @@ namespace Sass {
|
|
173
189
|
end_at = -1;
|
174
190
|
}
|
175
191
|
|
192
|
+
if (end_at != (int)end_at) {
|
193
|
+
sass::ostream strm;
|
194
|
+
strm << "$end-at: ";
|
195
|
+
strm << std::to_string(end_at);
|
196
|
+
strm << " is not an int";
|
197
|
+
error(strm.str(), pstate, traces);
|
198
|
+
}
|
199
|
+
|
176
200
|
if (end_at == 0 || (end_at + size) < 0) {
|
177
201
|
if (ss && ss->quote_mark()) newstr = quote("");
|
178
202
|
return SASS_MEMORY_NEW(String_Quoted, pstate, newstr);
|
@@ -185,17 +209,17 @@ namespace Sass {
|
|
185
209
|
if (end_at > size) { end_at = (double)size; }
|
186
210
|
if (start_at < 0) {
|
187
211
|
start_at += size + 1;
|
188
|
-
if (start_at
|
212
|
+
if (start_at <= 0) start_at = 1;
|
189
213
|
}
|
190
214
|
else if (start_at == 0) { ++ start_at; }
|
191
215
|
|
192
216
|
if (start_at <= end_at)
|
193
217
|
{
|
194
|
-
|
218
|
+
sass::string::iterator start = str.begin();
|
195
219
|
utf8::advance(start, start_at - 1, str.end());
|
196
|
-
|
220
|
+
sass::string::iterator end = start;
|
197
221
|
utf8::advance(end, end_at - start_at + 1, str.end());
|
198
|
-
newstr =
|
222
|
+
newstr = sass::string(start, end);
|
199
223
|
}
|
200
224
|
if (ss) {
|
201
225
|
if(ss->quote_mark()) newstr = quote(newstr);
|
@@ -211,13 +235,8 @@ namespace Sass {
|
|
211
235
|
BUILT_IN(to_upper_case)
|
212
236
|
{
|
213
237
|
String_Constant* s = ARG("$string", String_Constant);
|
214
|
-
|
215
|
-
|
216
|
-
for (size_t i = 0, L = str.length(); i < L; ++i) {
|
217
|
-
if (Sass::Util::isAscii(str[i])) {
|
218
|
-
str[i] = std::toupper(str[i]);
|
219
|
-
}
|
220
|
-
}
|
238
|
+
sass::string str = s->value();
|
239
|
+
Util::ascii_str_toupper(&str);
|
221
240
|
|
222
241
|
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
223
242
|
String_Quoted* cpy = SASS_MEMORY_COPY(ss);
|
@@ -232,13 +251,8 @@ namespace Sass {
|
|
232
251
|
BUILT_IN(to_lower_case)
|
233
252
|
{
|
234
253
|
String_Constant* s = ARG("$string", String_Constant);
|
235
|
-
|
236
|
-
|
237
|
-
for (size_t i = 0, L = str.length(); i < L; ++i) {
|
238
|
-
if (Sass::Util::isAscii(str[i])) {
|
239
|
-
str[i] = std::tolower(str[i]);
|
240
|
-
}
|
241
|
-
}
|
254
|
+
sass::string str = s->value();
|
255
|
+
Util::ascii_str_tolower(&str);
|
242
256
|
|
243
257
|
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
244
258
|
String_Quoted* cpy = SASS_MEMORY_COPY(ss);
|