sassc4 2.4.0
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 +7 -0
- data/.gitignore +18 -0
- data/.gitmodules +3 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +97 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +51 -0
- data/ext/depend +4 -0
- data/ext/extconf.rb +92 -0
- data/ext/libsass/VERSION +1 -0
- data/ext/libsass/contrib/plugin.cpp +60 -0
- data/ext/libsass/include/sass/base.h +97 -0
- data/ext/libsass/include/sass/context.h +174 -0
- data/ext/libsass/include/sass/functions.h +139 -0
- data/ext/libsass/include/sass/values.h +145 -0
- data/ext/libsass/include/sass/version.h +12 -0
- data/ext/libsass/include/sass.h +15 -0
- data/ext/libsass/include/sass2scss.h +120 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +953 -0
- data/ext/libsass/src/ast.hpp +1064 -0
- data/ext/libsass/src/ast2c.cpp +80 -0
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +140 -0
- data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
- data/ext/libsass/src/ast_helpers.hpp +316 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +275 -0
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +1070 -0
- data/ext/libsass/src/ast_selectors.hpp +523 -0
- data/ext/libsass/src/ast_supports.cpp +114 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +1154 -0
- data/ext/libsass/src/ast_values.hpp +498 -0
- data/ext/libsass/src/b64/cencode.h +32 -0
- data/ext/libsass/src/b64/encode.h +79 -0
- data/ext/libsass/src/backtrace.cpp +50 -0
- data/ext/libsass/src/backtrace.hpp +29 -0
- data/ext/libsass/src/base64vlq.cpp +47 -0
- data/ext/libsass/src/base64vlq.hpp +30 -0
- data/ext/libsass/src/bind.cpp +312 -0
- data/ext/libsass/src/bind.hpp +15 -0
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/c99func.c +54 -0
- data/ext/libsass/src/cencode.c +106 -0
- data/ext/libsass/src/check_nesting.cpp +393 -0
- data/ext/libsass/src/check_nesting.hpp +70 -0
- data/ext/libsass/src/color_maps.cpp +652 -0
- data/ext/libsass/src/color_maps.hpp +323 -0
- data/ext/libsass/src/color_spaces.cpp +241 -0
- data/ext/libsass/src/color_spaces.hpp +227 -0
- data/ext/libsass/src/constants.cpp +199 -0
- data/ext/libsass/src/constants.hpp +200 -0
- data/ext/libsass/src/context.cpp +870 -0
- data/ext/libsass/src/context.hpp +140 -0
- data/ext/libsass/src/cssize.cpp +521 -0
- data/ext/libsass/src/cssize.hpp +71 -0
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debug.hpp +43 -0
- data/ext/libsass/src/debugger.hpp +964 -0
- data/ext/libsass/src/emitter.cpp +297 -0
- data/ext/libsass/src/emitter.hpp +101 -0
- data/ext/libsass/src/environment.cpp +260 -0
- data/ext/libsass/src/environment.hpp +124 -0
- data/ext/libsass/src/error_handling.cpp +239 -0
- data/ext/libsass/src/error_handling.hpp +248 -0
- data/ext/libsass/src/eval.cpp +1543 -0
- data/ext/libsass/src/eval.hpp +110 -0
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +875 -0
- data/ext/libsass/src/expand.hpp +98 -0
- data/ext/libsass/src/extender.cpp +1226 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +531 -0
- data/ext/libsass/src/file.hpp +124 -0
- data/ext/libsass/src/fn_colors.cpp +836 -0
- data/ext/libsass/src/fn_colors.hpp +99 -0
- data/ext/libsass/src/fn_lists.cpp +285 -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 +248 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +246 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +205 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +268 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +159 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +1126 -0
- data/ext/libsass/src/inspect.hpp +101 -0
- data/ext/libsass/src/json.cpp +1436 -0
- data/ext/libsass/src/json.hpp +117 -0
- data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
- data/ext/libsass/src/lexer.cpp +122 -0
- data/ext/libsass/src/lexer.hpp +304 -0
- data/ext/libsass/src/listize.cpp +70 -0
- data/ext/libsass/src/listize.hpp +37 -0
- data/ext/libsass/src/mapping.hpp +19 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
- data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +223 -0
- data/ext/libsass/src/operators.cpp +267 -0
- data/ext/libsass/src/operators.hpp +30 -0
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +320 -0
- data/ext/libsass/src/output.hpp +47 -0
- data/ext/libsass/src/parser.cpp +3059 -0
- data/ext/libsass/src/parser.hpp +395 -0
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +188 -0
- data/ext/libsass/src/plugins.hpp +57 -0
- data/ext/libsass/src/position.cpp +163 -0
- data/ext/libsass/src/position.hpp +147 -0
- data/ext/libsass/src/prelexer.cpp +1780 -0
- data/ext/libsass/src/prelexer.hpp +484 -0
- data/ext/libsass/src/remove_placeholders.cpp +86 -0
- data/ext/libsass/src/remove_placeholders.hpp +37 -0
- data/ext/libsass/src/sass.cpp +156 -0
- data/ext/libsass/src/sass.hpp +147 -0
- data/ext/libsass/src/sass2scss.cpp +895 -0
- data/ext/libsass/src/sass_context.cpp +742 -0
- data/ext/libsass/src/sass_context.hpp +129 -0
- data/ext/libsass/src/sass_functions.cpp +210 -0
- data/ext/libsass/src/sass_functions.hpp +50 -0
- data/ext/libsass/src/sass_values.cpp +362 -0
- data/ext/libsass/src/sass_values.hpp +82 -0
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +202 -0
- data/ext/libsass/src/source_map.hpp +65 -0
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +114 -0
- data/ext/libsass/src/to_value.hpp +46 -0
- data/ext/libsass/src/units.cpp +507 -0
- data/ext/libsass/src/units.hpp +110 -0
- data/ext/libsass/src/utf8/checked.h +336 -0
- data/ext/libsass/src/utf8/core.h +332 -0
- data/ext/libsass/src/utf8/unchecked.h +235 -0
- data/ext/libsass/src/utf8.h +34 -0
- data/ext/libsass/src/utf8_string.cpp +104 -0
- data/ext/libsass/src/utf8_string.hpp +38 -0
- data/ext/libsass/src/util.cpp +723 -0
- data/ext/libsass/src/util.hpp +105 -0
- data/ext/libsass/src/util_string.cpp +125 -0
- data/ext/libsass/src/util_string.hpp +73 -0
- data/ext/libsass/src/values.cpp +140 -0
- data/ext/libsass/src/values.hpp +12 -0
- data/lib/sassc/dependency.rb +17 -0
- data/lib/sassc/engine.rb +141 -0
- data/lib/sassc/error.rb +37 -0
- data/lib/sassc/functions_handler.rb +73 -0
- data/lib/sassc/import_handler.rb +50 -0
- data/lib/sassc/importer.rb +31 -0
- data/lib/sassc/native/native_context_api.rb +147 -0
- data/lib/sassc/native/native_functions_api.rb +159 -0
- data/lib/sassc/native/sass2scss_api.rb +10 -0
- data/lib/sassc/native/sass_input_style.rb +13 -0
- data/lib/sassc/native/sass_output_style.rb +12 -0
- data/lib/sassc/native/sass_value.rb +97 -0
- data/lib/sassc/native/string_list.rb +10 -0
- data/lib/sassc/native.rb +64 -0
- data/lib/sassc/sass_2_scss.rb +9 -0
- data/lib/sassc/script/functions.rb +8 -0
- data/lib/sassc/script/value/bool.rb +32 -0
- data/lib/sassc/script/value/color.rb +95 -0
- data/lib/sassc/script/value/list.rb +136 -0
- data/lib/sassc/script/value/map.rb +69 -0
- data/lib/sassc/script/value/number.rb +389 -0
- data/lib/sassc/script/value/string.rb +96 -0
- data/lib/sassc/script/value.rb +137 -0
- data/lib/sassc/script/value_conversion/base.rb +13 -0
- data/lib/sassc/script/value_conversion/bool.rb +13 -0
- data/lib/sassc/script/value_conversion/color.rb +18 -0
- data/lib/sassc/script/value_conversion/list.rb +25 -0
- data/lib/sassc/script/value_conversion/map.rb +21 -0
- data/lib/sassc/script/value_conversion/number.rb +13 -0
- data/lib/sassc/script/value_conversion/string.rb +17 -0
- data/lib/sassc/script/value_conversion.rb +69 -0
- data/lib/sassc/script.rb +17 -0
- data/lib/sassc/util/normalized_map.rb +117 -0
- data/lib/sassc/util.rb +231 -0
- data/lib/sassc/version.rb +5 -0
- data/lib/sassc.rb +57 -0
- data/sassc.gemspec +69 -0
- data/test/css_color_level4_test.rb +168 -0
- data/test/custom_importer_test.rb +127 -0
- data/test/engine_test.rb +314 -0
- data/test/error_test.rb +29 -0
- data/test/fixtures/paths.scss +10 -0
- data/test/functions_test.rb +340 -0
- data/test/native_test.rb +213 -0
- data/test/output_style_test.rb +107 -0
- data/test/sass_2_scss_test.rb +14 -0
- data/test/test_helper.rb +45 -0
- metadata +396 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#ifndef SASS_PATHS_H
|
|
2
|
+
#define SASS_PATHS_H
|
|
3
|
+
|
|
4
|
+
#include <vector>
|
|
5
|
+
|
|
6
|
+
namespace Sass {
|
|
7
|
+
|
|
8
|
+
// Returns a list of all possible paths through the given lists.
|
|
9
|
+
//
|
|
10
|
+
// For example, given `[[1, 2], [3, 4], [5, 6]]`, this returns:
|
|
11
|
+
//
|
|
12
|
+
// ```
|
|
13
|
+
// [[1, 3, 5],
|
|
14
|
+
// [2, 3, 5],
|
|
15
|
+
// [1, 4, 5],
|
|
16
|
+
// [2, 4, 5],
|
|
17
|
+
// [1, 3, 6],
|
|
18
|
+
// [2, 3, 6],
|
|
19
|
+
// [1, 4, 6],
|
|
20
|
+
// [2, 4, 6]]
|
|
21
|
+
// ```
|
|
22
|
+
//
|
|
23
|
+
// Note: called `paths` in dart-sass
|
|
24
|
+
template <class T>
|
|
25
|
+
sass::vector<sass::vector<T>> permutate(
|
|
26
|
+
const sass::vector<sass::vector<T>>& in)
|
|
27
|
+
{
|
|
28
|
+
|
|
29
|
+
size_t L = in.size(), n = 0;
|
|
30
|
+
|
|
31
|
+
if (L == 0) return {};
|
|
32
|
+
// Exit early if any entry is empty
|
|
33
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
34
|
+
if (in[i].size() == 0) return {};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
size_t* state = new size_t[L + 1];
|
|
38
|
+
sass::vector<sass::vector<T>> out;
|
|
39
|
+
|
|
40
|
+
// First initialize all states for every permutation group
|
|
41
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
42
|
+
state[i] = in[i].size() - 1;
|
|
43
|
+
}
|
|
44
|
+
while (true) {
|
|
45
|
+
sass::vector<T> perm;
|
|
46
|
+
// Create one permutation for state
|
|
47
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
48
|
+
perm.push_back(in.at(i).at(in[i].size() - state[i] - 1));
|
|
49
|
+
}
|
|
50
|
+
// Current group finished
|
|
51
|
+
if (state[n] == 0) {
|
|
52
|
+
// Find position of next decrement
|
|
53
|
+
while (n < L && state[++n] == 0) {}
|
|
54
|
+
|
|
55
|
+
if (n == L) {
|
|
56
|
+
out.push_back(perm);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
state[n] -= 1;
|
|
61
|
+
|
|
62
|
+
for (size_t p = 0; p < n; p += 1) {
|
|
63
|
+
state[p] = in[p].size() - 1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Restart from front
|
|
67
|
+
n = 0;
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
state[n] -= 1;
|
|
72
|
+
}
|
|
73
|
+
out.push_back(perm);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
delete[] state;
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
// EO permutate
|
|
80
|
+
|
|
81
|
+
// ToDo: this variant is used in resolveParentSelectors
|
|
82
|
+
// Returns a list of all possible paths through the given lists.
|
|
83
|
+
//
|
|
84
|
+
// For example, given `[[1, 2], [3, 4], [5, 6]]`, this returns:
|
|
85
|
+
//
|
|
86
|
+
// ```
|
|
87
|
+
// [[1, 3, 5],
|
|
88
|
+
// [1, 3, 6],
|
|
89
|
+
// [1, 4, 5],
|
|
90
|
+
// [1, 4, 6],
|
|
91
|
+
// [2, 3, 5],
|
|
92
|
+
// [2, 3, 6],
|
|
93
|
+
// [2, 4, 5],
|
|
94
|
+
// [2, 4, 6]]
|
|
95
|
+
// ```
|
|
96
|
+
//
|
|
97
|
+
template <class T>
|
|
98
|
+
sass::vector<sass::vector<T>>
|
|
99
|
+
permutateAlt(const sass::vector<sass::vector<T>>& in) {
|
|
100
|
+
|
|
101
|
+
size_t L = in.size();
|
|
102
|
+
size_t n = in.size() - 1;
|
|
103
|
+
|
|
104
|
+
if (L == 0) return {};
|
|
105
|
+
// Exit early if any entry is empty
|
|
106
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
107
|
+
if (in[i].size() == 0) return {};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
size_t* state = new size_t[L];
|
|
111
|
+
sass::vector<sass::vector<T>> out;
|
|
112
|
+
|
|
113
|
+
// First initialize all states for every permutation group
|
|
114
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
115
|
+
state[i] = in[i].size() - 1;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
while (true) {
|
|
119
|
+
/*
|
|
120
|
+
// std::cerr << "PERM: ";
|
|
121
|
+
for (size_t p = 0; p < L; p++)
|
|
122
|
+
{ // std::cerr << state[p] << " "; }
|
|
123
|
+
// std::cerr << "\n";
|
|
124
|
+
*/
|
|
125
|
+
sass::vector<T> perm;
|
|
126
|
+
// Create one permutation for state
|
|
127
|
+
for (size_t i = 0; i < L; i += 1) {
|
|
128
|
+
perm.push_back(in.at(i).at(in[i].size() - state[i] - 1));
|
|
129
|
+
}
|
|
130
|
+
// Current group finished
|
|
131
|
+
if (state[n] == 0) {
|
|
132
|
+
// Find position of next decrement
|
|
133
|
+
while (n > 0 && state[--n] == 0) {}
|
|
134
|
+
|
|
135
|
+
// Check for end condition
|
|
136
|
+
if (state[n] != 0) {
|
|
137
|
+
// Decrease next on the left side
|
|
138
|
+
state[n] -= 1;
|
|
139
|
+
// Reset all counters to the right
|
|
140
|
+
for (size_t p = n + 1; p < L; p += 1) {
|
|
141
|
+
state[p] = in[p].size() - 1;
|
|
142
|
+
}
|
|
143
|
+
// Restart from end
|
|
144
|
+
n = L - 1;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
out.push_back(perm);
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
state[n] -= 1;
|
|
153
|
+
}
|
|
154
|
+
out.push_back(perm);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
delete[] state;
|
|
158
|
+
return out;
|
|
159
|
+
}
|
|
160
|
+
// EO permutateAlt
|
|
161
|
+
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
#endif
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
|
|
5
|
+
#include <iostream>
|
|
6
|
+
#include "output.hpp"
|
|
7
|
+
#include "plugins.hpp"
|
|
8
|
+
#include "util.hpp"
|
|
9
|
+
|
|
10
|
+
#ifdef _WIN32
|
|
11
|
+
#include <windows.h>
|
|
12
|
+
#else
|
|
13
|
+
#include <sys/types.h>
|
|
14
|
+
#include <dirent.h>
|
|
15
|
+
#include <errno.h>
|
|
16
|
+
#include <dlfcn.h>
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
namespace Sass {
|
|
20
|
+
|
|
21
|
+
Plugins::Plugins(void) { }
|
|
22
|
+
Plugins::~Plugins(void)
|
|
23
|
+
{
|
|
24
|
+
for (auto function : functions) {
|
|
25
|
+
sass_delete_function(function);
|
|
26
|
+
}
|
|
27
|
+
for (auto importer : importers) {
|
|
28
|
+
sass_delete_importer(importer);
|
|
29
|
+
}
|
|
30
|
+
for (auto header : headers) {
|
|
31
|
+
sass_delete_importer(header);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// check if plugin is compatible with this version
|
|
36
|
+
// plugins may be linked static against libsass
|
|
37
|
+
// we try to be compatible between major versions
|
|
38
|
+
inline bool compatibility(const char* their_version)
|
|
39
|
+
{
|
|
40
|
+
// const char* their_version = "3.1.2";
|
|
41
|
+
// first check if anyone has an unknown version
|
|
42
|
+
const char* our_version = libsass_version();
|
|
43
|
+
if (!strcmp(their_version, "[na]")) return false;
|
|
44
|
+
if (!strcmp(our_version, "[na]")) return false;
|
|
45
|
+
|
|
46
|
+
// find the position of the second dot
|
|
47
|
+
size_t pos = sass::string(our_version).find('.', 0);
|
|
48
|
+
if (pos != sass::string::npos) pos = sass::string(our_version).find('.', pos + 1);
|
|
49
|
+
|
|
50
|
+
// if we do not have two dots we fallback to compare complete string
|
|
51
|
+
if (pos == sass::string::npos) { return strcmp(their_version, our_version) ? 0 : 1; }
|
|
52
|
+
// otherwise only compare up to the second dot (major versions)
|
|
53
|
+
else { return strncmp(their_version, our_version, pos) ? 0 : 1; }
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// load one specific plugin
|
|
58
|
+
bool Plugins::load_plugin (const sass::string& path)
|
|
59
|
+
{
|
|
60
|
+
|
|
61
|
+
typedef const char* (*__plugin_version__)(void);
|
|
62
|
+
typedef Sass_Function_List (*__plugin_load_fns__)(void);
|
|
63
|
+
typedef Sass_Importer_List (*__plugin_load_imps__)(void);
|
|
64
|
+
|
|
65
|
+
if (LOAD_LIB(plugin, path))
|
|
66
|
+
{
|
|
67
|
+
// try to load initial function to query libsass version suppor
|
|
68
|
+
if (LOAD_LIB_FN(__plugin_version__, plugin_version, "libsass_get_version"))
|
|
69
|
+
{
|
|
70
|
+
// get the libsass version of the plugin
|
|
71
|
+
if (!compatibility(plugin_version())) return false;
|
|
72
|
+
// try to get import address for "libsass_load_functions"
|
|
73
|
+
if (LOAD_LIB_FN(__plugin_load_fns__, plugin_load_functions, "libsass_load_functions"))
|
|
74
|
+
{
|
|
75
|
+
Sass_Function_List fns = plugin_load_functions(), _p = fns;
|
|
76
|
+
while (fns && *fns) { functions.push_back(*fns); ++ fns; }
|
|
77
|
+
sass_free_memory(_p); // only delete the container, items not yet
|
|
78
|
+
}
|
|
79
|
+
// try to get import address for "libsass_load_importers"
|
|
80
|
+
if (LOAD_LIB_FN(__plugin_load_imps__, plugin_load_importers, "libsass_load_importers"))
|
|
81
|
+
{
|
|
82
|
+
Sass_Importer_List imps = plugin_load_importers(), _p = imps;
|
|
83
|
+
while (imps && *imps) { importers.push_back(*imps); ++ imps; }
|
|
84
|
+
sass_free_memory(_p); // only delete the container, items not yet
|
|
85
|
+
}
|
|
86
|
+
// try to get import address for "libsass_load_headers"
|
|
87
|
+
if (LOAD_LIB_FN(__plugin_load_imps__, plugin_load_headers, "libsass_load_headers"))
|
|
88
|
+
{
|
|
89
|
+
Sass_Importer_List imps = plugin_load_headers(), _p = imps;
|
|
90
|
+
while (imps && *imps) { headers.push_back(*imps); ++ imps; }
|
|
91
|
+
sass_free_memory(_p); // only delete the container, items not yet
|
|
92
|
+
}
|
|
93
|
+
// success
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
else
|
|
97
|
+
{
|
|
98
|
+
// print debug message to stderr (should not happen)
|
|
99
|
+
std::cerr << "failed loading 'libsass_support' in <" << path << ">" << std::endl;
|
|
100
|
+
if (const char* dlsym_error = dlerror()) std::cerr << dlsym_error << std::endl;
|
|
101
|
+
CLOSE_LIB(plugin);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else
|
|
105
|
+
{
|
|
106
|
+
// print debug message to stderr (should not happen)
|
|
107
|
+
std::cerr << "failed loading plugin <" << path << ">" << std::endl;
|
|
108
|
+
if (const char* dlopen_error = dlerror()) std::cerr << dlopen_error << std::endl;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return false;
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
size_t Plugins::load_plugins(const sass::string& path)
|
|
116
|
+
{
|
|
117
|
+
|
|
118
|
+
// count plugins
|
|
119
|
+
size_t loaded = 0;
|
|
120
|
+
|
|
121
|
+
#ifdef _WIN32
|
|
122
|
+
|
|
123
|
+
try
|
|
124
|
+
{
|
|
125
|
+
|
|
126
|
+
// use wchar (utf16)
|
|
127
|
+
WIN32_FIND_DATAW data;
|
|
128
|
+
// trailing slash is guaranteed
|
|
129
|
+
sass::string globsrch(path + "*.dll");
|
|
130
|
+
// convert to wide chars (utf16) for system call
|
|
131
|
+
std::wstring wglobsrch(UTF_8::convert_to_utf16(globsrch));
|
|
132
|
+
HANDLE hFile = FindFirstFileW(wglobsrch.c_str(), &data);
|
|
133
|
+
// check if system called returned a result
|
|
134
|
+
// ToDo: maybe we should print a debug message
|
|
135
|
+
if (hFile == INVALID_HANDLE_VALUE) return -1;
|
|
136
|
+
|
|
137
|
+
// read directory
|
|
138
|
+
while (true)
|
|
139
|
+
{
|
|
140
|
+
try
|
|
141
|
+
{
|
|
142
|
+
// the system will report the filenames with wide chars (utf16)
|
|
143
|
+
sass::string entry = UTF_8::convert_from_utf16(data.cFileName);
|
|
144
|
+
// check if file ending matches exactly
|
|
145
|
+
if (!ends_with(entry, ".dll")) continue;
|
|
146
|
+
// load the plugin and increase counter
|
|
147
|
+
if (load_plugin(path + entry)) ++ loaded;
|
|
148
|
+
// check if there should be more entries
|
|
149
|
+
if (GetLastError() == ERROR_NO_MORE_FILES) break;
|
|
150
|
+
// load next entry (check for return type)
|
|
151
|
+
if (!FindNextFileW(hFile, &data)) break;
|
|
152
|
+
}
|
|
153
|
+
catch (...)
|
|
154
|
+
{
|
|
155
|
+
// report the error to the console (should not happen)
|
|
156
|
+
// seems like we got strange data from the system call?
|
|
157
|
+
std::cerr << "filename in plugin path has invalid utf8?" << std::endl;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (utf8::invalid_utf8&)
|
|
162
|
+
{
|
|
163
|
+
// report the error to the console (should not happen)
|
|
164
|
+
// implementors should make sure to provide valid utf8
|
|
165
|
+
std::cerr << "plugin path contains invalid utf8" << std::endl;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
#else
|
|
169
|
+
|
|
170
|
+
DIR *dp;
|
|
171
|
+
struct dirent *dirp;
|
|
172
|
+
if((dp = opendir(path.c_str())) == NULL) return -1;
|
|
173
|
+
while ((dirp = readdir(dp)) != NULL) {
|
|
174
|
+
#if __APPLE__
|
|
175
|
+
if (!ends_with(dirp->d_name, ".dylib")) continue;
|
|
176
|
+
#else
|
|
177
|
+
if (!ends_with(dirp->d_name, ".so")) continue;
|
|
178
|
+
#endif
|
|
179
|
+
if (load_plugin(path + dirp->d_name)) ++ loaded;
|
|
180
|
+
}
|
|
181
|
+
closedir(dp);
|
|
182
|
+
|
|
183
|
+
#endif
|
|
184
|
+
return loaded;
|
|
185
|
+
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#ifndef SASS_PLUGINS_H
|
|
2
|
+
#define SASS_PLUGINS_H
|
|
3
|
+
|
|
4
|
+
#include <string>
|
|
5
|
+
#include <vector>
|
|
6
|
+
#include "utf8_string.hpp"
|
|
7
|
+
#include "sass/functions.h"
|
|
8
|
+
|
|
9
|
+
#ifdef _WIN32
|
|
10
|
+
|
|
11
|
+
#define LOAD_LIB(var, path) HMODULE var = LoadLibraryW(UTF_8::convert_to_utf16(path).c_str())
|
|
12
|
+
#define LOAD_LIB_WCHR(var, path_wide_str) HMODULE var = LoadLibraryW(path_wide_str.c_str())
|
|
13
|
+
#define LOAD_LIB_FN(type, var, name) type var = (type) GetProcAddress(plugin, name)
|
|
14
|
+
#define CLOSE_LIB(var) FreeLibrary(var)
|
|
15
|
+
|
|
16
|
+
#ifndef dlerror
|
|
17
|
+
#define dlerror() 0
|
|
18
|
+
#endif
|
|
19
|
+
|
|
20
|
+
#else
|
|
21
|
+
|
|
22
|
+
#define LOAD_LIB(var, path) void* var = dlopen(path.c_str(), RTLD_LAZY)
|
|
23
|
+
#define LOAD_LIB_FN(type, var, name) type var = (type) dlsym(plugin, name)
|
|
24
|
+
#define CLOSE_LIB(var) dlclose(var)
|
|
25
|
+
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
namespace Sass {
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Plugins {
|
|
32
|
+
|
|
33
|
+
public: // c-tor
|
|
34
|
+
Plugins(void);
|
|
35
|
+
~Plugins(void);
|
|
36
|
+
|
|
37
|
+
public: // methods
|
|
38
|
+
// load one specific plugin
|
|
39
|
+
bool load_plugin(const sass::string& path);
|
|
40
|
+
// load all plugins from a directory
|
|
41
|
+
size_t load_plugins(const sass::string& path);
|
|
42
|
+
|
|
43
|
+
public: // public accessors
|
|
44
|
+
const sass::vector<Sass_Importer_Entry> get_headers(void) { return headers; }
|
|
45
|
+
const sass::vector<Sass_Importer_Entry> get_importers(void) { return importers; }
|
|
46
|
+
const sass::vector<Sass_Function_Entry> get_functions(void) { return functions; }
|
|
47
|
+
|
|
48
|
+
private: // private vars
|
|
49
|
+
sass::vector<Sass_Importer_Entry> headers;
|
|
50
|
+
sass::vector<Sass_Importer_Entry> importers;
|
|
51
|
+
sass::vector<Sass_Function_Entry> functions;
|
|
52
|
+
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#endif
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
|
|
5
|
+
#include "position.hpp"
|
|
6
|
+
#include "source.hpp"
|
|
7
|
+
|
|
8
|
+
namespace Sass {
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
Offset::Offset(const char chr)
|
|
12
|
+
: line(chr == '\n' ? 1 : 0),
|
|
13
|
+
column(chr == '\n' ? 0 : 1)
|
|
14
|
+
{}
|
|
15
|
+
|
|
16
|
+
Offset::Offset(const char* string)
|
|
17
|
+
: line(0), column(0)
|
|
18
|
+
{
|
|
19
|
+
*this = inc(string, string + strlen(string));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Offset::Offset(const sass::string& text)
|
|
23
|
+
: line(0), column(0)
|
|
24
|
+
{
|
|
25
|
+
*this = inc(text.c_str(), text.c_str() + text.size());
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
Offset::Offset(const size_t line, const size_t column)
|
|
29
|
+
: line(line), column(column) { }
|
|
30
|
+
|
|
31
|
+
// init/create instance from const char substring
|
|
32
|
+
Offset Offset::init(const char* beg, const char* end)
|
|
33
|
+
{
|
|
34
|
+
Offset offset(0, 0);
|
|
35
|
+
if (end == 0) {
|
|
36
|
+
end = beg + strlen(beg);
|
|
37
|
+
}
|
|
38
|
+
offset.add(beg, end);
|
|
39
|
+
return offset;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// increase offset by given string (mostly called by lexer)
|
|
43
|
+
// increase line counter and count columns on the last line
|
|
44
|
+
Offset Offset::add(const char* begin, const char* end)
|
|
45
|
+
{
|
|
46
|
+
if (end == 0) return *this;
|
|
47
|
+
while (begin < end && *begin) {
|
|
48
|
+
if (*begin == '\n') {
|
|
49
|
+
++ line;
|
|
50
|
+
// start new line
|
|
51
|
+
column = 0;
|
|
52
|
+
} else {
|
|
53
|
+
// do not count any utf8 continuation bytes
|
|
54
|
+
// https://stackoverflow.com/a/9356203/1550314
|
|
55
|
+
// https://en.wikipedia.org/wiki/UTF-8#Description
|
|
56
|
+
unsigned char chr = *begin;
|
|
57
|
+
// Ignore all `10xxxxxx` chars
|
|
58
|
+
// '0xxxxxxx' are ASCII chars
|
|
59
|
+
// '11xxxxxx' are utf8 starts
|
|
60
|
+
// 64 => initial utf8 byte
|
|
61
|
+
// 128 => regular ASCII char
|
|
62
|
+
if ((chr & 192) != 128) {
|
|
63
|
+
// regular ASCII char
|
|
64
|
+
column += 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
++ begin;
|
|
68
|
+
}
|
|
69
|
+
return *this;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// increase offset by given string (mostly called by lexer)
|
|
73
|
+
// increase line counter and count columns on the last line
|
|
74
|
+
Offset Offset::inc(const char* begin, const char* end) const
|
|
75
|
+
{
|
|
76
|
+
Offset offset(line, column);
|
|
77
|
+
offset.add(begin, end);
|
|
78
|
+
return offset;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
bool Offset::operator== (const Offset &pos) const
|
|
82
|
+
{
|
|
83
|
+
return line == pos.line && column == pos.column;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
bool Offset::operator!= (const Offset &pos) const
|
|
87
|
+
{
|
|
88
|
+
return line != pos.line || column != pos.column;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
void Offset::operator+= (const Offset &off)
|
|
92
|
+
{
|
|
93
|
+
*this = Offset(line + off.line, off.line > 0 ? off.column : column + off.column);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
Offset Offset::operator+ (const Offset &off) const
|
|
97
|
+
{
|
|
98
|
+
return Offset(line + off.line, off.line > 0 ? off.column : column + off.column);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Offset Offset::operator- (const Offset &off) const
|
|
102
|
+
{
|
|
103
|
+
return Offset(line - off.line, off.line == line ? column - off.column : column);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Position::Position(const size_t file)
|
|
107
|
+
: Offset(0, 0), file(file) { }
|
|
108
|
+
|
|
109
|
+
Position::Position(const size_t file, const Offset& offset)
|
|
110
|
+
: Offset(offset), file(file) { }
|
|
111
|
+
|
|
112
|
+
Position::Position(const size_t line, const size_t column)
|
|
113
|
+
: Offset(line, column), file(-1) { }
|
|
114
|
+
|
|
115
|
+
Position::Position(const size_t file, const size_t line, const size_t column)
|
|
116
|
+
: Offset(line, column), file(file) { }
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
SourceSpan::SourceSpan(const char* path)
|
|
120
|
+
: source(SASS_MEMORY_NEW(SynthFile, path)), position(0, 0), offset(0, 0) { }
|
|
121
|
+
|
|
122
|
+
SourceSpan::SourceSpan(SourceDataObj source, const Offset& position, const Offset& offset)
|
|
123
|
+
: source(source), position(position), offset(offset) { }
|
|
124
|
+
|
|
125
|
+
Position Position::add(const char* begin, const char* end)
|
|
126
|
+
{
|
|
127
|
+
Offset::add(begin, end);
|
|
128
|
+
return *this;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
Position Position::inc(const char* begin, const char* end) const
|
|
132
|
+
{
|
|
133
|
+
Offset offset(line, column);
|
|
134
|
+
offset = offset.inc(begin, end);
|
|
135
|
+
return Position(file, offset);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
bool Position::operator== (const Position &pos) const
|
|
139
|
+
{
|
|
140
|
+
return file == pos.file && line == pos.line && column == pos.column;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
bool Position::operator!= (const Position &pos) const
|
|
144
|
+
{
|
|
145
|
+
return file == pos.file || line != pos.line || column != pos.column;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
void Position::operator+= (const Offset &off)
|
|
149
|
+
{
|
|
150
|
+
*this = Position(file, line + off.line, off.line > 0 ? off.column : column + off.column);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const Position Position::operator+ (const Offset &off) const
|
|
154
|
+
{
|
|
155
|
+
return Position(file, line + off.line, off.line > 0 ? off.column : column + off.column);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const Offset Position::operator- (const Offset &off) const
|
|
159
|
+
{
|
|
160
|
+
return Offset(line - off.line, off.line == line ? column - off.column : column);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
}
|