sassc 2.0.1 → 2.1.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|