sassc 2.0.1 → 2.1.0.pre1

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 (200) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +7 -3
  5. data/CHANGELOG.md +3 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +23 -8
  9. data/ext/extconf.rb +39 -0
  10. data/ext/libsass/.gitignore +1 -0
  11. data/ext/libsass/GNUmakefile.am +23 -39
  12. data/ext/libsass/Makefile +56 -91
  13. data/ext/libsass/Makefile.conf +16 -2
  14. data/ext/libsass/configure.ac +8 -12
  15. data/ext/libsass/include/sass/base.h +1 -0
  16. data/ext/libsass/include/sass/context.h +1 -1
  17. data/ext/libsass/src/GNUmakefile.am +1 -5
  18. data/ext/libsass/src/ast.cpp +747 -2010
  19. data/ext/libsass/src/ast.hpp +239 -2383
  20. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  21. data/ext/libsass/src/ast2c.hpp +39 -0
  22. data/ext/libsass/src/ast_def_macros.hpp +62 -10
  23. data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
  24. data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
  25. data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
  26. data/ext/libsass/src/ast_sel_unify.cpp +280 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1475 -0
  28. data/ext/libsass/src/ast_selectors.hpp +568 -0
  29. data/ext/libsass/src/ast_supports.cpp +130 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +967 -0
  32. data/ext/libsass/src/ast_values.hpp +489 -0
  33. data/ext/libsass/src/backtrace.cpp +4 -0
  34. data/ext/libsass/src/base64vlq.cpp +3 -0
  35. data/ext/libsass/src/bind.cpp +18 -17
  36. data/ext/libsass/src/bind.hpp +3 -1
  37. data/ext/libsass/src/c2ast.cpp +64 -0
  38. data/ext/libsass/src/c2ast.hpp +14 -0
  39. data/ext/libsass/src/cencode.c +2 -2
  40. data/ext/libsass/src/check_nesting.cpp +52 -56
  41. data/ext/libsass/src/check_nesting.hpp +35 -34
  42. data/ext/libsass/src/color_maps.cpp +156 -153
  43. data/ext/libsass/src/color_maps.hpp +152 -152
  44. data/ext/libsass/src/constants.cpp +15 -0
  45. data/ext/libsass/src/constants.hpp +13 -0
  46. data/ext/libsass/src/context.cpp +24 -14
  47. data/ext/libsass/src/context.hpp +6 -6
  48. data/ext/libsass/src/cssize.cpp +69 -71
  49. data/ext/libsass/src/cssize.hpp +50 -50
  50. data/ext/libsass/src/debugger.hpp +117 -110
  51. data/ext/libsass/src/emitter.cpp +13 -12
  52. data/ext/libsass/src/emitter.hpp +13 -9
  53. data/ext/libsass/src/environment.cpp +15 -1
  54. data/ext/libsass/src/environment.hpp +6 -0
  55. data/ext/libsass/src/error_handling.cpp +36 -59
  56. data/ext/libsass/src/error_handling.hpp +29 -16
  57. data/ext/libsass/src/eval.cpp +302 -323
  58. data/ext/libsass/src/eval.hpp +64 -55
  59. data/ext/libsass/src/expand.cpp +94 -88
  60. data/ext/libsass/src/expand.hpp +33 -37
  61. data/ext/libsass/src/extend.cpp +38 -36
  62. data/ext/libsass/src/extend.hpp +15 -15
  63. data/ext/libsass/src/file.cpp +34 -2
  64. data/ext/libsass/src/fn_colors.cpp +594 -0
  65. data/ext/libsass/src/fn_colors.hpp +85 -0
  66. data/ext/libsass/src/fn_lists.cpp +284 -0
  67. data/ext/libsass/src/fn_lists.hpp +34 -0
  68. data/ext/libsass/src/fn_maps.cpp +94 -0
  69. data/ext/libsass/src/fn_maps.hpp +30 -0
  70. data/ext/libsass/src/fn_miscs.cpp +256 -0
  71. data/ext/libsass/src/fn_miscs.hpp +40 -0
  72. data/ext/libsass/src/fn_numbers.cpp +220 -0
  73. data/ext/libsass/src/fn_numbers.hpp +45 -0
  74. data/ext/libsass/src/fn_selectors.cpp +235 -0
  75. data/ext/libsass/src/fn_selectors.hpp +35 -0
  76. data/ext/libsass/src/fn_strings.cpp +254 -0
  77. data/ext/libsass/src/fn_strings.hpp +34 -0
  78. data/ext/libsass/src/fn_utils.cpp +156 -0
  79. data/ext/libsass/src/fn_utils.hpp +56 -0
  80. data/ext/libsass/src/inspect.cpp +101 -152
  81. data/ext/libsass/src/inspect.hpp +69 -73
  82. data/ext/libsass/src/json.cpp +2 -2
  83. data/ext/libsass/src/lexer.cpp +6 -3
  84. data/ext/libsass/src/listize.cpp +9 -11
  85. data/ext/libsass/src/listize.hpp +11 -7
  86. data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
  87. data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
  88. data/ext/libsass/src/node.cpp +13 -10
  89. data/ext/libsass/src/node.hpp +3 -3
  90. data/ext/libsass/src/operation.hpp +184 -144
  91. data/ext/libsass/src/operators.cpp +43 -17
  92. data/ext/libsass/src/operators.hpp +5 -5
  93. data/ext/libsass/src/output.cpp +21 -18
  94. data/ext/libsass/src/output.hpp +14 -21
  95. data/ext/libsass/src/parser.cpp +215 -183
  96. data/ext/libsass/src/parser.hpp +28 -24
  97. data/ext/libsass/src/plugins.cpp +5 -1
  98. data/ext/libsass/src/position.cpp +3 -0
  99. data/ext/libsass/src/prelexer.cpp +9 -3
  100. data/ext/libsass/src/prelexer.hpp +9 -9
  101. data/ext/libsass/src/remove_placeholders.cpp +14 -11
  102. data/ext/libsass/src/remove_placeholders.hpp +8 -9
  103. data/ext/libsass/src/sass.cpp +9 -3
  104. data/ext/libsass/src/sass.hpp +12 -9
  105. data/ext/libsass/src/sass2scss.cpp +45 -14
  106. data/ext/libsass/src/sass_context.cpp +18 -15
  107. data/ext/libsass/src/sass_functions.cpp +6 -3
  108. data/ext/libsass/src/sass_functions.hpp +1 -1
  109. data/ext/libsass/src/sass_util.cpp +3 -0
  110. data/ext/libsass/src/sass_values.cpp +21 -13
  111. data/ext/libsass/src/source_map.cpp +5 -2
  112. data/ext/libsass/src/source_map.hpp +2 -2
  113. data/ext/libsass/src/subset_map.cpp +4 -1
  114. data/ext/libsass/src/to_value.cpp +23 -21
  115. data/ext/libsass/src/to_value.hpp +18 -22
  116. data/ext/libsass/src/units.cpp +4 -0
  117. data/ext/libsass/src/units.hpp +1 -0
  118. data/ext/libsass/src/utf8/checked.h +12 -10
  119. data/ext/libsass/src/utf8/core.h +3 -0
  120. data/ext/libsass/src/utf8_string.cpp +3 -0
  121. data/ext/libsass/src/util.cpp +67 -75
  122. data/ext/libsass/src/util.hpp +64 -19
  123. data/ext/libsass/src/util_string.cpp +75 -0
  124. data/ext/libsass/src/util_string.hpp +19 -0
  125. data/ext/libsass/src/values.cpp +22 -13
  126. data/ext/libsass/src/values.hpp +2 -2
  127. data/ext/libsass/win/libsass.targets +30 -4
  128. data/ext/libsass/win/libsass.vcxproj.filters +82 -4
  129. data/lib/sassc.rb +24 -0
  130. data/lib/sassc/engine.rb +2 -2
  131. data/lib/sassc/native.rb +8 -1
  132. data/lib/sassc/version.rb +1 -1
  133. data/sassc.gemspec +19 -11
  134. data/test/engine_test.rb +26 -1
  135. data/test/native_test.rb +1 -1
  136. metadata +66 -72
  137. data/ext/Rakefile +0 -3
  138. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  139. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  140. data/ext/libsass/.travis.yml +0 -64
  141. data/ext/libsass/Readme.md +0 -104
  142. data/ext/libsass/SECURITY.md +0 -10
  143. data/ext/libsass/appveyor.yml +0 -91
  144. data/ext/libsass/docs/README.md +0 -20
  145. data/ext/libsass/docs/api-context-example.md +0 -45
  146. data/ext/libsass/docs/api-context-internal.md +0 -163
  147. data/ext/libsass/docs/api-context.md +0 -295
  148. data/ext/libsass/docs/api-doc.md +0 -215
  149. data/ext/libsass/docs/api-function-example.md +0 -67
  150. data/ext/libsass/docs/api-function-internal.md +0 -8
  151. data/ext/libsass/docs/api-function.md +0 -74
  152. data/ext/libsass/docs/api-importer-example.md +0 -112
  153. data/ext/libsass/docs/api-importer-internal.md +0 -20
  154. data/ext/libsass/docs/api-importer.md +0 -86
  155. data/ext/libsass/docs/api-value-example.md +0 -55
  156. data/ext/libsass/docs/api-value-internal.md +0 -76
  157. data/ext/libsass/docs/api-value.md +0 -154
  158. data/ext/libsass/docs/build-on-darwin.md +0 -27
  159. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  160. data/ext/libsass/docs/build-on-windows.md +0 -139
  161. data/ext/libsass/docs/build-shared-library.md +0 -35
  162. data/ext/libsass/docs/build-with-autotools.md +0 -78
  163. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  164. data/ext/libsass/docs/build-with-mingw.md +0 -107
  165. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  166. data/ext/libsass/docs/build.md +0 -97
  167. data/ext/libsass/docs/compatibility-plan.md +0 -48
  168. data/ext/libsass/docs/contributing.md +0 -17
  169. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  170. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  171. data/ext/libsass/docs/implementations.md +0 -56
  172. data/ext/libsass/docs/plugins.md +0 -47
  173. data/ext/libsass/docs/setup-environment.md +0 -68
  174. data/ext/libsass/docs/source-map-internals.md +0 -51
  175. data/ext/libsass/docs/trace.md +0 -26
  176. data/ext/libsass/docs/triage.md +0 -17
  177. data/ext/libsass/docs/unicode.md +0 -39
  178. data/ext/libsass/extconf.rb +0 -6
  179. data/ext/libsass/script/bootstrap +0 -13
  180. data/ext/libsass/script/branding +0 -10
  181. data/ext/libsass/script/ci-build-libsass +0 -134
  182. data/ext/libsass/script/ci-build-plugin +0 -62
  183. data/ext/libsass/script/ci-install-compiler +0 -6
  184. data/ext/libsass/script/ci-install-deps +0 -20
  185. data/ext/libsass/script/ci-report-coverage +0 -42
  186. data/ext/libsass/script/spec +0 -5
  187. data/ext/libsass/script/tap-driver +0 -652
  188. data/ext/libsass/script/tap-runner +0 -1
  189. data/ext/libsass/script/test-leaks.pl +0 -103
  190. data/ext/libsass/src/functions.cpp +0 -2234
  191. data/ext/libsass/src/functions.hpp +0 -198
  192. data/ext/libsass/src/to_c.hpp +0 -39
  193. data/ext/libsass/test/test_node.cpp +0 -94
  194. data/ext/libsass/test/test_paths.cpp +0 -28
  195. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  196. data/ext/libsass/test/test_specificity.cpp +0 -25
  197. data/ext/libsass/test/test_subset_map.cpp +0 -472
  198. data/ext/libsass/test/test_superselector.cpp +0 -69
  199. data/ext/libsass/test/test_unification.cpp +0 -31
  200. data/lib/tasks/libsass.rb +0 -33
@@ -83,6 +83,7 @@ namespace Sass {
83
83
  // compare operations
84
84
  bool operator< (const Units& rhs) const;
85
85
  bool operator== (const Units& rhs) const;
86
+ bool operator!= (const Units& rhs) const;
86
87
  // factor to convert into given units
87
88
  double convert_factor(const Units&) const;
88
89
  };
@@ -1,4 +1,4 @@
1
- // Copyright 2006 Nemanja Trifunovic
1
+ // Copyright 2006-2016 Nemanja Trifunovic
2
2
 
3
3
  /*
4
4
  Permission is hereby granted, free of charge, to any person or organization
@@ -41,7 +41,7 @@ namespace utf8
41
41
  class invalid_code_point : public exception {
42
42
  uint32_t cp;
43
43
  public:
44
- invalid_code_point(uint32_t cp) : cp(cp) {}
44
+ invalid_code_point(uint32_t codepoint) : cp(codepoint) {}
45
45
  virtual const char* what() const throw() { return "Invalid code point"; }
46
46
  uint32_t code_point() const {return cp;}
47
47
  };
@@ -107,7 +107,9 @@ namespace utf8
107
107
  *out++ = *it;
108
108
  break;
109
109
  case internal::NOT_ENOUGH_ROOM:
110
- throw not_enough_room();
110
+ out = utf8::append (replacement, out);
111
+ start = end;
112
+ break;
111
113
  case internal::INVALID_LEAD:
112
114
  out = utf8::append (replacement, out);
113
115
  ++start;
@@ -194,10 +196,10 @@ namespace utf8
194
196
  }
195
197
 
196
198
  template <typename octet_iterator, typename distance_type>
197
- void retreat (octet_iterator& it, distance_type n, octet_iterator start)
199
+ void retreat (octet_iterator& it, distance_type n, octet_iterator end)
198
200
  {
199
201
  for (distance_type i = 0; i < n; ++i)
200
- utf8::prior(it, start);
202
+ utf8::prior(it, end);
201
203
  }
202
204
 
203
205
  template <typename octet_iterator>
@@ -240,7 +242,7 @@ namespace utf8
240
242
  template <typename u16bit_iterator, typename octet_iterator>
241
243
  u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
242
244
  {
243
- while (start != end) {
245
+ while (start < end) {
244
246
  uint32_t cp = utf8::next(start, end);
245
247
  if (cp > 0xffff) { //make a surrogate pair
246
248
  *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
@@ -264,7 +266,7 @@ namespace utf8
264
266
  template <typename octet_iterator, typename u32bit_iterator>
265
267
  u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
266
268
  {
267
- while (start != end)
269
+ while (start < end)
268
270
  (*result++) = utf8::next(start, end);
269
271
 
270
272
  return result;
@@ -279,9 +281,9 @@ namespace utf8
279
281
  public:
280
282
  iterator () {}
281
283
  explicit iterator (const octet_iterator& octet_it,
282
- const octet_iterator& range_start,
283
- const octet_iterator& range_end) :
284
- it(octet_it), range_start(range_start), range_end(range_end)
284
+ const octet_iterator& rangestart,
285
+ const octet_iterator& rangeend) :
286
+ it(octet_it), range_start(rangestart), range_end(rangeend)
285
287
  {
286
288
  if (it < range_start || it > range_end)
287
289
  throw std::out_of_range("Invalid utf-8 iterator position");
@@ -222,6 +222,9 @@ namespace internal
222
222
  template <typename octet_iterator>
223
223
  utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
224
224
  {
225
+ if (it == end)
226
+ return NOT_ENOUGH_ROOM;
227
+
225
228
  // Save the original value of it so we can go back in case of failure
226
229
  // Of course, it does not make much sense with i.e. stream iterators
227
230
  octet_iterator original_it = it;
@@ -1,4 +1,7 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
1
3
  #include "sass.hpp"
4
+
2
5
  #include <string>
3
6
  #include <vector>
4
7
  #include <cstdlib>
@@ -163,42 +163,64 @@ namespace Sass {
163
163
  std::replace(str.begin(), str.end(), '\n', ' ');
164
164
  }
165
165
 
166
- // bell characters are replaced with spaces
167
- // also eats spaces after line-feeds (ltrim)
166
+ // 1. Removes whitespace after newlines.
167
+ // 2. Replaces newlines with spaces.
168
+ //
169
+ // This method only considers LF and CRLF as newlines.
168
170
  std::string string_to_output(const std::string& str)
169
171
  {
170
- std::string out("");
171
- bool lf = false;
172
- for (auto i : str) {
173
- if (i == '\n') {
174
- out += ' ';
175
- lf = true;
176
- } else if (!(lf && isspace(i))) {
177
- out += i;
178
- lf = false;
172
+ std::string result;
173
+ result.reserve(str.size());
174
+ std::size_t pos = 0;
175
+ while (true) {
176
+ const std::size_t newline = str.find_first_of("\n\r", pos);
177
+ if (newline == std::string::npos) break;
178
+ result.append(str, pos, newline - pos);
179
+ if (str[newline] == '\r') {
180
+ if (str[newline + 1] == '\n') {
181
+ pos = newline + 2;
182
+ } else {
183
+ // CR without LF: append as-is and continue.
184
+ result += '\r';
185
+ pos = newline + 1;
186
+ continue;
187
+ }
188
+ } else {
189
+ pos = newline + 1;
190
+ }
191
+ result += ' ';
192
+ const std::size_t non_space = str.find_first_not_of(" \f\n\r\t\v", pos);
193
+ if (non_space != std::string::npos) {
194
+ pos = non_space;
179
195
  }
180
196
  }
181
- return out;
197
+ result.append(str, pos, std::string::npos);
198
+ return result;
182
199
  }
183
200
 
184
201
  std::string escape_string(const std::string& str)
185
202
  {
186
- std::string out("");
187
- for (auto i : str) {
188
- if (i == '\n') {
189
- out += "\\n";
190
- } else if (i == '\r') {
191
- out += "\\r";
192
- } else if (i == '\t') {
193
- out += "\\t";
194
- } else {
195
- out += i;
203
+ std::string out;
204
+ out.reserve(str.size());
205
+ for (char c : str) {
206
+ switch (c) {
207
+ case '\n':
208
+ out.append("\\n");
209
+ break;
210
+ case '\r':
211
+ out.append("\\r");
212
+ break;
213
+ case '\f':
214
+ out.append("\\f");
215
+ break;
216
+ default:
217
+ out += c;
196
218
  }
197
219
  }
198
220
  return out;
199
221
  }
200
222
 
201
- std::string comment_to_string(const std::string& text)
223
+ std::string comment_to_compact_string(const std::string& text)
202
224
  {
203
225
  std::string str = "";
204
226
  size_t has = 0;
@@ -207,7 +229,6 @@ namespace Sass {
207
229
  for (auto i : text) {
208
230
  if (clean) {
209
231
  if (i == '\n') { has = 0; }
210
- else if (i == '\r') { has = 0; }
211
232
  else if (i == '\t') { ++ has; }
212
233
  else if (i == ' ') { ++ has; }
213
234
  else if (i == '*') {}
@@ -219,8 +240,6 @@ namespace Sass {
219
240
  }
220
241
  } else if (i == '\n') {
221
242
  clean = true;
222
- } else if (i == '\r') {
223
- clean = true;
224
243
  } else {
225
244
  str += i;
226
245
  }
@@ -508,42 +527,15 @@ namespace Sass {
508
527
  }
509
528
 
510
529
  namespace Util {
511
- using std::string;
512
-
513
- std::string rtrim(const std::string &str) {
514
- std::string trimmed = str;
515
- size_t pos_ws = trimmed.find_last_not_of(" \t\n\v\f\r");
516
- if (pos_ws != std::string::npos)
517
- { trimmed.erase(pos_ws + 1); }
518
- else { trimmed.clear(); }
519
- return trimmed;
520
- }
521
-
522
- std::string normalize_underscores(const std::string& str) {
523
- std::string normalized = str;
524
- for(size_t i = 0, L = normalized.length(); i < L; ++i) {
525
- if(normalized[i] == '_') {
526
- normalized[i] = '-';
527
- }
528
- }
529
- return normalized;
530
- }
531
-
532
- std::string normalize_decimals(const std::string& str) {
533
- std::string prefix = "0";
534
- std::string normalized = str;
535
-
536
- return normalized[0] == '.' ? normalized.insert(0, prefix) : normalized;
537
- }
538
530
 
539
- bool isPrintable(Ruleset_Ptr r, Sass_Output_Style style) {
531
+ bool isPrintable(Ruleset* r, Sass_Output_Style style) {
540
532
  if (r == NULL) {
541
533
  return false;
542
534
  }
543
535
 
544
536
  Block_Obj b = r->block();
545
537
 
546
- Selector_List_Ptr sl = Cast<Selector_List>(r->selector());
538
+ Selector_List* sl = Cast<Selector_List>(r->selector());
547
539
  bool hasSelectors = sl ? sl->length() > 0 : false;
548
540
 
549
541
  if (!hasSelectors) {
@@ -556,14 +548,14 @@ namespace Sass {
556
548
  Statement_Obj stm = b->at(i);
557
549
  if (Cast<Directive>(stm)) {
558
550
  return true;
559
- } else if (Declaration_Ptr d = Cast<Declaration>(stm)) {
551
+ } else if (Declaration* d = Cast<Declaration>(stm)) {
560
552
  return isPrintable(d, style);
561
- } else if (Has_Block_Ptr p = Cast<Has_Block>(stm)) {
553
+ } else if (Has_Block* p = Cast<Has_Block>(stm)) {
562
554
  Block_Obj pChildBlock = p->block();
563
555
  if (isPrintable(pChildBlock, style)) {
564
556
  hasPrintableChildBlocks = true;
565
557
  }
566
- } else if (Comment_Ptr c = Cast<Comment>(stm)) {
558
+ } else if (Comment* c = Cast<Comment>(stm)) {
567
559
  // keep for uncompressed
568
560
  if (style != COMPRESSED) {
569
561
  hasDeclarations = true;
@@ -584,17 +576,17 @@ namespace Sass {
584
576
  return false;
585
577
  }
586
578
 
587
- bool isPrintable(String_Constant_Ptr s, Sass_Output_Style style)
579
+ bool isPrintable(String_Constant* s, Sass_Output_Style style)
588
580
  {
589
581
  return ! s->value().empty();
590
582
  }
591
583
 
592
- bool isPrintable(String_Quoted_Ptr s, Sass_Output_Style style)
584
+ bool isPrintable(String_Quoted* s, Sass_Output_Style style)
593
585
  {
594
586
  return true;
595
587
  }
596
588
 
597
- bool isPrintable(Declaration_Ptr d, Sass_Output_Style style)
589
+ bool isPrintable(Declaration* d, Sass_Output_Style style)
598
590
  {
599
591
  Expression_Obj val = d->value();
600
592
  if (String_Quoted_Obj sq = Cast<String_Quoted>(val)) return isPrintable(sq.ptr(), style);
@@ -602,7 +594,7 @@ namespace Sass {
602
594
  return true;
603
595
  }
604
596
 
605
- bool isPrintable(Supports_Block_Ptr f, Sass_Output_Style style) {
597
+ bool isPrintable(Supports_Block* f, Sass_Output_Style style) {
606
598
  if (f == NULL) {
607
599
  return false;
608
600
  }
@@ -616,7 +608,7 @@ namespace Sass {
616
608
  if (Cast<Declaration>(stm) || Cast<Directive>(stm)) {
617
609
  hasDeclarations = true;
618
610
  }
619
- else if (Has_Block_Ptr b = Cast<Has_Block>(stm)) {
611
+ else if (Has_Block* b = Cast<Has_Block>(stm)) {
620
612
  Block_Obj pChildBlock = b->block();
621
613
  if (!b->is_invisible()) {
622
614
  if (isPrintable(pChildBlock, style)) {
@@ -633,7 +625,7 @@ namespace Sass {
633
625
  return false;
634
626
  }
635
627
 
636
- bool isPrintable(Media_Block_Ptr m, Sass_Output_Style style)
628
+ bool isPrintable(Media_Block* m, Sass_Output_Style style)
637
629
  {
638
630
  if (m == 0) return false;
639
631
  Block_Obj b = m->block();
@@ -642,27 +634,27 @@ namespace Sass {
642
634
  Statement_Obj stm = b->at(i);
643
635
  if (Cast<Directive>(stm)) return true;
644
636
  else if (Cast<Declaration>(stm)) return true;
645
- else if (Comment_Ptr c = Cast<Comment>(stm)) {
637
+ else if (Comment* c = Cast<Comment>(stm)) {
646
638
  if (isPrintable(c, style)) {
647
639
  return true;
648
640
  }
649
641
  }
650
- else if (Ruleset_Ptr r = Cast<Ruleset>(stm)) {
642
+ else if (Ruleset* r = Cast<Ruleset>(stm)) {
651
643
  if (isPrintable(r, style)) {
652
644
  return true;
653
645
  }
654
646
  }
655
- else if (Supports_Block_Ptr f = Cast<Supports_Block>(stm)) {
647
+ else if (Supports_Block* f = Cast<Supports_Block>(stm)) {
656
648
  if (isPrintable(f, style)) {
657
649
  return true;
658
650
  }
659
651
  }
660
- else if (Media_Block_Ptr mb = Cast<Media_Block>(stm)) {
652
+ else if (Media_Block* mb = Cast<Media_Block>(stm)) {
661
653
  if (isPrintable(mb, style)) {
662
654
  return true;
663
655
  }
664
656
  }
665
- else if (Has_Block_Ptr b = Cast<Has_Block>(stm)) {
657
+ else if (Has_Block* b = Cast<Has_Block>(stm)) {
666
658
  if (isPrintable(b->block(), style)) {
667
659
  return true;
668
660
  }
@@ -671,7 +663,7 @@ namespace Sass {
671
663
  return false;
672
664
  }
673
665
 
674
- bool isPrintable(Comment_Ptr c, Sass_Output_Style style)
666
+ bool isPrintable(Comment* c, Sass_Output_Style style)
675
667
  {
676
668
  // keep for uncompressed
677
669
  if (style != COMPRESSED) {
@@ -695,27 +687,27 @@ namespace Sass {
695
687
  if (Cast<Declaration>(stm) || Cast<Directive>(stm)) {
696
688
  return true;
697
689
  }
698
- else if (Comment_Ptr c = Cast<Comment>(stm)) {
690
+ else if (Comment* c = Cast<Comment>(stm)) {
699
691
  if (isPrintable(c, style)) {
700
692
  return true;
701
693
  }
702
694
  }
703
- else if (Ruleset_Ptr r = Cast<Ruleset>(stm)) {
695
+ else if (Ruleset* r = Cast<Ruleset>(stm)) {
704
696
  if (isPrintable(r, style)) {
705
697
  return true;
706
698
  }
707
699
  }
708
- else if (Supports_Block_Ptr f = Cast<Supports_Block>(stm)) {
700
+ else if (Supports_Block* f = Cast<Supports_Block>(stm)) {
709
701
  if (isPrintable(f, style)) {
710
702
  return true;
711
703
  }
712
704
  }
713
- else if (Media_Block_Ptr m = Cast<Media_Block>(stm)) {
705
+ else if (Media_Block* m = Cast<Media_Block>(stm)) {
714
706
  if (isPrintable(m, style)) {
715
707
  return true;
716
708
  }
717
709
  }
718
- else if (Has_Block_Ptr b = Cast<Has_Block>(stm)) {
710
+ else if (Has_Block* b = Cast<Has_Block>(stm)) {
719
711
  if (isPrintable(b->block(), style)) {
720
712
  return true;
721
713
  }
@@ -1,21 +1,34 @@
1
1
  #ifndef SASS_UTIL_H
2
2
  #define SASS_UTIL_H
3
3
 
4
- #include <vector>
5
- #include <string>
6
- #include <assert.h>
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
7
6
  #include "sass.hpp"
7
+
8
8
  #include "sass/base.h"
9
9
  #include "ast_fwd_decl.hpp"
10
10
 
11
+ #include <cstring>
12
+ #include <vector>
13
+ #include <string>
14
+ #include <assert.h>
15
+ #include <math.h>
16
+
11
17
  #define SASS_ASSERT(cond, msg) assert(cond && msg)
12
18
 
13
19
  namespace Sass {
14
20
 
15
- #define out_of_memory() do { \
16
- std::cerr << "Out of memory.\n"; \
17
- exit(EXIT_FAILURE); \
18
- } while (0)
21
+ template <typename T>
22
+ T clip(const T& n, const T& lower, const T& upper) {
23
+ return std::max(lower, std::min(n, upper));
24
+ }
25
+
26
+ template <typename T>
27
+ T absmod(const T& n, const T& r) {
28
+ T m = std::fmod(n, r);
29
+ if (m < 0.0) m += r;
30
+ return m;
31
+ }
19
32
 
20
33
  double round(double val, size_t precision = 0);
21
34
  double sass_strtod(const char* str);
@@ -25,7 +38,7 @@ namespace Sass {
25
38
  std::string read_css_string(const std::string& str, bool css = true);
26
39
  std::string evacuate_escapes(const std::string& str);
27
40
  std::string string_to_output(const std::string& str);
28
- std::string comment_to_string(const std::string& text);
41
+ std::string comment_to_compact_string(const std::string& text);
29
42
  std::string read_hex_escapes(const std::string& str);
30
43
  std::string escape_string(const std::string& str);
31
44
  void newline_to_space(std::string& str);
@@ -39,21 +52,53 @@ namespace Sass {
39
52
 
40
53
  bool peek_linefeed(const char* start);
41
54
 
42
- namespace Util {
55
+ // Returns true iff `elements` ⊆ `container`.
56
+ template <typename C, typename T>
57
+ bool contains_all(C container, T elements) {
58
+ for (const auto &el : elements) {
59
+ if (container.find(el) == container.end()) return false;
60
+ }
61
+ return true;
62
+ }
63
+
64
+ // C++20 `starts_with` equivalent.
65
+ // See https://en.cppreference.com/w/cpp/string/basic_string/starts_with
66
+ inline bool starts_with(const std::string& str, const char* prefix, size_t prefix_len) {
67
+ return str.compare(0, prefix_len, prefix) == 0;
68
+ }
43
69
 
44
- std::string rtrim(const std::string& str);
70
+ inline bool starts_with(const std::string& str, const char* prefix) {
71
+ return starts_with(str, prefix, std::strlen(prefix));
72
+ }
73
+
74
+ // C++20 `ends_with` equivalent.
75
+ // See https://en.cppreference.com/w/cpp/string/basic_string/ends_with
76
+ inline bool ends_with(const std::string& str, const std::string& suffix) {
77
+ return suffix.size() <= str.size() && std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
78
+ }
45
79
 
46
- std::string normalize_underscores(const std::string& str);
47
- std::string normalize_decimals(const std::string& str);
80
+ inline bool ends_with(const std::string& str, const char* suffix, size_t suffix_len) {
81
+ if (suffix_len > str.size()) return false;
82
+ const char* suffix_it = suffix + suffix_len;
83
+ const char* str_it = str.c_str() + str.size();
84
+ while (suffix_it != suffix) if (*(--suffix_it) != *(--str_it)) return false;
85
+ return true;
86
+ }
87
+
88
+ inline bool ends_with(const std::string& str, const char* suffix) {
89
+ return ends_with(str, suffix, std::strlen(suffix));
90
+ }
91
+
92
+ namespace Util {
48
93
 
49
- bool isPrintable(Ruleset_Ptr r, Sass_Output_Style style = NESTED);
50
- bool isPrintable(Supports_Block_Ptr r, Sass_Output_Style style = NESTED);
51
- bool isPrintable(Media_Block_Ptr r, Sass_Output_Style style = NESTED);
52
- bool isPrintable(Comment_Ptr b, Sass_Output_Style style = NESTED);
94
+ bool isPrintable(Ruleset* r, Sass_Output_Style style = NESTED);
95
+ bool isPrintable(Supports_Block* r, Sass_Output_Style style = NESTED);
96
+ bool isPrintable(Media_Block* r, Sass_Output_Style style = NESTED);
97
+ bool isPrintable(Comment* b, Sass_Output_Style style = NESTED);
53
98
  bool isPrintable(Block_Obj b, Sass_Output_Style style = NESTED);
54
- bool isPrintable(String_Constant_Ptr s, Sass_Output_Style style = NESTED);
55
- bool isPrintable(String_Quoted_Ptr s, Sass_Output_Style style = NESTED);
56
- bool isPrintable(Declaration_Ptr d, Sass_Output_Style style = NESTED);
99
+ bool isPrintable(String_Constant* s, Sass_Output_Style style = NESTED);
100
+ bool isPrintable(String_Quoted* s, Sass_Output_Style style = NESTED);
101
+ bool isPrintable(Declaration* d, Sass_Output_Style style = NESTED);
57
102
  bool isAscii(const char chr);
58
103
 
59
104
  }