sassc 2.1.0.pre3 → 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 +24 -0
  4. data/Rakefile +2 -4
  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.hpp +12 -0
  81. data/ext/libsass/src/memory/allocator.cpp +48 -0
  82. data/ext/libsass/src/memory/allocator.hpp +138 -0
  83. data/ext/libsass/src/memory/config.hpp +20 -0
  84. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  85. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  86. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
  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 +11 -13
  132. data/lib/sassc/native.rb +9 -7
  133. data/lib/sassc/script.rb +4 -6
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/functions_test.rb +38 -1
  136. data/test/native_test.rb +4 -4
  137. metadata +31 -18
  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
@@ -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
@@ -1,19 +1,73 @@
1
1
  #ifndef SASS_UTIL_STRING_H
2
2
  #define SASS_UTIL_STRING_H
3
3
 
4
+ #include "sass.hpp"
4
5
  #include <string>
5
6
 
6
7
  namespace Sass {
7
- namespace Util {
8
+ namespace Util {
8
9
 
9
- std::string rtrim(const std::string& str);
10
+ // ##########################################################################
11
+ // Special case insensitive string matcher. We can optimize
12
+ // the more general compare case quite a bit by requiring
13
+ // consumers to obey some rules (lowercase and no space).
14
+ // - `literal` must only contain lower case ascii characters
15
+ // there is one edge case where this could give false positives
16
+ // test could contain a (non-ascii) char exactly 32 below literal
17
+ // ##########################################################################
18
+ bool equalsLiteral(const char* lit, const sass::string& test);
10
19
 
11
- std::string normalize_newlines(const std::string& str);
12
- std::string normalize_underscores(const std::string& str);
13
- std::string normalize_decimals(const std::string& str);
14
- char opening_bracket_for(char closing_bracket);
15
- char closing_bracket_for(char opening_bracket);
20
+ // ###########################################################################
21
+ // Returns [name] without a vendor prefix.
22
+ // If [name] has no vendor prefix, it's returned as-is.
23
+ // ###########################################################################
24
+ sass::string unvendor(const sass::string& name);
16
25
 
17
- } // namespace Sass
26
+ sass::string rtrim(sass::string str);
27
+ sass::string normalize_newlines(const sass::string& str);
28
+ sass::string normalize_underscores(const sass::string& str);
29
+ sass::string normalize_decimals(const sass::string& str);
30
+ char opening_bracket_for(char closing_bracket);
31
+ char closing_bracket_for(char opening_bracket);
32
+
33
+ // Locale-independent ASCII character routines.
34
+
35
+ inline bool ascii_isalpha(unsigned char c) {
36
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
37
+ }
38
+
39
+ inline bool ascii_isdigit(unsigned char c) {
40
+ return (c >= '0' && c <= '9');
41
+ }
42
+
43
+ inline bool ascii_isalnum(unsigned char c) {
44
+ return ascii_isalpha(c) || ascii_isdigit(c);
45
+ }
46
+
47
+ inline bool ascii_isascii(unsigned char c) { return c < 128; }
48
+
49
+ inline bool ascii_isxdigit(unsigned char c) {
50
+ return ascii_isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
51
+ }
52
+
53
+ inline bool ascii_isspace(unsigned char c) {
54
+ return c == ' ' || c == '\t' || c == '\v' || c == '\f' || c == '\r' || c == '\n';
55
+ }
56
+
57
+ inline char ascii_tolower(unsigned char c) {
58
+ if (c >= 'A' && c <= 'Z') return c + 32;
59
+ return c;
60
+ }
61
+
62
+ void ascii_str_tolower(sass::string* s);
63
+
64
+ inline char ascii_toupper(unsigned char c) {
65
+ if (c >= 'a' && c <= 'z') return c - 32;
66
+ return c;
67
+ }
68
+
69
+ void ascii_str_toupper(sass::string* s);
70
+
71
+ } // namespace Sass
18
72
  } // namespace Util
19
73
  #endif // SASS_UTIL_STRING_H
@@ -32,7 +32,7 @@ namespace Sass {
32
32
  const List* l = Cast<List>(val);
33
33
  union Sass_Value* list = sass_make_list(l->size(), l->separator(), l->is_bracketed());
34
34
  for (size_t i = 0, L = l->length(); i < L; ++i) {
35
- Expression_Obj obj = l->at(i);
35
+ ExpressionObj obj = l->at(i);
36
36
  auto val = ast_node_to_sass_value(obj);
37
37
  sass_list_set_value(list, i, val);
38
38
  }
@@ -42,7 +42,7 @@ namespace Sass {
42
42
  {
43
43
  const Map* m = Cast<Map>(val);
44
44
  union Sass_Value* map = sass_make_map(m->length());
45
- size_t i = 0; for (Expression_Obj key : m->keys()) {
45
+ size_t i = 0; for (ExpressionObj key : m->keys()) {
46
46
  sass_map_set_key(map, i, ast_node_to_sass_value(key));
47
47
  sass_map_set_value(map, i, ast_node_to_sass_value(m->at(key)));
48
48
  ++ i;
@@ -78,17 +78,17 @@ namespace Sass {
78
78
  switch (sass_value_get_tag(val)) {
79
79
  case SASS_NUMBER:
80
80
  return SASS_MEMORY_NEW(Number,
81
- ParserState("[C-VALUE]"),
81
+ SourceSpan("[C-VALUE]"),
82
82
  sass_number_get_value(val),
83
83
  sass_number_get_unit(val));
84
84
  case SASS_BOOLEAN:
85
85
  return SASS_MEMORY_NEW(Boolean,
86
- ParserState("[C-VALUE]"),
86
+ SourceSpan("[C-VALUE]"),
87
87
  sass_boolean_get_value(val));
88
88
  case SASS_COLOR:
89
89
  // ToDo: allow to also use HSLA colors!!
90
90
  return SASS_MEMORY_NEW(Color_RGBA,
91
- ParserState("[C-VALUE]"),
91
+ SourceSpan("[C-VALUE]"),
92
92
  sass_color_get_r(val),
93
93
  sass_color_get_g(val),
94
94
  sass_color_get_b(val),
@@ -96,15 +96,15 @@ namespace Sass {
96
96
  case SASS_STRING:
97
97
  if (sass_string_is_quoted(val)) {
98
98
  return SASS_MEMORY_NEW(String_Quoted,
99
- ParserState("[C-VALUE]"),
99
+ SourceSpan("[C-VALUE]"),
100
100
  sass_string_get_value(val));
101
101
  }
102
102
  return SASS_MEMORY_NEW(String_Constant,
103
- ParserState("[C-VALUE]"),
103
+ SourceSpan("[C-VALUE]"),
104
104
  sass_string_get_value(val));
105
105
  case SASS_LIST: {
106
106
  List* l = SASS_MEMORY_NEW(List,
107
- ParserState("[C-VALUE]"),
107
+ SourceSpan("[C-VALUE]"),
108
108
  sass_list_get_length(val),
109
109
  sass_list_get_separator(val));
110
110
  for (size_t i = 0, L = sass_list_get_length(val); i < L; ++i) {
@@ -114,7 +114,7 @@ namespace Sass {
114
114
  return l;
115
115
  }
116
116
  case SASS_MAP: {
117
- Map* m = SASS_MEMORY_NEW(Map, ParserState("[C-VALUE]"));
117
+ Map* m = SASS_MEMORY_NEW(Map, SourceSpan("[C-VALUE]"));
118
118
  for (size_t i = 0, L = sass_map_get_length(val); i < L; ++i) {
119
119
  *m << std::make_pair(
120
120
  sass_value_to_ast_node(sass_map_get_key(val, i)),
@@ -123,14 +123,14 @@ namespace Sass {
123
123
  return m;
124
124
  }
125
125
  case SASS_NULL:
126
- return SASS_MEMORY_NEW(Null, ParserState("[C-VALUE]"));
126
+ return SASS_MEMORY_NEW(Null, SourceSpan("[C-VALUE]"));
127
127
  case SASS_ERROR:
128
128
  return SASS_MEMORY_NEW(Custom_Error,
129
- ParserState("[C-VALUE]"),
129
+ SourceSpan("[C-VALUE]"),
130
130
  sass_error_get_message(val));
131
131
  case SASS_WARNING:
132
132
  return SASS_MEMORY_NEW(Custom_Warning,
133
- ParserState("[C-VALUE]"),
133
+ SourceSpan("[C-VALUE]"),
134
134
  sass_warning_get_message(val));
135
135
  default: break;
136
136
  }
@@ -16,6 +16,7 @@ module SassC
16
16
  def initialize(template, options = {})
17
17
  @template = template
18
18
  @options = options
19
+ @functions = options.fetch(:functions, Script::Functions)
19
20
  end
20
21
 
21
22
  def render
@@ -37,7 +38,7 @@ module SassC
37
38
  Native.option_set_omit_source_map_url(native_options, true) if omit_source_map_url?
38
39
 
39
40
  import_handler.setup(native_options)
40
- functions_handler.setup(native_options)
41
+ functions_handler.setup(native_options, functions: @functions)
41
42
 
42
43
  status = Native.compile_data_context(data_context)
43
44
 
@@ -54,11 +55,12 @@ module SassC
54
55
  @dependencies = Native.context_get_included_files(context)
55
56
  @source_map = Native.context_get_source_map_string(context)
56
57
 
57
- Native.delete_data_context(data_context)
58
-
59
58
  css.force_encoding(@template.encoding)
59
+ @source_map.force_encoding(@template.encoding) if @source_map.is_a?(String)
60
60
 
61
61
  return css unless quiet?
62
+ ensure
63
+ Native.delete_data_context(data_context) if data_context
62
64
  end
63
65
 
64
66
  def dependencies