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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitmodules +1 -1
- data/.travis.yml +7 -3
- data/CHANGELOG.md +3 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/README.md +1 -1
- data/Rakefile +23 -8
- data/ext/extconf.rb +39 -0
- data/ext/libsass/.gitignore +1 -0
- data/ext/libsass/GNUmakefile.am +23 -39
- data/ext/libsass/Makefile +56 -91
- data/ext/libsass/Makefile.conf +16 -2
- data/ext/libsass/configure.ac +8 -12
- data/ext/libsass/include/sass/base.h +1 -0
- data/ext/libsass/include/sass/context.h +1 -1
- data/ext/libsass/src/GNUmakefile.am +1 -5
- data/ext/libsass/src/ast.cpp +747 -2010
- data/ext/libsass/src/ast.hpp +239 -2383
- data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +62 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
- data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
- data/ext/libsass/src/ast_sel_unify.cpp +280 -0
- data/ext/libsass/src/ast_selectors.cpp +1475 -0
- data/ext/libsass/src/ast_selectors.hpp +568 -0
- data/ext/libsass/src/ast_supports.cpp +130 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +967 -0
- data/ext/libsass/src/ast_values.hpp +489 -0
- data/ext/libsass/src/backtrace.cpp +4 -0
- data/ext/libsass/src/base64vlq.cpp +3 -0
- data/ext/libsass/src/bind.cpp +18 -17
- data/ext/libsass/src/bind.hpp +3 -1
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/cencode.c +2 -2
- data/ext/libsass/src/check_nesting.cpp +52 -56
- data/ext/libsass/src/check_nesting.hpp +35 -34
- data/ext/libsass/src/color_maps.cpp +156 -153
- data/ext/libsass/src/color_maps.hpp +152 -152
- data/ext/libsass/src/constants.cpp +15 -0
- data/ext/libsass/src/constants.hpp +13 -0
- data/ext/libsass/src/context.cpp +24 -14
- data/ext/libsass/src/context.hpp +6 -6
- data/ext/libsass/src/cssize.cpp +69 -71
- data/ext/libsass/src/cssize.hpp +50 -50
- data/ext/libsass/src/debugger.hpp +117 -110
- data/ext/libsass/src/emitter.cpp +13 -12
- data/ext/libsass/src/emitter.hpp +13 -9
- data/ext/libsass/src/environment.cpp +15 -1
- data/ext/libsass/src/environment.hpp +6 -0
- data/ext/libsass/src/error_handling.cpp +36 -59
- data/ext/libsass/src/error_handling.hpp +29 -16
- data/ext/libsass/src/eval.cpp +302 -323
- data/ext/libsass/src/eval.hpp +64 -55
- data/ext/libsass/src/expand.cpp +94 -88
- data/ext/libsass/src/expand.hpp +33 -37
- data/ext/libsass/src/extend.cpp +38 -36
- data/ext/libsass/src/extend.hpp +15 -15
- data/ext/libsass/src/file.cpp +34 -2
- data/ext/libsass/src/fn_colors.cpp +594 -0
- data/ext/libsass/src/fn_colors.hpp +85 -0
- data/ext/libsass/src/fn_lists.cpp +284 -0
- data/ext/libsass/src/fn_lists.hpp +34 -0
- data/ext/libsass/src/fn_maps.cpp +94 -0
- data/ext/libsass/src/fn_maps.hpp +30 -0
- data/ext/libsass/src/fn_miscs.cpp +256 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +220 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +235 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +254 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +156 -0
- data/ext/libsass/src/fn_utils.hpp +56 -0
- data/ext/libsass/src/inspect.cpp +101 -152
- data/ext/libsass/src/inspect.hpp +69 -73
- data/ext/libsass/src/json.cpp +2 -2
- data/ext/libsass/src/lexer.cpp +6 -3
- data/ext/libsass/src/listize.cpp +9 -11
- data/ext/libsass/src/listize.hpp +11 -7
- data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
- data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
- data/ext/libsass/src/node.cpp +13 -10
- data/ext/libsass/src/node.hpp +3 -3
- data/ext/libsass/src/operation.hpp +184 -144
- data/ext/libsass/src/operators.cpp +43 -17
- data/ext/libsass/src/operators.hpp +5 -5
- data/ext/libsass/src/output.cpp +21 -18
- data/ext/libsass/src/output.hpp +14 -21
- data/ext/libsass/src/parser.cpp +215 -183
- data/ext/libsass/src/parser.hpp +28 -24
- data/ext/libsass/src/plugins.cpp +5 -1
- data/ext/libsass/src/position.cpp +3 -0
- data/ext/libsass/src/prelexer.cpp +9 -3
- data/ext/libsass/src/prelexer.hpp +9 -9
- data/ext/libsass/src/remove_placeholders.cpp +14 -11
- data/ext/libsass/src/remove_placeholders.hpp +8 -9
- data/ext/libsass/src/sass.cpp +9 -3
- data/ext/libsass/src/sass.hpp +12 -9
- data/ext/libsass/src/sass2scss.cpp +45 -14
- data/ext/libsass/src/sass_context.cpp +18 -15
- data/ext/libsass/src/sass_functions.cpp +6 -3
- data/ext/libsass/src/sass_functions.hpp +1 -1
- data/ext/libsass/src/sass_util.cpp +3 -0
- data/ext/libsass/src/sass_values.cpp +21 -13
- data/ext/libsass/src/source_map.cpp +5 -2
- data/ext/libsass/src/source_map.hpp +2 -2
- data/ext/libsass/src/subset_map.cpp +4 -1
- data/ext/libsass/src/to_value.cpp +23 -21
- data/ext/libsass/src/to_value.hpp +18 -22
- data/ext/libsass/src/units.cpp +4 -0
- data/ext/libsass/src/units.hpp +1 -0
- data/ext/libsass/src/utf8/checked.h +12 -10
- data/ext/libsass/src/utf8/core.h +3 -0
- data/ext/libsass/src/utf8_string.cpp +3 -0
- data/ext/libsass/src/util.cpp +67 -75
- data/ext/libsass/src/util.hpp +64 -19
- data/ext/libsass/src/util_string.cpp +75 -0
- data/ext/libsass/src/util_string.hpp +19 -0
- data/ext/libsass/src/values.cpp +22 -13
- data/ext/libsass/src/values.hpp +2 -2
- data/ext/libsass/win/libsass.targets +30 -4
- data/ext/libsass/win/libsass.vcxproj.filters +82 -4
- data/lib/sassc.rb +24 -0
- data/lib/sassc/engine.rb +2 -2
- data/lib/sassc/native.rb +8 -1
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +19 -11
- data/test/engine_test.rb +26 -1
- data/test/native_test.rb +1 -1
- metadata +66 -72
- data/ext/Rakefile +0 -3
- data/ext/libsass/.github/CONTRIBUTING.md +0 -65
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
- data/ext/libsass/.travis.yml +0 -64
- data/ext/libsass/Readme.md +0 -104
- data/ext/libsass/SECURITY.md +0 -10
- data/ext/libsass/appveyor.yml +0 -91
- data/ext/libsass/docs/README.md +0 -20
- data/ext/libsass/docs/api-context-example.md +0 -45
- data/ext/libsass/docs/api-context-internal.md +0 -163
- data/ext/libsass/docs/api-context.md +0 -295
- data/ext/libsass/docs/api-doc.md +0 -215
- data/ext/libsass/docs/api-function-example.md +0 -67
- data/ext/libsass/docs/api-function-internal.md +0 -8
- data/ext/libsass/docs/api-function.md +0 -74
- data/ext/libsass/docs/api-importer-example.md +0 -112
- data/ext/libsass/docs/api-importer-internal.md +0 -20
- data/ext/libsass/docs/api-importer.md +0 -86
- data/ext/libsass/docs/api-value-example.md +0 -55
- data/ext/libsass/docs/api-value-internal.md +0 -76
- data/ext/libsass/docs/api-value.md +0 -154
- data/ext/libsass/docs/build-on-darwin.md +0 -27
- data/ext/libsass/docs/build-on-gentoo.md +0 -55
- data/ext/libsass/docs/build-on-windows.md +0 -139
- data/ext/libsass/docs/build-shared-library.md +0 -35
- data/ext/libsass/docs/build-with-autotools.md +0 -78
- data/ext/libsass/docs/build-with-makefiles.md +0 -68
- data/ext/libsass/docs/build-with-mingw.md +0 -107
- data/ext/libsass/docs/build-with-visual-studio.md +0 -90
- data/ext/libsass/docs/build.md +0 -97
- data/ext/libsass/docs/compatibility-plan.md +0 -48
- data/ext/libsass/docs/contributing.md +0 -17
- data/ext/libsass/docs/custom-functions-internal.md +0 -122
- data/ext/libsass/docs/dev-ast-memory.md +0 -223
- data/ext/libsass/docs/implementations.md +0 -56
- data/ext/libsass/docs/plugins.md +0 -47
- data/ext/libsass/docs/setup-environment.md +0 -68
- data/ext/libsass/docs/source-map-internals.md +0 -51
- data/ext/libsass/docs/trace.md +0 -26
- data/ext/libsass/docs/triage.md +0 -17
- data/ext/libsass/docs/unicode.md +0 -39
- data/ext/libsass/extconf.rb +0 -6
- data/ext/libsass/script/bootstrap +0 -13
- data/ext/libsass/script/branding +0 -10
- data/ext/libsass/script/ci-build-libsass +0 -134
- data/ext/libsass/script/ci-build-plugin +0 -62
- data/ext/libsass/script/ci-install-compiler +0 -6
- data/ext/libsass/script/ci-install-deps +0 -20
- data/ext/libsass/script/ci-report-coverage +0 -42
- data/ext/libsass/script/spec +0 -5
- data/ext/libsass/script/tap-driver +0 -652
- data/ext/libsass/script/tap-runner +0 -1
- data/ext/libsass/script/test-leaks.pl +0 -103
- data/ext/libsass/src/functions.cpp +0 -2234
- data/ext/libsass/src/functions.hpp +0 -198
- data/ext/libsass/src/to_c.hpp +0 -39
- data/ext/libsass/test/test_node.cpp +0 -94
- data/ext/libsass/test/test_paths.cpp +0 -28
- data/ext/libsass/test/test_selector_difference.cpp +0 -25
- data/ext/libsass/test/test_specificity.cpp +0 -25
- data/ext/libsass/test/test_subset_map.cpp +0 -472
- data/ext/libsass/test/test_superselector.cpp +0 -69
- data/ext/libsass/test/test_unification.cpp +0 -31
- 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
|
+
}
|