sassc 2.0.1 → 2.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,30 @@
1
+ #ifndef SASS_FN_MAPS_H
2
+ #define SASS_FN_MAPS_H
3
+
4
+ #include "fn_utils.hpp"
5
+
6
+ namespace Sass {
7
+
8
+ namespace Functions {
9
+
10
+ #define ARGM(argname, argtype) get_arg_m(argname, env, sig, pstate, traces)
11
+
12
+ extern Signature map_get_sig;
13
+ extern Signature map_merge_sig;
14
+ extern Signature map_remove_sig;
15
+ extern Signature map_keys_sig;
16
+ extern Signature map_values_sig;
17
+ extern Signature map_has_key_sig;
18
+
19
+ BUILT_IN(map_get);
20
+ BUILT_IN(map_merge);
21
+ BUILT_IN(map_remove);
22
+ BUILT_IN(map_keys);
23
+ BUILT_IN(map_values);
24
+ BUILT_IN(map_has_key);
25
+
26
+ }
27
+
28
+ }
29
+
30
+ #endif
@@ -0,0 +1,256 @@
1
+ #include "ast.hpp"
2
+ #include "expand.hpp"
3
+ #include "fn_utils.hpp"
4
+ #include "fn_miscs.hpp"
5
+ #include "util_string.hpp"
6
+
7
+ namespace Sass {
8
+
9
+ namespace Functions {
10
+
11
+ // features
12
+ static std::set<std::string> features {
13
+ "global-variable-shadowing",
14
+ "extend-selector-pseudoclass",
15
+ "at-error",
16
+ "units-level-3",
17
+ "custom-property"
18
+ };
19
+
20
+ //////////////////////////
21
+ // INTROSPECTION FUNCTIONS
22
+ //////////////////////////
23
+
24
+ Signature type_of_sig = "type-of($value)";
25
+ BUILT_IN(type_of)
26
+ {
27
+ Expression* v = ARG("$value", Expression);
28
+ return SASS_MEMORY_NEW(String_Quoted, pstate, v->type());
29
+ }
30
+
31
+ Signature variable_exists_sig = "variable-exists($name)";
32
+ BUILT_IN(variable_exists)
33
+ {
34
+ std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
35
+
36
+ if(d_env.has("$"+s)) {
37
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
38
+ }
39
+ else {
40
+ return SASS_MEMORY_NEW(Boolean, pstate, false);
41
+ }
42
+ }
43
+
44
+ Signature global_variable_exists_sig = "global-variable-exists($name)";
45
+ BUILT_IN(global_variable_exists)
46
+ {
47
+ std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
48
+
49
+ if(d_env.has_global("$"+s)) {
50
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
51
+ }
52
+ else {
53
+ return SASS_MEMORY_NEW(Boolean, pstate, false);
54
+ }
55
+ }
56
+
57
+ Signature function_exists_sig = "function-exists($name)";
58
+ BUILT_IN(function_exists)
59
+ {
60
+ String_Constant* ss = Cast<String_Constant>(env["$name"]);
61
+ if (!ss) {
62
+ error("$name: " + (env["$name"]->to_string()) + " is not a string for `function-exists'", pstate, traces);
63
+ }
64
+
65
+ std::string name = Util::normalize_underscores(unquote(ss->value()));
66
+
67
+ if(d_env.has(name+"[f]")) {
68
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
69
+ }
70
+ else {
71
+ return SASS_MEMORY_NEW(Boolean, pstate, false);
72
+ }
73
+ }
74
+
75
+ Signature mixin_exists_sig = "mixin-exists($name)";
76
+ BUILT_IN(mixin_exists)
77
+ {
78
+ std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
79
+
80
+ if(d_env.has(s+"[m]")) {
81
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
82
+ }
83
+ else {
84
+ return SASS_MEMORY_NEW(Boolean, pstate, false);
85
+ }
86
+ }
87
+
88
+ Signature feature_exists_sig = "feature-exists($name)";
89
+ BUILT_IN(feature_exists)
90
+ {
91
+ std::string s = unquote(ARG("$name", String_Constant)->value());
92
+
93
+ if(features.find(s) == features.end()) {
94
+ return SASS_MEMORY_NEW(Boolean, pstate, false);
95
+ }
96
+ else {
97
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
98
+ }
99
+ }
100
+
101
+ Signature call_sig = "call($name, $args...)";
102
+ BUILT_IN(call)
103
+ {
104
+ std::string name;
105
+ Function* ff = Cast<Function>(env["$name"]);
106
+ String_Constant* ss = Cast<String_Constant>(env["$name"]);
107
+
108
+ if (ss) {
109
+ name = Util::normalize_underscores(unquote(ss->value()));
110
+ std::cerr << "DEPRECATION WARNING: ";
111
+ std::cerr << "Passing a string to call() is deprecated and will be illegal" << std::endl;
112
+ std::cerr << "in Sass 4.0. Use call(get-function(" + quote(name) + ")) instead." << std::endl;
113
+ std::cerr << std::endl;
114
+ } else if (ff) {
115
+ name = ff->name();
116
+ }
117
+
118
+ List_Obj arglist = SASS_MEMORY_COPY(ARG("$args", List));
119
+
120
+ Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
121
+ // std::string full_name(name + "[f]");
122
+ // Definition* def = d_env.has(full_name) ? Cast<Definition>((d_env)[full_name]) : 0;
123
+ // Parameters* params = def ? def->parameters() : 0;
124
+ // size_t param_size = params ? params->length() : 0;
125
+ for (size_t i = 0, L = arglist->length(); i < L; ++i) {
126
+ Expression_Obj expr = arglist->value_at_index(i);
127
+ // if (params && params->has_rest_parameter()) {
128
+ // Parameter_Obj p = param_size > i ? (*params)[i] : 0;
129
+ // List* list = Cast<List>(expr);
130
+ // if (list && p && !p->is_rest_parameter()) expr = (*list)[0];
131
+ // }
132
+ if (arglist->is_arglist()) {
133
+ Expression_Obj obj = arglist->at(i);
134
+ Argument_Obj arg = (Argument*) obj.ptr(); // XXX
135
+ args->append(SASS_MEMORY_NEW(Argument,
136
+ pstate,
137
+ expr,
138
+ arg ? arg->name() : "",
139
+ arg ? arg->is_rest_argument() : false,
140
+ arg ? arg->is_keyword_argument() : false));
141
+ } else {
142
+ args->append(SASS_MEMORY_NEW(Argument, pstate, expr));
143
+ }
144
+ }
145
+ Function_Call_Obj func = SASS_MEMORY_NEW(Function_Call, pstate, name, args);
146
+ Expand expand(ctx, &d_env, &selector_stack);
147
+ func->via_call(true); // calc invoke is allowed
148
+ if (ff) func->func(ff);
149
+ return Cast<PreValue>(func->perform(&expand.eval));
150
+ }
151
+
152
+ ////////////////////
153
+ // BOOLEAN FUNCTIONS
154
+ ////////////////////
155
+
156
+ Signature not_sig = "not($value)";
157
+ BUILT_IN(sass_not)
158
+ {
159
+ return SASS_MEMORY_NEW(Boolean, pstate, ARG("$value", Expression)->is_false());
160
+ }
161
+
162
+ Signature if_sig = "if($condition, $if-true, $if-false)";
163
+ // BUILT_IN(sass_if)
164
+ // { return ARG("$condition", Expression)->is_false() ? ARG("$if-false", Expression) : ARG("$if-true", Expression); }
165
+ BUILT_IN(sass_if)
166
+ {
167
+ Expand expand(ctx, &d_env, &selector_stack);
168
+ Expression_Obj cond = ARG("$condition", Expression)->perform(&expand.eval);
169
+ bool is_true = !cond->is_false();
170
+ Expression_Obj res = ARG(is_true ? "$if-true" : "$if-false", Expression);
171
+ Value_Obj qwe = Cast<Value>(res->perform(&expand.eval));
172
+ // res = res->perform(&expand.eval.val_eval);
173
+ qwe->set_delayed(false); // clone?
174
+ return qwe.detach();
175
+ }
176
+
177
+ //////////////////////////
178
+ // MISCELLANEOUS FUNCTIONS
179
+ //////////////////////////
180
+
181
+ // value.check_deprecated_interp if value.is_a?(Sass::Script::Value::String)
182
+ // unquoted_string(value.to_sass)
183
+
184
+ Signature inspect_sig = "inspect($value)";
185
+ BUILT_IN(inspect)
186
+ {
187
+ Expression* v = ARG("$value", Expression);
188
+ if (v->concrete_type() == Expression::NULL_VAL) {
189
+ return SASS_MEMORY_NEW(String_Constant, pstate, "null");
190
+ } else if (v->concrete_type() == Expression::BOOLEAN && v->is_false()) {
191
+ return SASS_MEMORY_NEW(String_Constant, pstate, "false");
192
+ } else if (v->concrete_type() == Expression::STRING) {
193
+ String_Constant *s = Cast<String_Constant>(v);
194
+ if (s->quote_mark()) {
195
+ return SASS_MEMORY_NEW(String_Constant, pstate, quote(s->value(), s->quote_mark()));
196
+ } else {
197
+ return s;
198
+ }
199
+ } else {
200
+ // ToDo: fix to_sass for nested parentheses
201
+ Sass_Output_Style old_style;
202
+ old_style = ctx.c_options.output_style;
203
+ ctx.c_options.output_style = TO_SASS;
204
+ Emitter emitter(ctx.c_options);
205
+ Inspect i(emitter);
206
+ i.in_declaration = false;
207
+ v->perform(&i);
208
+ ctx.c_options.output_style = old_style;
209
+ return SASS_MEMORY_NEW(String_Quoted, pstate, i.get_buffer());
210
+ }
211
+ // return v;
212
+ }
213
+
214
+ Signature content_exists_sig = "content-exists()";
215
+ BUILT_IN(content_exists)
216
+ {
217
+ if (!d_env.has_global("is_in_mixin")) {
218
+ error("Cannot call content-exists() except within a mixin.", pstate, traces);
219
+ }
220
+ return SASS_MEMORY_NEW(Boolean, pstate, d_env.has_lexical("@content[m]"));
221
+ }
222
+
223
+ Signature get_function_sig = "get-function($name, $css: false)";
224
+ BUILT_IN(get_function)
225
+ {
226
+ String_Constant* ss = Cast<String_Constant>(env["$name"]);
227
+ if (!ss) {
228
+ error("$name: " + (env["$name"]->to_string()) + " is not a string for `get-function'", pstate, traces);
229
+ }
230
+
231
+ std::string name = Util::normalize_underscores(unquote(ss->value()));
232
+ std::string full_name = name + "[f]";
233
+
234
+ Boolean_Obj css = ARG("$css", Boolean);
235
+ if (!css->is_false()) {
236
+ Definition* def = SASS_MEMORY_NEW(Definition,
237
+ pstate,
238
+ name,
239
+ SASS_MEMORY_NEW(Parameters, pstate),
240
+ SASS_MEMORY_NEW(Block, pstate, 0, false),
241
+ Definition::FUNCTION);
242
+ return SASS_MEMORY_NEW(Function, pstate, def, true);
243
+ }
244
+
245
+
246
+ if (!d_env.has_global(full_name)) {
247
+ error("Function not found: " + name, pstate, traces);
248
+ }
249
+
250
+ Definition* def = Cast<Definition>(d_env[full_name]);
251
+ return SASS_MEMORY_NEW(Function, pstate, def, false);
252
+ }
253
+
254
+ }
255
+
256
+ }
@@ -0,0 +1,40 @@
1
+ #ifndef SASS_FN_MISCS_H
2
+ #define SASS_FN_MISCS_H
3
+
4
+ #include "fn_utils.hpp"
5
+
6
+ namespace Sass {
7
+
8
+ namespace Functions {
9
+
10
+ extern Signature type_of_sig;
11
+ extern Signature variable_exists_sig;
12
+ extern Signature global_variable_exists_sig;
13
+ extern Signature function_exists_sig;
14
+ extern Signature mixin_exists_sig;
15
+ extern Signature feature_exists_sig;
16
+ extern Signature call_sig;
17
+ extern Signature not_sig;
18
+ extern Signature if_sig;
19
+ extern Signature set_nth_sig;
20
+ extern Signature content_exists_sig;
21
+ extern Signature get_function_sig;
22
+
23
+ BUILT_IN(type_of);
24
+ BUILT_IN(variable_exists);
25
+ BUILT_IN(global_variable_exists);
26
+ BUILT_IN(function_exists);
27
+ BUILT_IN(mixin_exists);
28
+ BUILT_IN(feature_exists);
29
+ BUILT_IN(call);
30
+ BUILT_IN(sass_not);
31
+ BUILT_IN(sass_if);
32
+ BUILT_IN(set_nth);
33
+ BUILT_IN(content_exists);
34
+ BUILT_IN(get_function);
35
+
36
+ }
37
+
38
+ }
39
+
40
+ #endif
@@ -0,0 +1,220 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include <cstdint>
6
+ #include <cstdlib>
7
+ #include <cmath>
8
+ #include <cctype>
9
+ #include <random>
10
+ #include <sstream>
11
+ #include <iomanip>
12
+ #include <algorithm>
13
+
14
+ #include "ast.hpp"
15
+ #include "units.hpp"
16
+ #include "fn_utils.hpp"
17
+ #include "fn_numbers.hpp"
18
+
19
+ #ifdef __MINGW32__
20
+ #include "windows.h"
21
+ #include "wincrypt.h"
22
+ #endif
23
+
24
+ namespace Sass {
25
+
26
+ namespace Functions {
27
+
28
+ #ifdef __MINGW32__
29
+ uint64_t GetSeed()
30
+ {
31
+ HCRYPTPROV hp = 0;
32
+ BYTE rb[8];
33
+ CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
34
+ CryptGenRandom(hp, sizeof(rb), rb);
35
+ CryptReleaseContext(hp, 0);
36
+
37
+ uint64_t seed;
38
+ memcpy(&seed, &rb[0], sizeof(seed));
39
+
40
+ return seed;
41
+ }
42
+ #else
43
+ uint64_t GetSeed()
44
+ {
45
+ std::random_device rd;
46
+ return rd();
47
+ }
48
+ #endif
49
+
50
+ // note: the performance of many implementations of
51
+ // random_device degrades sharply once the entropy pool
52
+ // is exhausted. For practical use, random_device is
53
+ // generally only used to seed a PRNG such as mt19937.
54
+ static std::mt19937 rand(static_cast<unsigned int>(GetSeed()));
55
+
56
+ ///////////////////
57
+ // NUMBER FUNCTIONS
58
+ ///////////////////
59
+
60
+ Signature percentage_sig = "percentage($number)";
61
+ BUILT_IN(percentage)
62
+ {
63
+ Number_Obj n = ARGN("$number");
64
+ if (!n->is_unitless()) error("argument $number of `" + std::string(sig) + "` must be unitless", pstate, traces);
65
+ return SASS_MEMORY_NEW(Number, pstate, n->value() * 100, "%");
66
+ }
67
+
68
+ Signature round_sig = "round($number)";
69
+ BUILT_IN(round)
70
+ {
71
+ Number_Obj r = ARGN("$number");
72
+ r->value(Sass::round(r->value(), ctx.c_options.precision));
73
+ r->pstate(pstate);
74
+ return r.detach();
75
+ }
76
+
77
+ Signature ceil_sig = "ceil($number)";
78
+ BUILT_IN(ceil)
79
+ {
80
+ Number_Obj r = ARGN("$number");
81
+ r->value(std::ceil(r->value()));
82
+ r->pstate(pstate);
83
+ return r.detach();
84
+ }
85
+
86
+ Signature floor_sig = "floor($number)";
87
+ BUILT_IN(floor)
88
+ {
89
+ Number_Obj r = ARGN("$number");
90
+ r->value(std::floor(r->value()));
91
+ r->pstate(pstate);
92
+ return r.detach();
93
+ }
94
+
95
+ Signature abs_sig = "abs($number)";
96
+ BUILT_IN(abs)
97
+ {
98
+ Number_Obj r = ARGN("$number");
99
+ r->value(std::abs(r->value()));
100
+ r->pstate(pstate);
101
+ return r.detach();
102
+ }
103
+
104
+ Signature min_sig = "min($numbers...)";
105
+ BUILT_IN(min)
106
+ {
107
+ List* arglist = ARG("$numbers", List);
108
+ Number_Obj least;
109
+ for (size_t i = 0, L = arglist->length(); i < L; ++i) {
110
+ Expression_Obj val = arglist->value_at_index(i);
111
+ Number_Obj xi = Cast<Number>(val);
112
+ if (!xi) {
113
+ error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `min'", pstate, traces);
114
+ }
115
+ if (least) {
116
+ if (*xi < *least) least = xi;
117
+ } else least = xi;
118
+ }
119
+ return least.detach();
120
+ }
121
+
122
+ Signature max_sig = "max($numbers...)";
123
+ BUILT_IN(max)
124
+ {
125
+ List* arglist = ARG("$numbers", List);
126
+ Number_Obj greatest;
127
+ for (size_t i = 0, L = arglist->length(); i < L; ++i) {
128
+ Expression_Obj val = arglist->value_at_index(i);
129
+ Number_Obj xi = Cast<Number>(val);
130
+ if (!xi) {
131
+ error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `max'", pstate, traces);
132
+ }
133
+ if (greatest) {
134
+ if (*greatest < *xi) greatest = xi;
135
+ } else greatest = xi;
136
+ }
137
+ return greatest.detach();
138
+ }
139
+
140
+ Signature random_sig = "random($limit:false)";
141
+ BUILT_IN(random)
142
+ {
143
+ AST_Node_Obj arg = env["$limit"];
144
+ Value* v = Cast<Value>(arg);
145
+ Number* l = Cast<Number>(arg);
146
+ Boolean* b = Cast<Boolean>(arg);
147
+ if (l) {
148
+ double lv = l->value();
149
+ if (lv < 1) {
150
+ std::stringstream err;
151
+ err << "$limit " << lv << " must be greater than or equal to 1 for `random'";
152
+ error(err.str(), pstate, traces);
153
+ }
154
+ bool eq_int = std::fabs(trunc(lv) - lv) < NUMBER_EPSILON;
155
+ if (!eq_int) {
156
+ std::stringstream err;
157
+ err << "Expected $limit to be an integer but got " << lv << " for `random'";
158
+ error(err.str(), pstate, traces);
159
+ }
160
+ std::uniform_real_distribution<> distributor(1, lv + 1);
161
+ uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
162
+ return SASS_MEMORY_NEW(Number, pstate, (double)distributed);
163
+ }
164
+ else if (b) {
165
+ std::uniform_real_distribution<> distributor(0, 1);
166
+ double distributed = static_cast<double>(distributor(rand));
167
+ return SASS_MEMORY_NEW(Number, pstate, distributed);
168
+ } else if (v) {
169
+ traces.push_back(Backtrace(pstate));
170
+ throw Exception::InvalidArgumentType(pstate, traces, "random", "$limit", "number", v);
171
+ } else {
172
+ traces.push_back(Backtrace(pstate));
173
+ throw Exception::InvalidArgumentType(pstate, traces, "random", "$limit", "number");
174
+ }
175
+ }
176
+
177
+ Signature unique_id_sig = "unique-id()";
178
+ BUILT_IN(unique_id)
179
+ {
180
+ std::stringstream ss;
181
+ std::uniform_real_distribution<> distributor(0, 4294967296); // 16^8
182
+ uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
183
+ ss << "u" << std::setfill('0') << std::setw(8) << std::hex << distributed;
184
+ return SASS_MEMORY_NEW(String_Quoted, pstate, ss.str());
185
+ }
186
+
187
+ Signature unit_sig = "unit($number)";
188
+ BUILT_IN(unit)
189
+ {
190
+ Number_Obj arg = ARGN("$number");
191
+ std::string str(quote(arg->unit(), '"'));
192
+ return SASS_MEMORY_NEW(String_Quoted, pstate, str);
193
+ }
194
+
195
+ Signature unitless_sig = "unitless($number)";
196
+ BUILT_IN(unitless)
197
+ {
198
+ Number_Obj arg = ARGN("$number");
199
+ bool unitless = arg->is_unitless();
200
+ return SASS_MEMORY_NEW(Boolean, pstate, unitless);
201
+ }
202
+
203
+ Signature comparable_sig = "comparable($number-1, $number-2)";
204
+ BUILT_IN(comparable)
205
+ {
206
+ Number_Obj n1 = ARGN("$number-1");
207
+ Number_Obj n2 = ARGN("$number-2");
208
+ if (n1->is_unitless() || n2->is_unitless()) {
209
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
210
+ }
211
+ // normalize into main units
212
+ n1->normalize(); n2->normalize();
213
+ Units &lhs_unit = *n1, &rhs_unit = *n2;
214
+ bool is_comparable = (lhs_unit == rhs_unit);
215
+ return SASS_MEMORY_NEW(Boolean, pstate, is_comparable);
216
+ }
217
+
218
+ }
219
+
220
+ }