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
@@ -2,6 +2,7 @@
2
2
  #include "sass.h"
3
3
  #include "ast.hpp"
4
4
  #include "util.hpp"
5
+ #include "util_string.hpp"
5
6
  #include "lexer.hpp"
6
7
  #include "prelexer.hpp"
7
8
  #include "constants.hpp"
@@ -26,8 +27,8 @@ namespace Sass {
26
27
  #endif
27
28
 
28
29
  // https://github.com/sass/sass/commit/4e3e1d5684cc29073a507578fc977434ff488c93
29
- if (fmod(val, 1) - 0.5 > - std::pow(0.1, precision + 1)) return std::ceil(val);
30
- else if (fmod(val, 1) - 0.5 > std::pow(0.1, precision)) return std::floor(val);
30
+ if (std::fmod(val, 1) - 0.5 > - std::pow(0.1, precision + 1)) return std::ceil(val);
31
+ else if (std::fmod(val, 1) - 0.5 > std::pow(0.1, precision)) return std::floor(val);
31
32
  // work around some compiler issue
32
33
  // cygwin has it not defined in std
33
34
  using namespace std;
@@ -75,7 +76,7 @@ namespace Sass {
75
76
  free(arr);
76
77
  }
77
78
 
78
- char **copy_strings(const std::vector<std::string>& strings, char*** array, int skip) {
79
+ char **copy_strings(const sass::vector<sass::string>& strings, char*** array, int skip) {
79
80
  int num = static_cast<int>(strings.size()) - skip;
80
81
  char** arr = (char**) calloc(num + 1, sizeof(char*));
81
82
  if (arr == 0)
@@ -96,10 +97,10 @@ namespace Sass {
96
97
  }
97
98
 
98
99
  // read css string (handle multiline DELIM)
99
- std::string read_css_string(const std::string& str, bool css)
100
+ sass::string read_css_string(const sass::string& str, bool css)
100
101
  {
101
102
  if (!css) return str;
102
- std::string out("");
103
+ sass::string out("");
103
104
  bool esc = false;
104
105
  for (auto i : str) {
105
106
  if (i == '\\') {
@@ -124,9 +125,9 @@ namespace Sass {
124
125
 
125
126
  // double escape all escape sequences
126
127
  // keep unescaped quotes and backslashes
127
- std::string evacuate_escapes(const std::string& str)
128
+ sass::string evacuate_escapes(const sass::string& str)
128
129
  {
129
- std::string out("");
130
+ sass::string out("");
130
131
  bool esc = false;
131
132
  for (auto i : str) {
132
133
  if (i == '\\' && !esc) {
@@ -158,7 +159,7 @@ namespace Sass {
158
159
  }
159
160
 
160
161
  // bell characters are replaced with spaces
161
- void newline_to_space(std::string& str)
162
+ void newline_to_space(sass::string& str)
162
163
  {
163
164
  std::replace(str.begin(), str.end(), '\n', ' ');
164
165
  }
@@ -167,14 +168,14 @@ namespace Sass {
167
168
  // 2. Replaces newlines with spaces.
168
169
  //
169
170
  // This method only considers LF and CRLF as newlines.
170
- std::string string_to_output(const std::string& str)
171
+ sass::string string_to_output(const sass::string& str)
171
172
  {
172
- std::string result;
173
+ sass::string result;
173
174
  result.reserve(str.size());
174
175
  std::size_t pos = 0;
175
176
  while (true) {
176
177
  const std::size_t newline = str.find_first_of("\n\r", pos);
177
- if (newline == std::string::npos) break;
178
+ if (newline == sass::string::npos) break;
178
179
  result.append(str, pos, newline - pos);
179
180
  if (str[newline] == '\r') {
180
181
  if (str[newline + 1] == '\n') {
@@ -190,17 +191,17 @@ namespace Sass {
190
191
  }
191
192
  result += ' ';
192
193
  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
+ if (non_space != sass::string::npos) {
194
195
  pos = non_space;
195
196
  }
196
197
  }
197
- result.append(str, pos, std::string::npos);
198
+ result.append(str, pos, sass::string::npos);
198
199
  return result;
199
200
  }
200
201
 
201
- std::string escape_string(const std::string& str)
202
+ sass::string escape_string(const sass::string& str)
202
203
  {
203
- std::string out;
204
+ sass::string out;
204
205
  out.reserve(str.size());
205
206
  for (char c : str) {
206
207
  switch (c) {
@@ -220,9 +221,9 @@ namespace Sass {
220
221
  return out;
221
222
  }
222
223
 
223
- std::string comment_to_compact_string(const std::string& text)
224
+ sass::string comment_to_compact_string(const sass::string& text)
224
225
  {
225
- std::string str = "";
226
+ sass::string str = "";
226
227
  size_t has = 0;
227
228
  char prev = 0;
228
229
  bool clean = false;
@@ -269,10 +270,10 @@ namespace Sass {
269
270
  return quote_mark;
270
271
  }
271
272
 
272
- std::string read_hex_escapes(const std::string& s)
273
+ sass::string read_hex_escapes(const sass::string& s)
273
274
  {
274
275
 
275
- std::string result;
276
+ sass::string result;
276
277
  bool skipped = false;
277
278
 
278
279
  for (size_t i = 0, L = s.length(); i < L; ++i) {
@@ -289,7 +290,7 @@ namespace Sass {
289
290
 
290
291
  // parse as many sequence chars as possible
291
292
  // ToDo: Check if ruby aborts after possible max
292
- while (i + len < L && s[i + len] && isxdigit(s[i + len])) ++ len;
293
+ while (i + len < L && s[i + len] && Util::ascii_isxdigit(static_cast<unsigned char>(s[i + len]))) ++ len;
293
294
 
294
295
  if (len > 1) {
295
296
 
@@ -338,7 +339,7 @@ namespace Sass {
338
339
 
339
340
  }
340
341
 
341
- std::string unquote(const std::string& s, char* qd, bool keep_utf8_sequences, bool strict)
342
+ sass::string unquote(const sass::string& s, char* qd, bool keep_utf8_sequences, bool strict)
342
343
  {
343
344
 
344
345
  // not enough room for quotes
@@ -354,7 +355,7 @@ namespace Sass {
354
355
  else if (*s.begin() == '\'' && *s.rbegin() == '\'') q = '\'';
355
356
  else return s;
356
357
 
357
- std::string unq;
358
+ sass::string unq;
358
359
  unq.reserve(s.length()-2);
359
360
 
360
361
  for (size_t i = 1, L = s.length() - 1; i < L; ++i) {
@@ -375,7 +376,7 @@ namespace Sass {
375
376
 
376
377
  // parse as many sequence chars as possible
377
378
  // ToDo: Check if ruby aborts after possible max
378
- while (i + len < L && s[i + len] && isxdigit(s[i + len])) ++ len;
379
+ while (i + len < L && s[i + len] && Util::ascii_isxdigit(static_cast<unsigned char>(s[i + len]))) ++ len;
379
380
 
380
381
  // hex string?
381
382
  if (keep_utf8_sequences) {
@@ -413,7 +414,7 @@ namespace Sass {
413
414
  // // don't be that strict
414
415
  // return s;
415
416
  // // this basically always means an internal error and not users fault
416
- // error("Unescaped delimiter in string to unquote found. [" + s + "]", ParserState("[UNQUOTE]"));
417
+ // error("Unescaped delimiter in string to unquote found. [" + s + "]", SourceSpan("[UNQUOTE]"));
417
418
  // }
418
419
  else {
419
420
  if (strict && !skipped) {
@@ -430,16 +431,16 @@ namespace Sass {
430
431
 
431
432
  }
432
433
 
433
- std::string quote(const std::string& s, char q)
434
+ sass::string quote(const sass::string& s, char q)
434
435
  {
435
436
 
436
437
  // autodetect with fallback to given quote
437
438
  q = detect_best_quotemark(s.c_str(), q);
438
439
 
439
440
  // return an empty quoted string
440
- if (s.empty()) return std::string(2, q ? q : '"');
441
+ if (s.empty()) return sass::string(2, q ? q : '"');
441
442
 
442
- std::string quoted;
443
+ sass::string quoted;
443
444
  quoted.reserve(s.length()+2);
444
445
  quoted.push_back(q);
445
446
 
@@ -528,14 +529,14 @@ namespace Sass {
528
529
 
529
530
  namespace Util {
530
531
 
531
- bool isPrintable(Ruleset* r, Sass_Output_Style style) {
532
+ bool isPrintable(StyleRule* r, Sass_Output_Style style) {
532
533
  if (r == NULL) {
533
534
  return false;
534
535
  }
535
536
 
536
537
  Block_Obj b = r->block();
537
538
 
538
- Selector_List* sl = Cast<Selector_List>(r->selector());
539
+ SelectorList* sl = r->selector();
539
540
  bool hasSelectors = sl ? sl->length() > 0 : false;
540
541
 
541
542
  if (!hasSelectors) {
@@ -546,11 +547,11 @@ namespace Sass {
546
547
  bool hasPrintableChildBlocks = false;
547
548
  for (size_t i = 0, L = b->length(); i < L; ++i) {
548
549
  Statement_Obj stm = b->at(i);
549
- if (Cast<Directive>(stm)) {
550
+ if (Cast<AtRule>(stm)) {
550
551
  return true;
551
552
  } else if (Declaration* d = Cast<Declaration>(stm)) {
552
553
  return isPrintable(d, style);
553
- } else if (Has_Block* p = Cast<Has_Block>(stm)) {
554
+ } else if (ParentStatement* p = Cast<ParentStatement>(stm)) {
554
555
  Block_Obj pChildBlock = p->block();
555
556
  if (isPrintable(pChildBlock, style)) {
556
557
  hasPrintableChildBlocks = true;
@@ -588,13 +589,13 @@ namespace Sass {
588
589
 
589
590
  bool isPrintable(Declaration* d, Sass_Output_Style style)
590
591
  {
591
- Expression_Obj val = d->value();
592
+ ExpressionObj val = d->value();
592
593
  if (String_Quoted_Obj sq = Cast<String_Quoted>(val)) return isPrintable(sq.ptr(), style);
593
594
  if (String_Constant_Obj sc = Cast<String_Constant>(val)) return isPrintable(sc.ptr(), style);
594
595
  return true;
595
596
  }
596
597
 
597
- bool isPrintable(Supports_Block* f, Sass_Output_Style style) {
598
+ bool isPrintable(SupportsRule* f, Sass_Output_Style style) {
598
599
  if (f == NULL) {
599
600
  return false;
600
601
  }
@@ -605,10 +606,10 @@ namespace Sass {
605
606
  bool hasPrintableChildBlocks = false;
606
607
  for (size_t i = 0, L = b->length(); i < L; ++i) {
607
608
  Statement_Obj stm = b->at(i);
608
- if (Cast<Declaration>(stm) || Cast<Directive>(stm)) {
609
+ if (Cast<Declaration>(stm) || Cast<AtRule>(stm)) {
609
610
  hasDeclarations = true;
610
611
  }
611
- else if (Has_Block* b = Cast<Has_Block>(stm)) {
612
+ else if (ParentStatement* b = Cast<ParentStatement>(stm)) {
612
613
  Block_Obj pChildBlock = b->block();
613
614
  if (!b->is_invisible()) {
614
615
  if (isPrintable(pChildBlock, style)) {
@@ -625,36 +626,37 @@ namespace Sass {
625
626
  return false;
626
627
  }
627
628
 
628
- bool isPrintable(Media_Block* m, Sass_Output_Style style)
629
+ bool isPrintable(CssMediaRule* m, Sass_Output_Style style)
629
630
  {
630
631
  if (m == nullptr) return false;
631
632
  Block_Obj b = m->block();
632
633
  if (b == nullptr) return false;
634
+ if (m->empty()) return false;
633
635
  for (size_t i = 0, L = b->length(); i < L; ++i) {
634
636
  Statement_Obj stm = b->at(i);
635
- if (Cast<Directive>(stm)) return true;
637
+ if (Cast<AtRule>(stm)) return true;
636
638
  else if (Cast<Declaration>(stm)) return true;
637
639
  else if (Comment* c = Cast<Comment>(stm)) {
638
640
  if (isPrintable(c, style)) {
639
641
  return true;
640
642
  }
641
643
  }
642
- else if (Ruleset* r = Cast<Ruleset>(stm)) {
644
+ else if (StyleRule* r = Cast<StyleRule>(stm)) {
643
645
  if (isPrintable(r, style)) {
644
646
  return true;
645
647
  }
646
648
  }
647
- else if (Supports_Block* f = Cast<Supports_Block>(stm)) {
649
+ else if (SupportsRule* f = Cast<SupportsRule>(stm)) {
648
650
  if (isPrintable(f, style)) {
649
651
  return true;
650
652
  }
651
653
  }
652
- else if (Media_Block* mb = Cast<Media_Block>(stm)) {
654
+ else if (CssMediaRule* mb = Cast<CssMediaRule>(stm)) {
653
655
  if (isPrintable(mb, style)) {
654
656
  return true;
655
657
  }
656
658
  }
657
- else if (Has_Block* b = Cast<Has_Block>(stm)) {
659
+ else if (ParentStatement* b = Cast<ParentStatement>(stm)) {
658
660
  if (isPrintable(b->block(), style)) {
659
661
  return true;
660
662
  }
@@ -684,7 +686,7 @@ namespace Sass {
684
686
 
685
687
  for (size_t i = 0, L = b->length(); i < L; ++i) {
686
688
  Statement_Obj stm = b->at(i);
687
- if (Cast<Declaration>(stm) || Cast<Directive>(stm)) {
689
+ if (Cast<Declaration>(stm) || Cast<AtRule>(stm)) {
688
690
  return true;
689
691
  }
690
692
  else if (Comment* c = Cast<Comment>(stm)) {
@@ -692,22 +694,22 @@ namespace Sass {
692
694
  return true;
693
695
  }
694
696
  }
695
- else if (Ruleset* r = Cast<Ruleset>(stm)) {
697
+ else if (StyleRule* r = Cast<StyleRule>(stm)) {
696
698
  if (isPrintable(r, style)) {
697
699
  return true;
698
700
  }
699
701
  }
700
- else if (Supports_Block* f = Cast<Supports_Block>(stm)) {
702
+ else if (SupportsRule* f = Cast<SupportsRule>(stm)) {
701
703
  if (isPrintable(f, style)) {
702
704
  return true;
703
705
  }
704
706
  }
705
- else if (Media_Block* m = Cast<Media_Block>(stm)) {
707
+ else if (CssMediaRule * m = Cast<CssMediaRule>(stm)) {
706
708
  if (isPrintable(m, style)) {
707
709
  return true;
708
710
  }
709
711
  }
710
- else if (Has_Block* b = Cast<Has_Block>(stm)) {
712
+ else if (ParentStatement* b = Cast<ParentStatement>(stm)) {
711
713
  if (isPrintable(b->block(), style)) {
712
714
  return true;
713
715
  }
@@ -717,9 +719,5 @@ namespace Sass {
717
719
  return false;
718
720
  }
719
721
 
720
- bool isAscii(const char chr) {
721
- return unsigned(chr) < 128;
722
- }
723
-
724
722
  }
725
723
  }
@@ -8,11 +8,11 @@
8
8
  #include "sass/base.h"
9
9
  #include "ast_fwd_decl.hpp"
10
10
 
11
+ #include <cmath>
11
12
  #include <cstring>
12
13
  #include <vector>
13
14
  #include <string>
14
15
  #include <assert.h>
15
- #include <math.h>
16
16
 
17
17
  #define SASS_ASSERT(cond, msg) assert(cond && msg)
18
18
 
@@ -34,17 +34,17 @@ namespace Sass {
34
34
  double sass_strtod(const char* str);
35
35
  const char* safe_str(const char *, const char* = "");
36
36
  void free_string_array(char **);
37
- char **copy_strings(const std::vector<std::string>&, char ***, int = 0);
38
- std::string read_css_string(const std::string& str, bool css = true);
39
- std::string evacuate_escapes(const std::string& str);
40
- std::string string_to_output(const std::string& str);
41
- std::string comment_to_compact_string(const std::string& text);
42
- std::string read_hex_escapes(const std::string& str);
43
- std::string escape_string(const std::string& str);
44
- void newline_to_space(std::string& str);
45
-
46
- std::string quote(const std::string&, char q = 0);
47
- std::string unquote(const std::string&, char* q = 0, bool keep_utf8_sequences = false, bool strict = true);
37
+ char **copy_strings(const sass::vector<sass::string>&, char ***, int = 0);
38
+ sass::string read_css_string(const sass::string& str, bool css = true);
39
+ sass::string evacuate_escapes(const sass::string& str);
40
+ sass::string string_to_output(const sass::string& str);
41
+ sass::string comment_to_compact_string(const sass::string& text);
42
+ sass::string read_hex_escapes(const sass::string& str);
43
+ sass::string escape_string(const sass::string& str);
44
+ void newline_to_space(sass::string& str);
45
+
46
+ sass::string quote(const sass::string&, char q = 0);
47
+ sass::string unquote(const sass::string&, char* q = 0, bool keep_utf8_sequences = false, bool strict = true);
48
48
  char detect_best_quotemark(const char* s, char qm = '"');
49
49
 
50
50
  bool is_hex_doublet(double n);
@@ -63,21 +63,21 @@ namespace Sass {
63
63
 
64
64
  // C++20 `starts_with` equivalent.
65
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) {
66
+ inline bool starts_with(const sass::string& str, const char* prefix, size_t prefix_len) {
67
67
  return str.compare(0, prefix_len, prefix) == 0;
68
68
  }
69
69
 
70
- inline bool starts_with(const std::string& str, const char* prefix) {
70
+ inline bool starts_with(const sass::string& str, const char* prefix) {
71
71
  return starts_with(str, prefix, std::strlen(prefix));
72
72
  }
73
73
 
74
74
  // C++20 `ends_with` equivalent.
75
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) {
76
+ inline bool ends_with(const sass::string& str, const sass::string& suffix) {
77
77
  return suffix.size() <= str.size() && std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
78
78
  }
79
79
 
80
- inline bool ends_with(const std::string& str, const char* suffix, size_t suffix_len) {
80
+ inline bool ends_with(const sass::string& str, const char* suffix, size_t suffix_len) {
81
81
  if (suffix_len > str.size()) return false;
82
82
  const char* suffix_it = suffix + suffix_len;
83
83
  const char* str_it = str.c_str() + str.size();
@@ -85,21 +85,20 @@ namespace Sass {
85
85
  return true;
86
86
  }
87
87
 
88
- inline bool ends_with(const std::string& str, const char* suffix) {
88
+ inline bool ends_with(const sass::string& str, const char* suffix) {
89
89
  return ends_with(str, suffix, std::strlen(suffix));
90
90
  }
91
91
 
92
92
  namespace Util {
93
93
 
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);
94
+ bool isPrintable(StyleRule* r, Sass_Output_Style style = NESTED);
95
+ bool isPrintable(SupportsRule* r, Sass_Output_Style style = NESTED);
96
+ bool isPrintable(CssMediaRule* r, Sass_Output_Style style = NESTED);
97
97
  bool isPrintable(Comment* b, Sass_Output_Style style = NESTED);
98
98
  bool isPrintable(Block_Obj b, Sass_Output_Style style = NESTED);
99
99
  bool isPrintable(String_Constant* s, Sass_Output_Style style = NESTED);
100
100
  bool isPrintable(String_Quoted* s, Sass_Output_Style style = NESTED);
101
101
  bool isPrintable(Declaration* d, Sass_Output_Style style = NESTED);
102
- bool isAscii(const char chr);
103
102
 
104
103
  }
105
104
  }
@@ -1,75 +1,125 @@
1
1
  #include "util_string.hpp"
2
2
 
3
+ #include <iostream>
3
4
  #include <algorithm>
4
5
 
5
6
  namespace Sass {
6
- namespace Util {
7
+ namespace Util {
7
8
 
8
- std::string rtrim(const std::string &str) {
9
- std::string trimmed = str;
10
- size_t pos_ws = trimmed.find_last_not_of(" \t\n\v\f\r");
11
- if (pos_ws != std::string::npos) {
12
- trimmed.erase(pos_ws + 1);
13
- } else {
14
- trimmed.clear();
15
- }
16
- return trimmed;
17
- }
9
+ // ##########################################################################
10
+ // Special case insensitive string matcher. We can optimize
11
+ // the more general compare case quite a bit by requiring
12
+ // consumers to obey some rules (lowercase and no space).
13
+ // - `literal` must only contain lower case ascii characters
14
+ // there is one edge case where this could give false positives
15
+ // test could contain a (non-ascii) char exactly 32 below literal
16
+ // ##########################################################################
17
+ bool equalsLiteral(const char* lit, const sass::string& test) {
18
+ // Work directly on characters
19
+ const char* src = test.c_str();
20
+ // There is a small chance that the search string
21
+ // Is longer than the rest of the string to look at
22
+ while (*lit && (*src == *lit || *src + 32 == *lit)) {
23
+ ++src, ++lit;
24
+ }
25
+ // True if literal is at end
26
+ // If not test was too long
27
+ return *lit == 0;
28
+ }
18
29
 
19
- std::string normalize_newlines(const std::string& str) {
20
- std::string result;
21
- result.reserve(str.size());
22
- std::size_t pos = 0;
23
- while (true) {
24
- const std::size_t newline = str.find_first_of("\n\f\r", pos);
25
- if (newline == std::string::npos) break;
26
- result.append(str, pos, newline - pos);
27
- result += '\n';
28
- if (str[newline] == '\r' && str[newline + 1] == '\n') {
29
- pos = newline + 2;
30
- } else {
31
- pos = newline + 1;
30
+ void ascii_str_tolower(sass::string* s) {
31
+ for (auto& ch : *s) {
32
+ ch = ascii_tolower(static_cast<unsigned char>(ch));
33
+ }
32
34
  }
33
- }
34
- result.append(str, pos, std::string::npos);
35
- return result;
36
- }
37
35
 
38
- std::string normalize_underscores(const std::string& str) {
39
- std::string normalized = str;
40
- std::replace(normalized.begin(), normalized.end(), '_', '-');
41
- return normalized;
42
- }
36
+ void ascii_str_toupper(sass::string* s) {
37
+ for (auto& ch : *s) {
38
+ ch = ascii_toupper(static_cast<unsigned char>(ch));
39
+ }
40
+ }
43
41
 
44
- std::string normalize_decimals(const std::string& str) {
45
- std::string normalized;
46
- if (!str.empty() && str[0] == '.') {
47
- normalized.reserve(str.size() + 1);
48
- normalized += '0';
49
- normalized += str;
50
- } else {
51
- normalized = str;
52
- }
53
- return normalized;
54
- }
42
+ sass::string rtrim(sass::string str) {
43
+ auto it = std::find_if_not(str.rbegin(), str.rend(), ascii_isspace);
44
+ str.erase(str.rend() - it);
45
+ return str;
46
+ }
55
47
 
56
- char opening_bracket_for(char closing_bracket) {
57
- switch (closing_bracket) {
58
- case ')': return '(';
59
- case ']': return '[';
60
- case '}': return '{';
61
- default: return '\0';
62
- }
63
- }
48
+ // ###########################################################################
49
+ // Returns [name] without a vendor prefix.
50
+ // If [name] has no vendor prefix, it's returned as-is.
51
+ // ###########################################################################
52
+ sass::string unvendor(const sass::string& name)
53
+ {
54
+ if (name.size() < 2) return name;
55
+ if (name[0] != '-') return name;
56
+ if (name[1] == '-') return name;
57
+ for (size_t i = 2; i < name.size(); i++) {
58
+ if (name[i] == '-') return name.substr(i + 1);
59
+ }
60
+ return name;
61
+ }
62
+ // EO unvendor
63
+
64
+ sass::string normalize_newlines(const sass::string& str) {
65
+ sass::string result;
66
+ result.reserve(str.size());
67
+ std::size_t pos = 0;
68
+ while (true) {
69
+ const std::size_t newline = str.find_first_of("\n\f\r", pos);
70
+ if (newline == sass::string::npos) break;
71
+ result.append(str, pos, newline - pos);
72
+ result += '\n';
73
+ if (str[newline] == '\r' && str[newline + 1] == '\n') {
74
+ pos = newline + 2;
75
+ }
76
+ else {
77
+ pos = newline + 1;
78
+ }
79
+ }
80
+ result.append(str, pos, sass::string::npos);
81
+ return result;
82
+ }
83
+
84
+ sass::string normalize_underscores(const sass::string& str) {
85
+ sass::string normalized = str;
86
+ std::replace(normalized.begin(), normalized.end(), '_', '-');
87
+ return normalized;
88
+ }
89
+
90
+ sass::string normalize_decimals(const sass::string& str) {
91
+ sass::string normalized;
92
+ if (!str.empty() && str[0] == '.') {
93
+ normalized.reserve(str.size() + 1);
94
+ normalized += '0';
95
+ normalized += str;
96
+ }
97
+ else {
98
+ normalized = str;
99
+ }
100
+ return normalized;
101
+ }
102
+
103
+ char opening_bracket_for(char closing_bracket) {
104
+ switch (closing_bracket) {
105
+ case ')': return '(';
106
+ case ']': return '[';
107
+ case '}': return '{';
108
+ default: return '\0';
109
+ }
110
+ }
111
+
112
+ char closing_bracket_for(char opening_bracket) {
113
+ switch (opening_bracket) {
114
+ case '(': return ')';
115
+ case '[': return ']';
116
+ case '{': return '}';
117
+ default: return '\0';
118
+ }
119
+ }
64
120
 
65
- char closing_bracket_for(char opening_bracket) {
66
- switch (opening_bracket) {
67
- case '(': return ')';
68
- case '[': return ']';
69
- case '{': return '}';
70
- default: return '\0';
71
121
  }
72
- }
122
+ // namespace Util
73
123
 
74
- } // namespace Sass
75
- } // namespace Util
124
+ }
125
+ // namespace Sass