sassc 2.0.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +9 -3
  5. data/CHANGELOG.md +36 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +43 -7
  9. data/ext/depend +4 -0
  10. data/ext/extconf.rb +92 -0
  11. data/ext/libsass/VERSION +1 -0
  12. data/ext/libsass/include/sass/base.h +9 -1
  13. data/ext/libsass/include/sass/context.h +5 -1
  14. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  15. data/ext/libsass/src/ast.cpp +755 -2028
  16. data/ext/libsass/src/ast.hpp +492 -2477
  17. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  18. data/ext/libsass/src/ast2c.hpp +39 -0
  19. data/ext/libsass/src/ast_def_macros.hpp +70 -10
  20. data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
  21. data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
  22. data/ext/libsass/src/ast_helpers.hpp +292 -0
  23. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  24. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  25. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  26. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1043 -0
  28. data/ext/libsass/src/ast_selectors.hpp +522 -0
  29. data/ext/libsass/src/ast_supports.cpp +114 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +1154 -0
  32. data/ext/libsass/src/ast_values.hpp +498 -0
  33. data/ext/libsass/src/backtrace.cpp +11 -7
  34. data/ext/libsass/src/backtrace.hpp +5 -5
  35. data/ext/libsass/src/base64vlq.cpp +5 -2
  36. data/ext/libsass/src/base64vlq.hpp +1 -1
  37. data/ext/libsass/src/bind.cpp +35 -34
  38. data/ext/libsass/src/bind.hpp +3 -1
  39. data/ext/libsass/src/c2ast.cpp +64 -0
  40. data/ext/libsass/src/c2ast.hpp +14 -0
  41. data/ext/libsass/src/cencode.c +4 -6
  42. data/ext/libsass/src/check_nesting.cpp +83 -88
  43. data/ext/libsass/src/check_nesting.hpp +39 -34
  44. data/ext/libsass/src/color_maps.cpp +168 -164
  45. data/ext/libsass/src/color_maps.hpp +152 -160
  46. data/ext/libsass/src/constants.cpp +20 -0
  47. data/ext/libsass/src/constants.hpp +19 -0
  48. data/ext/libsass/src/context.cpp +104 -121
  49. data/ext/libsass/src/context.hpp +43 -55
  50. data/ext/libsass/src/cssize.cpp +103 -188
  51. data/ext/libsass/src/cssize.hpp +45 -51
  52. data/ext/libsass/src/dart_helpers.hpp +199 -0
  53. data/ext/libsass/src/debugger.hpp +524 -361
  54. data/ext/libsass/src/emitter.cpp +26 -26
  55. data/ext/libsass/src/emitter.hpp +20 -18
  56. data/ext/libsass/src/environment.cpp +41 -27
  57. data/ext/libsass/src/environment.hpp +33 -22
  58. data/ext/libsass/src/error_handling.cpp +92 -94
  59. data/ext/libsass/src/error_handling.hpp +73 -50
  60. data/ext/libsass/src/eval.cpp +380 -515
  61. data/ext/libsass/src/eval.hpp +64 -57
  62. data/ext/libsass/src/eval_selectors.cpp +75 -0
  63. data/ext/libsass/src/expand.cpp +322 -263
  64. data/ext/libsass/src/expand.hpp +55 -39
  65. data/ext/libsass/src/extender.cpp +1188 -0
  66. data/ext/libsass/src/extender.hpp +399 -0
  67. data/ext/libsass/src/extension.cpp +43 -0
  68. data/ext/libsass/src/extension.hpp +89 -0
  69. data/ext/libsass/src/file.cpp +134 -88
  70. data/ext/libsass/src/file.hpp +28 -37
  71. data/ext/libsass/src/fn_colors.cpp +596 -0
  72. data/ext/libsass/src/fn_colors.hpp +85 -0
  73. data/ext/libsass/src/fn_lists.cpp +285 -0
  74. data/ext/libsass/src/fn_lists.hpp +34 -0
  75. data/ext/libsass/src/fn_maps.cpp +94 -0
  76. data/ext/libsass/src/fn_maps.hpp +30 -0
  77. data/ext/libsass/src/fn_miscs.cpp +244 -0
  78. data/ext/libsass/src/fn_miscs.hpp +40 -0
  79. data/ext/libsass/src/fn_numbers.cpp +227 -0
  80. data/ext/libsass/src/fn_numbers.hpp +45 -0
  81. data/ext/libsass/src/fn_selectors.cpp +205 -0
  82. data/ext/libsass/src/fn_selectors.hpp +35 -0
  83. data/ext/libsass/src/fn_strings.cpp +268 -0
  84. data/ext/libsass/src/fn_strings.hpp +34 -0
  85. data/ext/libsass/src/fn_utils.cpp +158 -0
  86. data/ext/libsass/src/fn_utils.hpp +62 -0
  87. data/ext/libsass/src/inspect.cpp +253 -266
  88. data/ext/libsass/src/inspect.hpp +72 -74
  89. data/ext/libsass/src/json.cpp +2 -2
  90. data/ext/libsass/src/lexer.cpp +25 -84
  91. data/ext/libsass/src/lexer.hpp +5 -16
  92. data/ext/libsass/src/listize.cpp +27 -43
  93. data/ext/libsass/src/listize.hpp +14 -11
  94. data/ext/libsass/src/mapping.hpp +1 -0
  95. data/ext/libsass/src/memory.hpp +12 -0
  96. data/ext/libsass/src/memory/allocator.cpp +48 -0
  97. data/ext/libsass/src/memory/allocator.hpp +138 -0
  98. data/ext/libsass/src/memory/config.hpp +20 -0
  99. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  100. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  101. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  102. data/ext/libsass/src/operation.hpp +193 -143
  103. data/ext/libsass/src/operators.cpp +56 -29
  104. data/ext/libsass/src/operators.hpp +11 -11
  105. data/ext/libsass/src/ordered_map.hpp +112 -0
  106. data/ext/libsass/src/output.cpp +59 -75
  107. data/ext/libsass/src/output.hpp +15 -22
  108. data/ext/libsass/src/parser.cpp +662 -818
  109. data/ext/libsass/src/parser.hpp +96 -100
  110. data/ext/libsass/src/parser_selectors.cpp +189 -0
  111. data/ext/libsass/src/permutate.hpp +164 -0
  112. data/ext/libsass/src/plugins.cpp +12 -8
  113. data/ext/libsass/src/plugins.hpp +8 -8
  114. data/ext/libsass/src/position.cpp +10 -26
  115. data/ext/libsass/src/position.hpp +44 -21
  116. data/ext/libsass/src/prelexer.cpp +14 -8
  117. data/ext/libsass/src/prelexer.hpp +9 -9
  118. data/ext/libsass/src/remove_placeholders.cpp +59 -57
  119. data/ext/libsass/src/remove_placeholders.hpp +20 -18
  120. data/ext/libsass/src/sass.cpp +25 -18
  121. data/ext/libsass/src/sass.hpp +22 -14
  122. data/ext/libsass/src/sass2scss.cpp +49 -18
  123. data/ext/libsass/src/sass_context.cpp +104 -132
  124. data/ext/libsass/src/sass_context.hpp +2 -2
  125. data/ext/libsass/src/sass_functions.cpp +7 -4
  126. data/ext/libsass/src/sass_functions.hpp +1 -1
  127. data/ext/libsass/src/sass_values.cpp +26 -21
  128. data/ext/libsass/src/settings.hpp +19 -0
  129. data/ext/libsass/src/source.cpp +69 -0
  130. data/ext/libsass/src/source.hpp +95 -0
  131. data/ext/libsass/src/source_data.hpp +32 -0
  132. data/ext/libsass/src/source_map.cpp +27 -20
  133. data/ext/libsass/src/source_map.hpp +14 -11
  134. data/ext/libsass/src/stylesheet.cpp +22 -0
  135. data/ext/libsass/src/stylesheet.hpp +57 -0
  136. data/ext/libsass/src/to_value.cpp +24 -22
  137. data/ext/libsass/src/to_value.hpp +18 -22
  138. data/ext/libsass/src/units.cpp +28 -22
  139. data/ext/libsass/src/units.hpp +9 -8
  140. data/ext/libsass/src/utf8/checked.h +12 -10
  141. data/ext/libsass/src/utf8/core.h +3 -0
  142. data/ext/libsass/src/utf8_string.cpp +12 -10
  143. data/ext/libsass/src/utf8_string.hpp +7 -6
  144. data/ext/libsass/src/util.cpp +97 -107
  145. data/ext/libsass/src/util.hpp +74 -30
  146. data/ext/libsass/src/util_string.cpp +125 -0
  147. data/ext/libsass/src/util_string.hpp +73 -0
  148. data/ext/libsass/src/values.cpp +33 -24
  149. data/ext/libsass/src/values.hpp +2 -2
  150. data/lib/sassc.rb +24 -0
  151. data/lib/sassc/engine.rb +7 -5
  152. data/lib/sassc/functions_handler.rb +11 -13
  153. data/lib/sassc/native.rb +10 -9
  154. data/lib/sassc/native/native_functions_api.rb +0 -5
  155. data/lib/sassc/script.rb +4 -6
  156. data/lib/sassc/version.rb +1 -1
  157. data/sassc.gemspec +32 -12
  158. data/test/engine_test.rb +32 -2
  159. data/test/functions_test.rb +38 -1
  160. data/test/native_test.rb +4 -4
  161. metadata +95 -109
  162. data/ext/Rakefile +0 -3
  163. data/ext/libsass/.editorconfig +0 -15
  164. data/ext/libsass/.gitattributes +0 -2
  165. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  166. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  167. data/ext/libsass/.gitignore +0 -85
  168. data/ext/libsass/.travis.yml +0 -64
  169. data/ext/libsass/COPYING +0 -25
  170. data/ext/libsass/GNUmakefile.am +0 -88
  171. data/ext/libsass/INSTALL +0 -1
  172. data/ext/libsass/LICENSE +0 -25
  173. data/ext/libsass/Makefile +0 -351
  174. data/ext/libsass/Makefile.conf +0 -55
  175. data/ext/libsass/Readme.md +0 -104
  176. data/ext/libsass/SECURITY.md +0 -10
  177. data/ext/libsass/appveyor.yml +0 -91
  178. data/ext/libsass/configure.ac +0 -138
  179. data/ext/libsass/contrib/libsass.spec +0 -66
  180. data/ext/libsass/docs/README.md +0 -20
  181. data/ext/libsass/docs/api-context-example.md +0 -45
  182. data/ext/libsass/docs/api-context-internal.md +0 -163
  183. data/ext/libsass/docs/api-context.md +0 -295
  184. data/ext/libsass/docs/api-doc.md +0 -215
  185. data/ext/libsass/docs/api-function-example.md +0 -67
  186. data/ext/libsass/docs/api-function-internal.md +0 -8
  187. data/ext/libsass/docs/api-function.md +0 -74
  188. data/ext/libsass/docs/api-importer-example.md +0 -112
  189. data/ext/libsass/docs/api-importer-internal.md +0 -20
  190. data/ext/libsass/docs/api-importer.md +0 -86
  191. data/ext/libsass/docs/api-value-example.md +0 -55
  192. data/ext/libsass/docs/api-value-internal.md +0 -76
  193. data/ext/libsass/docs/api-value.md +0 -154
  194. data/ext/libsass/docs/build-on-darwin.md +0 -27
  195. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  196. data/ext/libsass/docs/build-on-windows.md +0 -139
  197. data/ext/libsass/docs/build-shared-library.md +0 -35
  198. data/ext/libsass/docs/build-with-autotools.md +0 -78
  199. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  200. data/ext/libsass/docs/build-with-mingw.md +0 -107
  201. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  202. data/ext/libsass/docs/build.md +0 -97
  203. data/ext/libsass/docs/compatibility-plan.md +0 -48
  204. data/ext/libsass/docs/contributing.md +0 -17
  205. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  206. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  207. data/ext/libsass/docs/implementations.md +0 -56
  208. data/ext/libsass/docs/plugins.md +0 -47
  209. data/ext/libsass/docs/setup-environment.md +0 -68
  210. data/ext/libsass/docs/source-map-internals.md +0 -51
  211. data/ext/libsass/docs/trace.md +0 -26
  212. data/ext/libsass/docs/triage.md +0 -17
  213. data/ext/libsass/docs/unicode.md +0 -39
  214. data/ext/libsass/extconf.rb +0 -6
  215. data/ext/libsass/include/sass/version.h.in +0 -12
  216. data/ext/libsass/m4/.gitkeep +0 -0
  217. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
  218. data/ext/libsass/res/resource.rc +0 -35
  219. data/ext/libsass/script/bootstrap +0 -13
  220. data/ext/libsass/script/branding +0 -10
  221. data/ext/libsass/script/ci-build-libsass +0 -134
  222. data/ext/libsass/script/ci-build-plugin +0 -62
  223. data/ext/libsass/script/ci-install-compiler +0 -6
  224. data/ext/libsass/script/ci-install-deps +0 -20
  225. data/ext/libsass/script/ci-report-coverage +0 -42
  226. data/ext/libsass/script/spec +0 -5
  227. data/ext/libsass/script/tap-driver +0 -652
  228. data/ext/libsass/script/tap-runner +0 -1
  229. data/ext/libsass/script/test-leaks.pl +0 -103
  230. data/ext/libsass/src/GNUmakefile.am +0 -54
  231. data/ext/libsass/src/extend.cpp +0 -2130
  232. data/ext/libsass/src/extend.hpp +0 -86
  233. data/ext/libsass/src/functions.cpp +0 -2234
  234. data/ext/libsass/src/functions.hpp +0 -198
  235. data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
  236. data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
  237. data/ext/libsass/src/node.cpp +0 -319
  238. data/ext/libsass/src/node.hpp +0 -118
  239. data/ext/libsass/src/paths.hpp +0 -71
  240. data/ext/libsass/src/sass_util.cpp +0 -149
  241. data/ext/libsass/src/sass_util.hpp +0 -256
  242. data/ext/libsass/src/subset_map.cpp +0 -55
  243. data/ext/libsass/src/subset_map.hpp +0 -76
  244. data/ext/libsass/src/support/libsass.pc.in +0 -11
  245. data/ext/libsass/src/to_c.hpp +0 -39
  246. data/ext/libsass/test/test_node.cpp +0 -94
  247. data/ext/libsass/test/test_paths.cpp +0 -28
  248. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  249. data/ext/libsass/test/test_specificity.cpp +0 -25
  250. data/ext/libsass/test/test_subset_map.cpp +0 -472
  251. data/ext/libsass/test/test_superselector.cpp +0 -69
  252. data/ext/libsass/test/test_unification.cpp +0 -31
  253. data/ext/libsass/version.sh +0 -10
  254. data/ext/libsass/win/libsass.sln +0 -39
  255. data/ext/libsass/win/libsass.sln.DotSettings +0 -9
  256. data/ext/libsass/win/libsass.targets +0 -118
  257. data/ext/libsass/win/libsass.vcxproj +0 -188
  258. data/ext/libsass/win/libsass.vcxproj.filters +0 -357
  259. data/lib/sassc/native/lib_c.rb +0 -21
  260. 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,244 @@
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
+ //////////////////////////
12
+ // INTROSPECTION FUNCTIONS
13
+ //////////////////////////
14
+
15
+ Signature type_of_sig = "type-of($value)";
16
+ BUILT_IN(type_of)
17
+ {
18
+ Expression* v = ARG("$value", Expression);
19
+ return SASS_MEMORY_NEW(String_Quoted, pstate, v->type());
20
+ }
21
+
22
+ Signature variable_exists_sig = "variable-exists($name)";
23
+ BUILT_IN(variable_exists)
24
+ {
25
+ sass::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
26
+
27
+ if(d_env.has("$"+s)) {
28
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
29
+ }
30
+ else {
31
+ return SASS_MEMORY_NEW(Boolean, pstate, false);
32
+ }
33
+ }
34
+
35
+ Signature global_variable_exists_sig = "global-variable-exists($name)";
36
+ BUILT_IN(global_variable_exists)
37
+ {
38
+ sass::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
39
+
40
+ if(d_env.has_global("$"+s)) {
41
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
42
+ }
43
+ else {
44
+ return SASS_MEMORY_NEW(Boolean, pstate, false);
45
+ }
46
+ }
47
+
48
+ Signature function_exists_sig = "function-exists($name)";
49
+ BUILT_IN(function_exists)
50
+ {
51
+ String_Constant* ss = Cast<String_Constant>(env["$name"]);
52
+ if (!ss) {
53
+ error("$name: " + (env["$name"]->to_string()) + " is not a string for `function-exists'", pstate, traces);
54
+ }
55
+
56
+ sass::string name = Util::normalize_underscores(unquote(ss->value()));
57
+
58
+ if(d_env.has(name+"[f]")) {
59
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
60
+ }
61
+ else {
62
+ return SASS_MEMORY_NEW(Boolean, pstate, false);
63
+ }
64
+ }
65
+
66
+ Signature mixin_exists_sig = "mixin-exists($name)";
67
+ BUILT_IN(mixin_exists)
68
+ {
69
+ sass::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
70
+
71
+ if(d_env.has(s+"[m]")) {
72
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
73
+ }
74
+ else {
75
+ return SASS_MEMORY_NEW(Boolean, pstate, false);
76
+ }
77
+ }
78
+
79
+ Signature feature_exists_sig = "feature-exists($feature)";
80
+ BUILT_IN(feature_exists)
81
+ {
82
+ sass::string s = unquote(ARG("$feature", String_Constant)->value());
83
+
84
+ static const auto *const features = new std::unordered_set<sass::string> {
85
+ "global-variable-shadowing",
86
+ "extend-selector-pseudoclass",
87
+ "at-error",
88
+ "units-level-3",
89
+ "custom-property"
90
+ };
91
+ return SASS_MEMORY_NEW(Boolean, pstate, features->find(s) != features->end());
92
+ }
93
+
94
+ Signature call_sig = "call($function, $args...)";
95
+ BUILT_IN(call)
96
+ {
97
+ sass::string function;
98
+ Function* ff = Cast<Function>(env["$function"]);
99
+ String_Constant* ss = Cast<String_Constant>(env["$function"]);
100
+
101
+ if (ss) {
102
+ function = Util::normalize_underscores(unquote(ss->value()));
103
+ std::cerr << "DEPRECATION WARNING: ";
104
+ std::cerr << "Passing a string to call() is deprecated and will be illegal" << std::endl;
105
+ std::cerr << "in Sass 4.0. Use call(get-function(" + quote(function) + ")) instead." << std::endl;
106
+ std::cerr << std::endl;
107
+ } else if (ff) {
108
+ function = ff->name();
109
+ }
110
+
111
+ List_Obj arglist = SASS_MEMORY_COPY(ARG("$args", List));
112
+
113
+ Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
114
+ // sass::string full_name(name + "[f]");
115
+ // Definition* def = d_env.has(full_name) ? Cast<Definition>((d_env)[full_name]) : 0;
116
+ // Parameters* params = def ? def->parameters() : 0;
117
+ // size_t param_size = params ? params->length() : 0;
118
+ for (size_t i = 0, L = arglist->length(); i < L; ++i) {
119
+ ExpressionObj expr = arglist->value_at_index(i);
120
+ // if (params && params->has_rest_parameter()) {
121
+ // Parameter_Obj p = param_size > i ? (*params)[i] : 0;
122
+ // List* list = Cast<List>(expr);
123
+ // if (list && p && !p->is_rest_parameter()) expr = (*list)[0];
124
+ // }
125
+ if (arglist->is_arglist()) {
126
+ ExpressionObj obj = arglist->at(i);
127
+ Argument_Obj arg = (Argument*) obj.ptr(); // XXX
128
+ args->append(SASS_MEMORY_NEW(Argument,
129
+ pstate,
130
+ expr,
131
+ arg ? arg->name() : "",
132
+ arg ? arg->is_rest_argument() : false,
133
+ arg ? arg->is_keyword_argument() : false));
134
+ } else {
135
+ args->append(SASS_MEMORY_NEW(Argument, pstate, expr));
136
+ }
137
+ }
138
+ Function_Call_Obj func = SASS_MEMORY_NEW(Function_Call, pstate, function, args);
139
+
140
+ Expand expand(ctx, &d_env, &selector_stack, &original_stack);
141
+ func->via_call(true); // calc invoke is allowed
142
+ if (ff) func->func(ff);
143
+ return Cast<PreValue>(func->perform(&expand.eval));
144
+ }
145
+
146
+ ////////////////////
147
+ // BOOLEAN FUNCTIONS
148
+ ////////////////////
149
+
150
+ Signature not_sig = "not($value)";
151
+ BUILT_IN(sass_not)
152
+ {
153
+ return SASS_MEMORY_NEW(Boolean, pstate, ARG("$value", Expression)->is_false());
154
+ }
155
+
156
+ Signature if_sig = "if($condition, $if-true, $if-false)";
157
+ BUILT_IN(sass_if)
158
+ {
159
+ Expand expand(ctx, &d_env, &selector_stack, &original_stack);
160
+ ExpressionObj cond = ARG("$condition", Expression)->perform(&expand.eval);
161
+ bool is_true = !cond->is_false();
162
+ ExpressionObj res = ARG(is_true ? "$if-true" : "$if-false", Expression);
163
+ ValueObj qwe = Cast<Value>(res->perform(&expand.eval));
164
+ // res = res->perform(&expand.eval.val_eval);
165
+ qwe->set_delayed(false); // clone?
166
+ return qwe.detach();
167
+ }
168
+
169
+ //////////////////////////
170
+ // MISCELLANEOUS FUNCTIONS
171
+ //////////////////////////
172
+
173
+ Signature inspect_sig = "inspect($value)";
174
+ BUILT_IN(inspect)
175
+ {
176
+ Expression* v = ARG("$value", Expression);
177
+ if (v->concrete_type() == Expression::NULL_VAL) {
178
+ return SASS_MEMORY_NEW(String_Constant, pstate, "null");
179
+ } else if (v->concrete_type() == Expression::BOOLEAN && v->is_false()) {
180
+ return SASS_MEMORY_NEW(String_Constant, pstate, "false");
181
+ } else if (v->concrete_type() == Expression::STRING) {
182
+ String_Constant *s = Cast<String_Constant>(v);
183
+ if (s->quote_mark()) {
184
+ return SASS_MEMORY_NEW(String_Constant, pstate, quote(s->value(), s->quote_mark()));
185
+ } else {
186
+ return s;
187
+ }
188
+ } else {
189
+ // ToDo: fix to_sass for nested parentheses
190
+ Sass_Output_Style old_style;
191
+ old_style = ctx.c_options.output_style;
192
+ ctx.c_options.output_style = TO_SASS;
193
+ Emitter emitter(ctx.c_options);
194
+ Inspect i(emitter);
195
+ i.in_declaration = false;
196
+ v->perform(&i);
197
+ ctx.c_options.output_style = old_style;
198
+ return SASS_MEMORY_NEW(String_Quoted, pstate, i.get_buffer());
199
+ }
200
+ }
201
+
202
+ Signature content_exists_sig = "content-exists()";
203
+ BUILT_IN(content_exists)
204
+ {
205
+ if (!d_env.has_global("is_in_mixin")) {
206
+ error("Cannot call content-exists() except within a mixin.", pstate, traces);
207
+ }
208
+ return SASS_MEMORY_NEW(Boolean, pstate, d_env.has_lexical("@content[m]"));
209
+ }
210
+
211
+ Signature get_function_sig = "get-function($name, $css: false)";
212
+ BUILT_IN(get_function)
213
+ {
214
+ String_Constant* ss = Cast<String_Constant>(env["$name"]);
215
+ if (!ss) {
216
+ error("$name: " + (env["$name"]->to_string()) + " is not a string for `get-function'", pstate, traces);
217
+ }
218
+
219
+ sass::string name = Util::normalize_underscores(unquote(ss->value()));
220
+ sass::string full_name = name + "[f]";
221
+
222
+ Boolean_Obj css = ARG("$css", Boolean);
223
+ if (!css->is_false()) {
224
+ Definition* def = SASS_MEMORY_NEW(Definition,
225
+ pstate,
226
+ name,
227
+ SASS_MEMORY_NEW(Parameters, pstate),
228
+ SASS_MEMORY_NEW(Block, pstate, 0, false),
229
+ Definition::FUNCTION);
230
+ return SASS_MEMORY_NEW(Function, pstate, def, true);
231
+ }
232
+
233
+
234
+ if (!d_env.has_global(full_name)) {
235
+ error("Function not found: " + name, pstate, traces);
236
+ }
237
+
238
+ Definition* def = Cast<Definition>(d_env[full_name]);
239
+ return SASS_MEMORY_NEW(Function, pstate, def, false);
240
+ }
241
+
242
+ }
243
+
244
+ }
@@ -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,227 @@
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 <random>
9
+ #include <sstream>
10
+ #include <iomanip>
11
+ #include <algorithm>
12
+
13
+ #include "ast.hpp"
14
+ #include "units.hpp"
15
+ #include "fn_utils.hpp"
16
+ #include "fn_numbers.hpp"
17
+
18
+ #ifdef __MINGW32__
19
+ #include "windows.h"
20
+ #include "wincrypt.h"
21
+ #endif
22
+
23
+ namespace Sass {
24
+
25
+ namespace Functions {
26
+
27
+ #ifdef __MINGW32__
28
+ uint64_t GetSeed()
29
+ {
30
+ HCRYPTPROV hp = 0;
31
+ BYTE rb[8];
32
+ CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
33
+ CryptGenRandom(hp, sizeof(rb), rb);
34
+ CryptReleaseContext(hp, 0);
35
+
36
+ uint64_t seed;
37
+ memcpy(&seed, &rb[0], sizeof(seed));
38
+
39
+ return seed;
40
+ }
41
+ #else
42
+ uint64_t GetSeed()
43
+ {
44
+ std::random_device rd;
45
+ return rd();
46
+ }
47
+ #endif
48
+
49
+ // note: the performance of many implementations of
50
+ // random_device degrades sharply once the entropy pool
51
+ // is exhausted. For practical use, random_device is
52
+ // generally only used to seed a PRNG such as mt19937.
53
+ static std::mt19937 rand(static_cast<unsigned int>(GetSeed()));
54
+
55
+ ///////////////////
56
+ // NUMBER FUNCTIONS
57
+ ///////////////////
58
+
59
+ Signature percentage_sig = "percentage($number)";
60
+ BUILT_IN(percentage)
61
+ {
62
+ Number_Obj n = ARGN("$number");
63
+ if (!n->is_unitless()) error("argument $number of `" + sass::string(sig) + "` must be unitless", pstate, traces);
64
+ return SASS_MEMORY_NEW(Number, pstate, n->value() * 100, "%");
65
+ }
66
+
67
+ Signature round_sig = "round($number)";
68
+ BUILT_IN(round)
69
+ {
70
+ Number_Obj r = ARGN("$number");
71
+ r->value(Sass::round(r->value(), ctx.c_options.precision));
72
+ r->pstate(pstate);
73
+ return r.detach();
74
+ }
75
+
76
+ Signature ceil_sig = "ceil($number)";
77
+ BUILT_IN(ceil)
78
+ {
79
+ Number_Obj r = ARGN("$number");
80
+ r->value(std::ceil(r->value()));
81
+ r->pstate(pstate);
82
+ return r.detach();
83
+ }
84
+
85
+ Signature floor_sig = "floor($number)";
86
+ BUILT_IN(floor)
87
+ {
88
+ Number_Obj r = ARGN("$number");
89
+ r->value(std::floor(r->value()));
90
+ r->pstate(pstate);
91
+ return r.detach();
92
+ }
93
+
94
+ Signature abs_sig = "abs($number)";
95
+ BUILT_IN(abs)
96
+ {
97
+ Number_Obj r = ARGN("$number");
98
+ r->value(std::abs(r->value()));
99
+ r->pstate(pstate);
100
+ return r.detach();
101
+ }
102
+
103
+ Signature min_sig = "min($numbers...)";
104
+ BUILT_IN(min)
105
+ {
106
+ List* arglist = ARG("$numbers", List);
107
+ Number_Obj least;
108
+ size_t L = arglist->length();
109
+ if (L == 0) {
110
+ error("At least one argument must be passed.", pstate, traces);
111
+ }
112
+ for (size_t i = 0; i < L; ++i) {
113
+ ExpressionObj val = arglist->value_at_index(i);
114
+ Number_Obj xi = Cast<Number>(val);
115
+ if (!xi) {
116
+ error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `min'", pstate, traces);
117
+ }
118
+ if (least) {
119
+ if (*xi < *least) least = xi;
120
+ } else least = xi;
121
+ }
122
+ return least.detach();
123
+ }
124
+
125
+ Signature max_sig = "max($numbers...)";
126
+ BUILT_IN(max)
127
+ {
128
+ List* arglist = ARG("$numbers", List);
129
+ Number_Obj greatest;
130
+ size_t L = arglist->length();
131
+ if (L == 0) {
132
+ error("At least one argument must be passed.", pstate, traces);
133
+ }
134
+ for (size_t i = 0; i < L; ++i) {
135
+ ExpressionObj val = arglist->value_at_index(i);
136
+ Number_Obj xi = Cast<Number>(val);
137
+ if (!xi) {
138
+ error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `max'", pstate, traces);
139
+ }
140
+ if (greatest) {
141
+ if (*greatest < *xi) greatest = xi;
142
+ } else greatest = xi;
143
+ }
144
+ return greatest.detach();
145
+ }
146
+
147
+ Signature random_sig = "random($limit:false)";
148
+ BUILT_IN(random)
149
+ {
150
+ AST_Node_Obj arg = env["$limit"];
151
+ Value* v = Cast<Value>(arg);
152
+ Number* l = Cast<Number>(arg);
153
+ Boolean* b = Cast<Boolean>(arg);
154
+ if (l) {
155
+ double lv = l->value();
156
+ if (lv < 1) {
157
+ sass::ostream err;
158
+ err << "$limit " << lv << " must be greater than or equal to 1 for `random'";
159
+ error(err.str(), pstate, traces);
160
+ }
161
+ bool eq_int = std::fabs(trunc(lv) - lv) < NUMBER_EPSILON;
162
+ if (!eq_int) {
163
+ sass::ostream err;
164
+ err << "Expected $limit to be an integer but got " << lv << " for `random'";
165
+ error(err.str(), pstate, traces);
166
+ }
167
+ std::uniform_real_distribution<> distributor(1, lv + 1);
168
+ uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
169
+ return SASS_MEMORY_NEW(Number, pstate, (double)distributed);
170
+ }
171
+ else if (b) {
172
+ std::uniform_real_distribution<> distributor(0, 1);
173
+ double distributed = static_cast<double>(distributor(rand));
174
+ return SASS_MEMORY_NEW(Number, pstate, distributed);
175
+ } else if (v) {
176
+ traces.push_back(Backtrace(pstate));
177
+ throw Exception::InvalidArgumentType(pstate, traces, "random", "$limit", "number", v);
178
+ } else {
179
+ traces.push_back(Backtrace(pstate));
180
+ throw Exception::InvalidArgumentType(pstate, traces, "random", "$limit", "number");
181
+ }
182
+ }
183
+
184
+ Signature unique_id_sig = "unique-id()";
185
+ BUILT_IN(unique_id)
186
+ {
187
+ sass::ostream ss;
188
+ std::uniform_real_distribution<> distributor(0, 4294967296); // 16^8
189
+ uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
190
+ ss << "u" << std::setfill('0') << std::setw(8) << std::hex << distributed;
191
+ return SASS_MEMORY_NEW(String_Quoted, pstate, ss.str());
192
+ }
193
+
194
+ Signature unit_sig = "unit($number)";
195
+ BUILT_IN(unit)
196
+ {
197
+ Number_Obj arg = ARGN("$number");
198
+ sass::string str(quote(arg->unit(), '"'));
199
+ return SASS_MEMORY_NEW(String_Quoted, pstate, str);
200
+ }
201
+
202
+ Signature unitless_sig = "unitless($number)";
203
+ BUILT_IN(unitless)
204
+ {
205
+ Number_Obj arg = ARGN("$number");
206
+ bool unitless = arg->is_unitless();
207
+ return SASS_MEMORY_NEW(Boolean, pstate, unitless);
208
+ }
209
+
210
+ Signature comparable_sig = "comparable($number1, $number2)";
211
+ BUILT_IN(comparable)
212
+ {
213
+ Number_Obj n1 = ARGN("$number1");
214
+ Number_Obj n2 = ARGN("$number2");
215
+ if (n1->is_unitless() || n2->is_unitless()) {
216
+ return SASS_MEMORY_NEW(Boolean, pstate, true);
217
+ }
218
+ // normalize into main units
219
+ n1->normalize(); n2->normalize();
220
+ Units &lhs_unit = *n1, &rhs_unit = *n2;
221
+ bool is_comparable = (lhs_unit == rhs_unit);
222
+ return SASS_MEMORY_NEW(Boolean, pstate, is_comparable);
223
+ }
224
+
225
+ }
226
+
227
+ }