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.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/CHANGELOG.md +18 -0
  4. data/Rakefile +1 -3
  5. data/ext/extconf.rb +13 -5
  6. data/ext/libsass/VERSION +1 -1
  7. data/ext/libsass/include/sass/base.h +2 -1
  8. data/ext/libsass/include/sass/context.h +4 -0
  9. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  10. data/ext/libsass/src/ast.cpp +158 -168
  11. data/ext/libsass/src/ast.hpp +389 -230
  12. data/ext/libsass/src/ast_def_macros.hpp +18 -10
  13. data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
  14. data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
  15. data/ext/libsass/src/ast_helpers.hpp +292 -0
  16. data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
  17. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  18. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  19. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  20. data/ext/libsass/src/ast_selectors.cpp +594 -1026
  21. data/ext/libsass/src/ast_selectors.hpp +339 -385
  22. data/ext/libsass/src/ast_supports.cpp +36 -52
  23. data/ext/libsass/src/ast_supports.hpp +29 -29
  24. data/ext/libsass/src/ast_values.cpp +271 -84
  25. data/ext/libsass/src/ast_values.hpp +116 -107
  26. data/ext/libsass/src/backtrace.cpp +9 -9
  27. data/ext/libsass/src/backtrace.hpp +5 -5
  28. data/ext/libsass/src/base64vlq.cpp +2 -2
  29. data/ext/libsass/src/base64vlq.hpp +1 -1
  30. data/ext/libsass/src/bind.cpp +18 -18
  31. data/ext/libsass/src/bind.hpp +1 -1
  32. data/ext/libsass/src/c2ast.cpp +3 -3
  33. data/ext/libsass/src/c2ast.hpp +1 -1
  34. data/ext/libsass/src/cencode.c +4 -6
  35. data/ext/libsass/src/check_nesting.cpp +40 -41
  36. data/ext/libsass/src/check_nesting.hpp +6 -2
  37. data/ext/libsass/src/color_maps.cpp +14 -13
  38. data/ext/libsass/src/color_maps.hpp +1 -9
  39. data/ext/libsass/src/constants.cpp +5 -0
  40. data/ext/libsass/src/constants.hpp +6 -0
  41. data/ext/libsass/src/context.cpp +92 -119
  42. data/ext/libsass/src/context.hpp +41 -53
  43. data/ext/libsass/src/cssize.cpp +66 -149
  44. data/ext/libsass/src/cssize.hpp +17 -23
  45. data/ext/libsass/src/dart_helpers.hpp +199 -0
  46. data/ext/libsass/src/debugger.hpp +451 -295
  47. data/ext/libsass/src/emitter.cpp +15 -16
  48. data/ext/libsass/src/emitter.hpp +10 -12
  49. data/ext/libsass/src/environment.cpp +27 -27
  50. data/ext/libsass/src/environment.hpp +29 -24
  51. data/ext/libsass/src/error_handling.cpp +62 -41
  52. data/ext/libsass/src/error_handling.hpp +61 -51
  53. data/ext/libsass/src/eval.cpp +167 -281
  54. data/ext/libsass/src/eval.hpp +27 -29
  55. data/ext/libsass/src/eval_selectors.cpp +75 -0
  56. data/ext/libsass/src/expand.cpp +275 -222
  57. data/ext/libsass/src/expand.hpp +36 -16
  58. data/ext/libsass/src/extender.cpp +1188 -0
  59. data/ext/libsass/src/extender.hpp +399 -0
  60. data/ext/libsass/src/extension.cpp +43 -0
  61. data/ext/libsass/src/extension.hpp +89 -0
  62. data/ext/libsass/src/file.cpp +81 -72
  63. data/ext/libsass/src/file.hpp +28 -37
  64. data/ext/libsass/src/fn_colors.cpp +20 -18
  65. data/ext/libsass/src/fn_lists.cpp +30 -29
  66. data/ext/libsass/src/fn_maps.cpp +3 -3
  67. data/ext/libsass/src/fn_miscs.cpp +34 -46
  68. data/ext/libsass/src/fn_numbers.cpp +20 -13
  69. data/ext/libsass/src/fn_selectors.cpp +98 -128
  70. data/ext/libsass/src/fn_strings.cpp +47 -33
  71. data/ext/libsass/src/fn_utils.cpp +31 -29
  72. data/ext/libsass/src/fn_utils.hpp +17 -11
  73. data/ext/libsass/src/inspect.cpp +186 -148
  74. data/ext/libsass/src/inspect.hpp +31 -29
  75. data/ext/libsass/src/lexer.cpp +20 -82
  76. data/ext/libsass/src/lexer.hpp +5 -16
  77. data/ext/libsass/src/listize.cpp +23 -37
  78. data/ext/libsass/src/listize.hpp +8 -9
  79. data/ext/libsass/src/mapping.hpp +1 -0
  80. data/ext/libsass/src/memory/allocator.cpp +48 -0
  81. data/ext/libsass/src/memory/allocator.hpp +138 -0
  82. data/ext/libsass/src/memory/config.hpp +20 -0
  83. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  84. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  85. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
  86. data/ext/libsass/src/memory.hpp +12 -0
  87. data/ext/libsass/src/operation.hpp +71 -61
  88. data/ext/libsass/src/operators.cpp +19 -18
  89. data/ext/libsass/src/operators.hpp +11 -11
  90. data/ext/libsass/src/ordered_map.hpp +112 -0
  91. data/ext/libsass/src/output.cpp +45 -64
  92. data/ext/libsass/src/output.hpp +6 -6
  93. data/ext/libsass/src/parser.cpp +512 -700
  94. data/ext/libsass/src/parser.hpp +89 -97
  95. data/ext/libsass/src/parser_selectors.cpp +189 -0
  96. data/ext/libsass/src/permutate.hpp +164 -0
  97. data/ext/libsass/src/plugins.cpp +7 -7
  98. data/ext/libsass/src/plugins.hpp +8 -8
  99. data/ext/libsass/src/position.cpp +7 -26
  100. data/ext/libsass/src/position.hpp +44 -21
  101. data/ext/libsass/src/prelexer.cpp +6 -6
  102. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  103. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  104. data/ext/libsass/src/sass.cpp +16 -15
  105. data/ext/libsass/src/sass.hpp +10 -5
  106. data/ext/libsass/src/sass2scss.cpp +4 -4
  107. data/ext/libsass/src/sass_context.cpp +91 -122
  108. data/ext/libsass/src/sass_context.hpp +2 -2
  109. data/ext/libsass/src/sass_functions.cpp +1 -1
  110. data/ext/libsass/src/sass_values.cpp +8 -11
  111. data/ext/libsass/src/settings.hpp +19 -0
  112. data/ext/libsass/src/source.cpp +69 -0
  113. data/ext/libsass/src/source.hpp +95 -0
  114. data/ext/libsass/src/source_data.hpp +32 -0
  115. data/ext/libsass/src/source_map.cpp +22 -18
  116. data/ext/libsass/src/source_map.hpp +12 -9
  117. data/ext/libsass/src/stylesheet.cpp +22 -0
  118. data/ext/libsass/src/stylesheet.hpp +57 -0
  119. data/ext/libsass/src/to_value.cpp +2 -2
  120. data/ext/libsass/src/to_value.hpp +1 -1
  121. data/ext/libsass/src/units.cpp +24 -22
  122. data/ext/libsass/src/units.hpp +8 -8
  123. data/ext/libsass/src/utf8_string.cpp +9 -10
  124. data/ext/libsass/src/utf8_string.hpp +7 -6
  125. data/ext/libsass/src/util.cpp +48 -50
  126. data/ext/libsass/src/util.hpp +20 -21
  127. data/ext/libsass/src/util_string.cpp +111 -61
  128. data/ext/libsass/src/util_string.hpp +62 -8
  129. data/ext/libsass/src/values.cpp +12 -12
  130. data/lib/sassc/engine.rb +5 -3
  131. data/lib/sassc/functions_handler.rb +8 -8
  132. data/lib/sassc/native.rb +4 -6
  133. data/lib/sassc/script.rb +4 -4
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/functions_test.rb +18 -1
  136. data/test/native_test.rb +4 -4
  137. metadata +29 -15
  138. data/ext/libsass/src/extend.cpp +0 -2132
  139. data/ext/libsass/src/extend.hpp +0 -86
  140. data/ext/libsass/src/node.cpp +0 -322
  141. data/ext/libsass/src/node.hpp +0 -118
  142. data/ext/libsass/src/paths.hpp +0 -71
  143. data/ext/libsass/src/sass_util.cpp +0 -152
  144. data/ext/libsass/src/sass_util.hpp +0 -256
  145. data/ext/libsass/src/subset_map.cpp +0 -58
  146. data/ext/libsass/src/subset_map.hpp +0 -76
  147. data/lib/sassc/native/lib_c.rb +0 -21
@@ -1,5 +1,8 @@
1
+ #include <numeric>
2
+
1
3
  #include "parser.hpp"
2
- #include "extend.hpp"
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( arglist->length() == 0 )
17
- error("$selectors: At least one selector must be passed for `selector-nest'", pstate, traces);
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
- Expression_Obj exp = Cast<Expression>(arglist->value_at_index(i));
28
+ ExpressionObj exp = Cast<Expression>(arglist->value_at_index(i));
23
29
  if (exp->concrete_type() == Expression::NULL_VAL) {
24
- std::stringstream msg;
25
- msg << "$selectors: null is not a valid selector: it must be a string,\n";
26
- msg << "a list of strings, or a list of lists of strings for 'selector-nest'";
27
- error(msg.str(), pstate, traces);
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
- std::string exp_src = exp->to_string(ctx.c_options);
33
- Selector_List_Obj sel = Parser::parse_selector(exp_src.c_str(), ctx, traces);
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 appending to as we go down the parsedSelector vector.
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
- Selector_List_Obj result = *itr;
52
+ SelectorListObj& result = *itr;
45
53
  ++itr;
46
54
 
47
55
  for(;itr != parsedSelectors.end(); ++itr) {
48
- Selector_List_Obj child = *itr;
49
- std::vector<Complex_Selector_Obj> exploded;
50
- selector_stack.push_back(result);
51
- Selector_List_Obj rv = child->resolve_parent_refs(selector_stack, traces);
52
- selector_stack.pop_back();
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 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( arglist->length() == 0 )
70
- error("$selectors: At least one selector must be passed for `selector-append'", pstate, traces);
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
- Expression_Obj exp = Cast<Expression>(arglist->value_at_index(i));
83
+ Expression* exp = Cast<Expression>(arglist->value_at_index(i));
76
84
  if (exp->concrete_type() == Expression::NULL_VAL) {
77
- std::stringstream msg;
78
- msg << "$selectors: null is not a valid selector: it must be a string,\n";
79
- msg << "a list of strings, or a list of lists of strings for 'selector-append'";
80
- error(msg.str(), pstate, traces);
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
- std::string exp_src = exp->to_string();
86
- Selector_List_Obj sel = Parser::parse_selector(exp_src.c_str(), ctx, traces,
87
- exp->pstate(), pstate.src,
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
- // Nothing to do
94
- if( parsedSelectors.empty() ) {
95
- return SASS_MEMORY_NEW(Null, pstate);
96
- }
97
-
98
- // Set the first element as the `result`, keep appending to as we go down the parsedSelector vector.
99
- SelectorStack::iterator itr = parsedSelectors.begin();
100
- Selector_List_Obj result = *itr;
101
- ++itr;
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
- // TODO: Add check for namespace stuff
107
+ if (parsedSelectors.size() > 1) {
134
108
 
135
- Complex_Selector* lastComponent = parentSeqClone->mutable_last();
136
- if (lastComponent->head() == nullptr) {
137
- std::string msg = "Parent \"" + parentSeqClone->to_string() + "\" is incompatible with \"" + base->to_string() + "\"";
138
- error(msg, pstate, traces);
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
- lastComponent->head()->concat(base->head());
141
- lastComponent->tail(base->tail());
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
- result->elements(newElements);
134
+ // Nothing to do
135
+ if( parsedSelectors.empty() ) {
136
+ return SASS_MEMORY_NEW(Null, pstate);
148
137
  }
149
138
 
150
- Listize 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
- Selector_List_Obj selector1 = ARGSELS("$selector1");
158
- Selector_List_Obj selector2 = ARGSELS("$selector2");
159
-
160
- Selector_List_Obj result = selector1->unify_with(selector2);
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
- Compound_Selector_Obj sel = ARGSEL("$selector");
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
- Simple_Selector_Obj ss = (*sel)[i];
174
- std::string ss_string = ss->to_string() ;
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
- Selector_List_Obj selector = ARGSELS("$selector");
186
- Selector_List_Obj extendee = ARGSELS("$extendee");
187
- Selector_List_Obj extender = ARGSELS("$extender");
188
-
189
- Subset_Map subset_map;
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
- Selector_List_Obj selector = ARGSELS("$selector");
203
- Selector_List_Obj original = ARGSELS("$original");
204
- Selector_List_Obj replacement = ARGSELS("$replacement");
205
- Subset_Map subset_map;
206
- replacement->populate_extends(original, subset_map);
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
- Selector_List_Obj sel = ARGSELS("$selector");
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
- Selector_List_Obj sel_sup = ARGSELS("$super");
228
- Selector_List_Obj sel_sub = ARGSELS("$sub");
229
- bool result = sel_sup->is_superselector_of(sel_sub);
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 ParserState& pstate, Backtraces traces)
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
- std::string msg("utf8::invalid_code_point");
21
+ sass::string msg("utf8::invalid_code_point");
22
22
  error(msg, pstate, traces);
23
23
  }
24
24
  catch (utf8::not_enough_room&) {
25
- std::string msg("utf8::not_enough_room");
25
+ sass::string msg("utf8::not_enough_room");
26
26
  error(msg, pstate, traces);
27
27
  }
28
28
  catch (utf8::invalid_utf8&) {
29
- std::string msg("utf8::invalid_utf8");
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
- std::string val(arg->to_string(ctx.c_options));
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 = std::string::npos;
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
- std::string str;
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
- std::string ins = i->value();
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 = std::string::npos;
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
- std::string str = s->value();
143
- std::string substr = t->value();
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 == std::string::npos) {
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
- std::string newstr;
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
- std::string str(s->value());
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 < 0) start_at = 0;
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
- std::string::iterator start = str.begin();
218
+ sass::string::iterator start = str.begin();
195
219
  utf8::advance(start, start_at - 1, str.end());
196
- std::string::iterator end = start;
220
+ sass::string::iterator end = start;
197
221
  utf8::advance(end, end_at - start_at + 1, str.end());
198
- newstr = std::string(start, end);
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
- std::string str = s->value();
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
- std::string str = s->value();
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);