sassc 2.2.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
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