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,742 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
#include "ast.hpp"
|
|
5
|
+
|
|
6
|
+
#include "sass_functions.hpp"
|
|
7
|
+
#include "json.hpp"
|
|
8
|
+
|
|
9
|
+
#define LFEED "\n"
|
|
10
|
+
|
|
11
|
+
// C++ helper
|
|
12
|
+
namespace Sass {
|
|
13
|
+
// see sass_copy_c_string(sass::string str)
|
|
14
|
+
static inline JsonNode* json_mkstream(const sass::ostream& stream)
|
|
15
|
+
{
|
|
16
|
+
// hold on to string on stack!
|
|
17
|
+
sass::string str(stream.str());
|
|
18
|
+
return json_mkstring(str.c_str());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static void handle_string_error(Sass_Context* c_ctx, const sass::string& msg, int severety)
|
|
22
|
+
{
|
|
23
|
+
sass::ostream msg_stream;
|
|
24
|
+
JsonNode* json_err = json_mkobject();
|
|
25
|
+
msg_stream << "Internal Error: " << msg << std::endl;
|
|
26
|
+
json_append_member(json_err, "status", json_mknumber(severety));
|
|
27
|
+
json_append_member(json_err, "message", json_mkstring(msg.c_str()));
|
|
28
|
+
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
|
29
|
+
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
|
30
|
+
catch (...) {}
|
|
31
|
+
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
|
32
|
+
c_ctx->error_text = sass_copy_c_string(msg.c_str());
|
|
33
|
+
c_ctx->error_status = severety;
|
|
34
|
+
c_ctx->output_string = 0;
|
|
35
|
+
c_ctx->source_map_string = 0;
|
|
36
|
+
json_delete(json_err);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static int handle_error(Sass_Context* c_ctx) {
|
|
40
|
+
try {
|
|
41
|
+
throw;
|
|
42
|
+
}
|
|
43
|
+
catch (Exception::Base& e) {
|
|
44
|
+
sass::ostream msg_stream;
|
|
45
|
+
sass::string cwd(Sass::File::get_cwd());
|
|
46
|
+
sass::string msg_prefix(e.errtype());
|
|
47
|
+
bool got_newline = false;
|
|
48
|
+
msg_stream << msg_prefix << ": ";
|
|
49
|
+
const char* msg = e.what();
|
|
50
|
+
while (msg && *msg) {
|
|
51
|
+
if (*msg == '\r') {
|
|
52
|
+
got_newline = true;
|
|
53
|
+
}
|
|
54
|
+
else if (*msg == '\n') {
|
|
55
|
+
got_newline = true;
|
|
56
|
+
}
|
|
57
|
+
else if (got_newline) {
|
|
58
|
+
msg_stream << sass::string(msg_prefix.size() + 2, ' ');
|
|
59
|
+
got_newline = false;
|
|
60
|
+
}
|
|
61
|
+
msg_stream << *msg;
|
|
62
|
+
++msg;
|
|
63
|
+
}
|
|
64
|
+
if (!got_newline) msg_stream << "\n";
|
|
65
|
+
|
|
66
|
+
if (e.traces.empty()) {
|
|
67
|
+
// we normally should have some traces, still here as a fallback
|
|
68
|
+
sass::string rel_path(Sass::File::abs2rel(e.pstate.getPath(), cwd, cwd));
|
|
69
|
+
msg_stream << sass::string(msg_prefix.size() + 2, ' ');
|
|
70
|
+
msg_stream << " on line " << e.pstate.getLine() << " of " << rel_path << "\n";
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
sass::string rel_path(Sass::File::abs2rel(e.pstate.getPath(), cwd, cwd));
|
|
74
|
+
msg_stream << traces_to_string(e.traces, " ");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// now create the code trace (ToDo: maybe have util functions?)
|
|
78
|
+
if (e.pstate.position.line != sass::string::npos &&
|
|
79
|
+
e.pstate.position.column != sass::string::npos &&
|
|
80
|
+
e.pstate.getRawData() != nullptr &&
|
|
81
|
+
e.pstate.source != nullptr) {
|
|
82
|
+
Offset offset(e.pstate.position);
|
|
83
|
+
size_t lines = offset.line;
|
|
84
|
+
// scan through src until target line
|
|
85
|
+
// move line_beg pointer to line start
|
|
86
|
+
const char* line_beg;
|
|
87
|
+
for (line_beg = e.pstate.getRawData(); *line_beg != '\0'; ++line_beg) {
|
|
88
|
+
if (lines == 0) break;
|
|
89
|
+
if (*line_beg == '\n') --lines;
|
|
90
|
+
}
|
|
91
|
+
// move line_end before next newline character
|
|
92
|
+
const char* line_end;
|
|
93
|
+
for (line_end = line_beg; *line_end != '\0'; ++line_end) {
|
|
94
|
+
if (*line_end == '\n' || *line_end == '\r') break;
|
|
95
|
+
}
|
|
96
|
+
if (*line_end != '\0') ++line_end;
|
|
97
|
+
size_t line_len = line_end - line_beg;
|
|
98
|
+
size_t move_in = 0; size_t shorten = 0;
|
|
99
|
+
size_t left_chars = 42; size_t max_chars = 76;
|
|
100
|
+
// reported excerpt should not exceed `max_chars` chars
|
|
101
|
+
if (offset.column > line_len) left_chars = offset.column;
|
|
102
|
+
if (offset.column > left_chars) move_in = offset.column - left_chars;
|
|
103
|
+
if (line_len > max_chars + move_in) shorten = line_len - move_in - max_chars;
|
|
104
|
+
utf8::advance(line_beg, move_in, line_end);
|
|
105
|
+
utf8::retreat(line_end, shorten, line_beg);
|
|
106
|
+
sass::string sanitized; sass::string marker(offset.column - move_in, '-');
|
|
107
|
+
utf8::replace_invalid(line_beg, line_end, std::back_inserter(sanitized));
|
|
108
|
+
msg_stream << ">> " << sanitized << "\n";
|
|
109
|
+
msg_stream << " " << marker << "^\n";
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
JsonNode* json_err = json_mkobject();
|
|
113
|
+
json_append_member(json_err, "status", json_mknumber(1));
|
|
114
|
+
json_append_member(json_err, "file", json_mkstring(e.pstate.getPath()));
|
|
115
|
+
json_append_member(json_err, "line", json_mknumber((double)(e.pstate.getLine())));
|
|
116
|
+
json_append_member(json_err, "column", json_mknumber((double)(e.pstate.getColumn())));
|
|
117
|
+
json_append_member(json_err, "message", json_mkstring(e.what()));
|
|
118
|
+
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
|
119
|
+
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
|
120
|
+
catch (...) {} // silently ignore this error?
|
|
121
|
+
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
|
122
|
+
c_ctx->error_text = sass_copy_c_string(e.what());
|
|
123
|
+
c_ctx->error_status = 1;
|
|
124
|
+
c_ctx->error_file = sass_copy_c_string(e.pstate.getPath());
|
|
125
|
+
c_ctx->error_line = e.pstate.getLine();
|
|
126
|
+
c_ctx->error_column = e.pstate.getColumn();
|
|
127
|
+
c_ctx->error_src = sass_copy_c_string(e.pstate.getRawData());
|
|
128
|
+
c_ctx->output_string = 0;
|
|
129
|
+
c_ctx->source_map_string = 0;
|
|
130
|
+
json_delete(json_err);
|
|
131
|
+
}
|
|
132
|
+
catch (std::bad_alloc& ba) {
|
|
133
|
+
sass::ostream msg_stream;
|
|
134
|
+
msg_stream << "Unable to allocate memory: " << ba.what();
|
|
135
|
+
handle_string_error(c_ctx, msg_stream.str(), 2);
|
|
136
|
+
}
|
|
137
|
+
catch (std::exception& e) {
|
|
138
|
+
handle_string_error(c_ctx, e.what(), 3);
|
|
139
|
+
}
|
|
140
|
+
catch (sass::string& e) {
|
|
141
|
+
handle_string_error(c_ctx, e, 4);
|
|
142
|
+
}
|
|
143
|
+
catch (const char* e) {
|
|
144
|
+
handle_string_error(c_ctx, e, 4);
|
|
145
|
+
}
|
|
146
|
+
catch (...) {
|
|
147
|
+
handle_string_error(c_ctx, "unknown", 5);
|
|
148
|
+
}
|
|
149
|
+
return c_ctx->error_status;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// allow one error handler to throw another error
|
|
153
|
+
// this can happen with invalid utf8 and json lib
|
|
154
|
+
static int handle_errors(Sass_Context* c_ctx) {
|
|
155
|
+
try { return handle_error(c_ctx); }
|
|
156
|
+
catch (...) { return handle_error(c_ctx); }
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static Block_Obj sass_parse_block(Sass_Compiler* compiler) throw()
|
|
160
|
+
{
|
|
161
|
+
|
|
162
|
+
// assert valid pointer
|
|
163
|
+
if (compiler == 0) return {};
|
|
164
|
+
// The cpp context must be set by now
|
|
165
|
+
Context* cpp_ctx = compiler->cpp_ctx;
|
|
166
|
+
Sass_Context* c_ctx = compiler->c_ctx;
|
|
167
|
+
// We will take care to wire up the rest
|
|
168
|
+
compiler->cpp_ctx->c_compiler = compiler;
|
|
169
|
+
compiler->state = SASS_COMPILER_PARSED;
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
|
|
173
|
+
// get input/output path from options
|
|
174
|
+
sass::string input_path = safe_str(c_ctx->input_path);
|
|
175
|
+
sass::string output_path = safe_str(c_ctx->output_path);
|
|
176
|
+
|
|
177
|
+
// maybe skip some entries of included files
|
|
178
|
+
// we do not include stdin for data contexts
|
|
179
|
+
bool skip = c_ctx->type == SASS_CONTEXT_DATA;
|
|
180
|
+
|
|
181
|
+
// dispatch parse call
|
|
182
|
+
Block_Obj root(cpp_ctx->parse());
|
|
183
|
+
// abort on errors
|
|
184
|
+
if (!root) return {};
|
|
185
|
+
|
|
186
|
+
// skip all prefixed files? (ToDo: check srcmap)
|
|
187
|
+
// IMO source-maps should point to headers already
|
|
188
|
+
// therefore don't skip it for now. re-enable or
|
|
189
|
+
// remove completely once this is tested
|
|
190
|
+
size_t headers = cpp_ctx->head_imports;
|
|
191
|
+
|
|
192
|
+
// copy the included files on to the context (dont forget to free later)
|
|
193
|
+
if (copy_strings(cpp_ctx->get_included_files(skip, headers), &c_ctx->included_files) == NULL)
|
|
194
|
+
throw(std::bad_alloc());
|
|
195
|
+
|
|
196
|
+
// return parsed block
|
|
197
|
+
return root;
|
|
198
|
+
|
|
199
|
+
}
|
|
200
|
+
// pass errors to generic error handler
|
|
201
|
+
catch (...) { handle_errors(c_ctx); }
|
|
202
|
+
|
|
203
|
+
// error
|
|
204
|
+
return {};
|
|
205
|
+
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
extern "C" {
|
|
211
|
+
using namespace Sass;
|
|
212
|
+
|
|
213
|
+
static void sass_clear_options (struct Sass_Options* options);
|
|
214
|
+
static void sass_reset_options (struct Sass_Options* options);
|
|
215
|
+
static void copy_options(struct Sass_Options* to, struct Sass_Options* from) {
|
|
216
|
+
// do not overwrite ourself
|
|
217
|
+
if (to == from) return;
|
|
218
|
+
// free assigned memory
|
|
219
|
+
sass_clear_options(to);
|
|
220
|
+
// move memory
|
|
221
|
+
*to = *from;
|
|
222
|
+
// Reset pointers on source
|
|
223
|
+
sass_reset_options(from);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
#define IMPLEMENT_SASS_OPTION_ACCESSOR(type, option) \
|
|
227
|
+
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return options->option; } \
|
|
228
|
+
void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) { options->option = option; }
|
|
229
|
+
#define IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \
|
|
230
|
+
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return safe_str(options->option, def); }
|
|
231
|
+
#define IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def) \
|
|
232
|
+
void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) \
|
|
233
|
+
{ free(options->option); options->option = option || def ? sass_copy_c_string(option ? option : def) : 0; }
|
|
234
|
+
#define IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(type, option, def) \
|
|
235
|
+
IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \
|
|
236
|
+
IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def)
|
|
237
|
+
|
|
238
|
+
#define IMPLEMENT_SASS_CONTEXT_GETTER(type, option) \
|
|
239
|
+
type ADDCALL sass_context_get_##option (struct Sass_Context* ctx) { return ctx->option; }
|
|
240
|
+
#define IMPLEMENT_SASS_CONTEXT_TAKER(type, option) \
|
|
241
|
+
type sass_context_take_##option (struct Sass_Context* ctx) \
|
|
242
|
+
{ type foo = ctx->option; ctx->option = 0; return foo; }
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
// generic compilation function (not exported, use file/data compile instead)
|
|
246
|
+
static Sass_Compiler* sass_prepare_context (Sass_Context* c_ctx, Context* cpp_ctx) throw()
|
|
247
|
+
{
|
|
248
|
+
try {
|
|
249
|
+
// register our custom functions
|
|
250
|
+
if (c_ctx->c_functions) {
|
|
251
|
+
auto this_func_data = c_ctx->c_functions;
|
|
252
|
+
while (this_func_data && *this_func_data) {
|
|
253
|
+
cpp_ctx->add_c_function(*this_func_data);
|
|
254
|
+
++this_func_data;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// register our custom headers
|
|
259
|
+
if (c_ctx->c_headers) {
|
|
260
|
+
auto this_head_data = c_ctx->c_headers;
|
|
261
|
+
while (this_head_data && *this_head_data) {
|
|
262
|
+
cpp_ctx->add_c_header(*this_head_data);
|
|
263
|
+
++this_head_data;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// register our custom importers
|
|
268
|
+
if (c_ctx->c_importers) {
|
|
269
|
+
auto this_imp_data = c_ctx->c_importers;
|
|
270
|
+
while (this_imp_data && *this_imp_data) {
|
|
271
|
+
cpp_ctx->add_c_importer(*this_imp_data);
|
|
272
|
+
++this_imp_data;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// reset error status
|
|
277
|
+
c_ctx->error_json = 0;
|
|
278
|
+
c_ctx->error_text = 0;
|
|
279
|
+
c_ctx->error_message = 0;
|
|
280
|
+
c_ctx->error_status = 0;
|
|
281
|
+
// reset error position
|
|
282
|
+
c_ctx->error_file = 0;
|
|
283
|
+
c_ctx->error_src = 0;
|
|
284
|
+
c_ctx->error_line = sass::string::npos;
|
|
285
|
+
c_ctx->error_column = sass::string::npos;
|
|
286
|
+
|
|
287
|
+
// allocate a new compiler instance
|
|
288
|
+
void* ctxmem = calloc(1, sizeof(struct Sass_Compiler));
|
|
289
|
+
if (ctxmem == 0) { std::cerr << "Error allocating memory for context" << std::endl; return 0; }
|
|
290
|
+
Sass_Compiler* compiler = (struct Sass_Compiler*) ctxmem;
|
|
291
|
+
compiler->state = SASS_COMPILER_CREATED;
|
|
292
|
+
|
|
293
|
+
// store in sass compiler
|
|
294
|
+
compiler->c_ctx = c_ctx;
|
|
295
|
+
compiler->cpp_ctx = cpp_ctx;
|
|
296
|
+
cpp_ctx->c_compiler = compiler;
|
|
297
|
+
|
|
298
|
+
// use to parse block
|
|
299
|
+
return compiler;
|
|
300
|
+
|
|
301
|
+
}
|
|
302
|
+
// pass errors to generic error handler
|
|
303
|
+
catch (...) { handle_errors(c_ctx); }
|
|
304
|
+
|
|
305
|
+
// error
|
|
306
|
+
return 0;
|
|
307
|
+
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// generic compilation function (not exported, use file/data compile instead)
|
|
311
|
+
static int sass_compile_context (Sass_Context* c_ctx, Context* cpp_ctx)
|
|
312
|
+
{
|
|
313
|
+
|
|
314
|
+
// prepare sass compiler with context and options
|
|
315
|
+
Sass_Compiler* compiler = sass_prepare_context(c_ctx, cpp_ctx);
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
// call each compiler step
|
|
319
|
+
sass_compiler_parse(compiler);
|
|
320
|
+
sass_compiler_execute(compiler);
|
|
321
|
+
}
|
|
322
|
+
// pass errors to generic error handler
|
|
323
|
+
catch (...) { handle_errors(c_ctx); }
|
|
324
|
+
|
|
325
|
+
sass_delete_compiler(compiler);
|
|
326
|
+
|
|
327
|
+
return c_ctx->error_status;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
inline void init_options (struct Sass_Options* options)
|
|
331
|
+
{
|
|
332
|
+
options->precision = 10;
|
|
333
|
+
options->indent = " ";
|
|
334
|
+
options->linefeed = LFEED;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
Sass_Options* ADDCALL sass_make_options (void)
|
|
338
|
+
{
|
|
339
|
+
struct Sass_Options* options = (struct Sass_Options*) calloc(1, sizeof(struct Sass_Options));
|
|
340
|
+
if (options == 0) { std::cerr << "Error allocating memory for options" << std::endl; return 0; }
|
|
341
|
+
init_options(options);
|
|
342
|
+
return options;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
Sass_File_Context* ADDCALL sass_make_file_context(const char* input_path)
|
|
346
|
+
{
|
|
347
|
+
#ifdef DEBUG_SHARED_PTR
|
|
348
|
+
SharedObj::setTaint(true);
|
|
349
|
+
#endif
|
|
350
|
+
struct Sass_File_Context* ctx = (struct Sass_File_Context*) calloc(1, sizeof(struct Sass_File_Context));
|
|
351
|
+
if (ctx == 0) { std::cerr << "Error allocating memory for file context" << std::endl; return 0; }
|
|
352
|
+
ctx->type = SASS_CONTEXT_FILE;
|
|
353
|
+
init_options(ctx);
|
|
354
|
+
try {
|
|
355
|
+
if (input_path == 0) { throw(std::runtime_error("File context created without an input path")); }
|
|
356
|
+
if (*input_path == 0) { throw(std::runtime_error("File context created with empty input path")); }
|
|
357
|
+
sass_option_set_input_path(ctx, input_path);
|
|
358
|
+
} catch (...) {
|
|
359
|
+
handle_errors(ctx);
|
|
360
|
+
}
|
|
361
|
+
return ctx;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
Sass_Data_Context* ADDCALL sass_make_data_context(char* source_string)
|
|
365
|
+
{
|
|
366
|
+
#ifdef DEBUG_SHARED_PTR
|
|
367
|
+
SharedObj::setTaint(true);
|
|
368
|
+
#endif
|
|
369
|
+
struct Sass_Data_Context* ctx = (struct Sass_Data_Context*) calloc(1, sizeof(struct Sass_Data_Context));
|
|
370
|
+
if (ctx == 0) { std::cerr << "Error allocating memory for data context" << std::endl; return 0; }
|
|
371
|
+
ctx->type = SASS_CONTEXT_DATA;
|
|
372
|
+
init_options(ctx);
|
|
373
|
+
try {
|
|
374
|
+
if (source_string == 0) { throw(std::runtime_error("Data context created without a source string")); }
|
|
375
|
+
if (*source_string == 0) { throw(std::runtime_error("Data context created with empty source string")); }
|
|
376
|
+
ctx->source_string = source_string;
|
|
377
|
+
} catch (...) {
|
|
378
|
+
handle_errors(ctx);
|
|
379
|
+
}
|
|
380
|
+
return ctx;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx)
|
|
384
|
+
{
|
|
385
|
+
if (data_ctx == 0) return 0;
|
|
386
|
+
Context* cpp_ctx = new Data_Context(*data_ctx);
|
|
387
|
+
return sass_prepare_context(data_ctx, cpp_ctx);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_Context* file_ctx)
|
|
391
|
+
{
|
|
392
|
+
if (file_ctx == 0) return 0;
|
|
393
|
+
Context* cpp_ctx = new File_Context(*file_ctx);
|
|
394
|
+
return sass_prepare_context(file_ctx, cpp_ctx);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
int ADDCALL sass_compile_data_context(Sass_Data_Context* data_ctx)
|
|
398
|
+
{
|
|
399
|
+
if (data_ctx == 0) return 1;
|
|
400
|
+
if (data_ctx->error_status)
|
|
401
|
+
return data_ctx->error_status;
|
|
402
|
+
try {
|
|
403
|
+
if (data_ctx->source_string == 0) { throw(std::runtime_error("Data context has no source string")); }
|
|
404
|
+
// empty source string is a valid case, even if not really useful (different than with file context)
|
|
405
|
+
// if (*data_ctx->source_string == 0) { throw(std::runtime_error("Data context has empty source string")); }
|
|
406
|
+
}
|
|
407
|
+
catch (...) { return handle_errors(data_ctx) | 1; }
|
|
408
|
+
Context* cpp_ctx = new Data_Context(*data_ctx);
|
|
409
|
+
return sass_compile_context(data_ctx, cpp_ctx);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
int ADDCALL sass_compile_file_context(Sass_File_Context* file_ctx)
|
|
413
|
+
{
|
|
414
|
+
if (file_ctx == 0) return 1;
|
|
415
|
+
if (file_ctx->error_status)
|
|
416
|
+
return file_ctx->error_status;
|
|
417
|
+
try {
|
|
418
|
+
if (file_ctx->input_path == 0) { throw(std::runtime_error("File context has no input path")); }
|
|
419
|
+
if (*file_ctx->input_path == 0) { throw(std::runtime_error("File context has empty input path")); }
|
|
420
|
+
}
|
|
421
|
+
catch (...) { return handle_errors(file_ctx) | 1; }
|
|
422
|
+
Context* cpp_ctx = new File_Context(*file_ctx);
|
|
423
|
+
return sass_compile_context(file_ctx, cpp_ctx);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
int ADDCALL sass_compiler_parse(struct Sass_Compiler* compiler)
|
|
427
|
+
{
|
|
428
|
+
if (compiler == 0) return 1;
|
|
429
|
+
if (compiler->state == SASS_COMPILER_PARSED) return 0;
|
|
430
|
+
if (compiler->state != SASS_COMPILER_CREATED) return -1;
|
|
431
|
+
if (compiler->c_ctx == NULL) return 1;
|
|
432
|
+
if (compiler->cpp_ctx == NULL) return 1;
|
|
433
|
+
if (compiler->c_ctx->error_status)
|
|
434
|
+
return compiler->c_ctx->error_status;
|
|
435
|
+
// parse the context we have set up (file or data)
|
|
436
|
+
compiler->root = sass_parse_block(compiler);
|
|
437
|
+
// success
|
|
438
|
+
return 0;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler)
|
|
442
|
+
{
|
|
443
|
+
if (compiler == 0) return 1;
|
|
444
|
+
if (compiler->state == SASS_COMPILER_EXECUTED) return 0;
|
|
445
|
+
if (compiler->state != SASS_COMPILER_PARSED) return -1;
|
|
446
|
+
if (compiler->c_ctx == NULL) return 1;
|
|
447
|
+
if (compiler->cpp_ctx == NULL) return 1;
|
|
448
|
+
if (compiler->root.isNull()) return 1;
|
|
449
|
+
if (compiler->c_ctx->error_status)
|
|
450
|
+
return compiler->c_ctx->error_status;
|
|
451
|
+
compiler->state = SASS_COMPILER_EXECUTED;
|
|
452
|
+
Context* cpp_ctx = compiler->cpp_ctx;
|
|
453
|
+
Block_Obj root = compiler->root;
|
|
454
|
+
// compile the parsed root block
|
|
455
|
+
try { compiler->c_ctx->output_string = cpp_ctx->render(root); }
|
|
456
|
+
// pass catched errors to generic error handler
|
|
457
|
+
catch (...) { return handle_errors(compiler->c_ctx) | 1; }
|
|
458
|
+
// generate source map json and store on context
|
|
459
|
+
compiler->c_ctx->source_map_string = cpp_ctx->render_srcmap();
|
|
460
|
+
// success
|
|
461
|
+
return 0;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// helper function, not exported, only accessible locally
|
|
465
|
+
static void sass_reset_options (struct Sass_Options* options)
|
|
466
|
+
{
|
|
467
|
+
// free pointer before
|
|
468
|
+
// or copy/move them
|
|
469
|
+
options->input_path = 0;
|
|
470
|
+
options->output_path = 0;
|
|
471
|
+
options->plugin_path = 0;
|
|
472
|
+
options->include_path = 0;
|
|
473
|
+
options->source_map_file = 0;
|
|
474
|
+
options->source_map_root = 0;
|
|
475
|
+
options->c_functions = 0;
|
|
476
|
+
options->c_importers = 0;
|
|
477
|
+
options->c_headers = 0;
|
|
478
|
+
options->plugin_paths = 0;
|
|
479
|
+
options->include_paths = 0;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// helper function, not exported, only accessible locally
|
|
483
|
+
static void sass_clear_options (struct Sass_Options* options)
|
|
484
|
+
{
|
|
485
|
+
if (options == 0) return;
|
|
486
|
+
// Deallocate custom functions, headers and imports
|
|
487
|
+
sass_delete_function_list(options->c_functions);
|
|
488
|
+
sass_delete_importer_list(options->c_importers);
|
|
489
|
+
sass_delete_importer_list(options->c_headers);
|
|
490
|
+
// Deallocate inc paths
|
|
491
|
+
if (options->plugin_paths) {
|
|
492
|
+
struct string_list* cur;
|
|
493
|
+
struct string_list* next;
|
|
494
|
+
cur = options->plugin_paths;
|
|
495
|
+
while (cur) {
|
|
496
|
+
next = cur->next;
|
|
497
|
+
free(cur->string);
|
|
498
|
+
free(cur);
|
|
499
|
+
cur = next;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
// Deallocate inc paths
|
|
503
|
+
if (options->include_paths) {
|
|
504
|
+
struct string_list* cur;
|
|
505
|
+
struct string_list* next;
|
|
506
|
+
cur = options->include_paths;
|
|
507
|
+
while (cur) {
|
|
508
|
+
next = cur->next;
|
|
509
|
+
free(cur->string);
|
|
510
|
+
free(cur);
|
|
511
|
+
cur = next;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
// Free options strings
|
|
515
|
+
free(options->input_path);
|
|
516
|
+
free(options->output_path);
|
|
517
|
+
free(options->plugin_path);
|
|
518
|
+
free(options->include_path);
|
|
519
|
+
free(options->source_map_file);
|
|
520
|
+
free(options->source_map_root);
|
|
521
|
+
// Reset our pointers
|
|
522
|
+
options->input_path = 0;
|
|
523
|
+
options->output_path = 0;
|
|
524
|
+
options->plugin_path = 0;
|
|
525
|
+
options->include_path = 0;
|
|
526
|
+
options->source_map_file = 0;
|
|
527
|
+
options->source_map_root = 0;
|
|
528
|
+
options->c_functions = 0;
|
|
529
|
+
options->c_importers = 0;
|
|
530
|
+
options->c_headers = 0;
|
|
531
|
+
options->plugin_paths = 0;
|
|
532
|
+
options->include_paths = 0;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// helper function, not exported, only accessible locally
|
|
536
|
+
// sass_free_context is also defined in old sass_interface
|
|
537
|
+
static void sass_clear_context (struct Sass_Context* ctx)
|
|
538
|
+
{
|
|
539
|
+
if (ctx == 0) return;
|
|
540
|
+
// release the allocated memory (mostly via sass_copy_c_string)
|
|
541
|
+
if (ctx->output_string) free(ctx->output_string);
|
|
542
|
+
if (ctx->source_map_string) free(ctx->source_map_string);
|
|
543
|
+
if (ctx->error_message) free(ctx->error_message);
|
|
544
|
+
if (ctx->error_text) free(ctx->error_text);
|
|
545
|
+
if (ctx->error_json) free(ctx->error_json);
|
|
546
|
+
if (ctx->error_file) free(ctx->error_file);
|
|
547
|
+
if (ctx->error_src) free(ctx->error_src);
|
|
548
|
+
free_string_array(ctx->included_files);
|
|
549
|
+
// play safe and reset properties
|
|
550
|
+
ctx->output_string = 0;
|
|
551
|
+
ctx->source_map_string = 0;
|
|
552
|
+
ctx->error_message = 0;
|
|
553
|
+
ctx->error_text = 0;
|
|
554
|
+
ctx->error_json = 0;
|
|
555
|
+
ctx->error_file = 0;
|
|
556
|
+
ctx->error_src = 0;
|
|
557
|
+
ctx->included_files = 0;
|
|
558
|
+
// debug leaked memory
|
|
559
|
+
#ifdef DEBUG_SHARED_PTR
|
|
560
|
+
SharedObj::dumpMemLeaks();
|
|
561
|
+
#endif
|
|
562
|
+
// now clear the options
|
|
563
|
+
sass_clear_options(ctx);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
void ADDCALL sass_delete_compiler (struct Sass_Compiler* compiler)
|
|
567
|
+
{
|
|
568
|
+
if (compiler == 0) {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
Context* cpp_ctx = compiler->cpp_ctx;
|
|
572
|
+
if (cpp_ctx) delete(cpp_ctx);
|
|
573
|
+
compiler->cpp_ctx = NULL;
|
|
574
|
+
compiler->c_ctx = NULL;
|
|
575
|
+
compiler->root = {};
|
|
576
|
+
free(compiler);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
void ADDCALL sass_delete_options (struct Sass_Options* options)
|
|
580
|
+
{
|
|
581
|
+
sass_clear_options(options); free(options);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Deallocate all associated memory with file context
|
|
585
|
+
void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx)
|
|
586
|
+
{
|
|
587
|
+
// clear the context and free it
|
|
588
|
+
sass_clear_context(ctx); free(ctx);
|
|
589
|
+
}
|
|
590
|
+
// Deallocate all associated memory with data context
|
|
591
|
+
void ADDCALL sass_delete_data_context (struct Sass_Data_Context* ctx)
|
|
592
|
+
{
|
|
593
|
+
// clean the source string if it was not passed
|
|
594
|
+
// we reset this member once we start parsing
|
|
595
|
+
if (ctx->source_string) free(ctx->source_string);
|
|
596
|
+
// clear the context and free it
|
|
597
|
+
sass_clear_context(ctx); free(ctx);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Getters for sass context from specific implementations
|
|
601
|
+
struct Sass_Context* ADDCALL sass_file_context_get_context(struct Sass_File_Context* ctx) { return ctx; }
|
|
602
|
+
struct Sass_Context* ADDCALL sass_data_context_get_context(struct Sass_Data_Context* ctx) { return ctx; }
|
|
603
|
+
|
|
604
|
+
// Getters for context options from Sass_Context
|
|
605
|
+
struct Sass_Options* ADDCALL sass_context_get_options(struct Sass_Context* ctx) { return ctx; }
|
|
606
|
+
struct Sass_Options* ADDCALL sass_file_context_get_options(struct Sass_File_Context* ctx) { return ctx; }
|
|
607
|
+
struct Sass_Options* ADDCALL sass_data_context_get_options(struct Sass_Data_Context* ctx) { return ctx; }
|
|
608
|
+
void ADDCALL sass_file_context_set_options (struct Sass_File_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }
|
|
609
|
+
void ADDCALL sass_data_context_set_options (struct Sass_Data_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }
|
|
610
|
+
|
|
611
|
+
// Getters for Sass_Compiler options (get connected sass context)
|
|
612
|
+
enum Sass_Compiler_State ADDCALL sass_compiler_get_state(struct Sass_Compiler* compiler) { return compiler->state; }
|
|
613
|
+
struct Sass_Context* ADDCALL sass_compiler_get_context(struct Sass_Compiler* compiler) { return compiler->c_ctx; }
|
|
614
|
+
struct Sass_Options* ADDCALL sass_compiler_get_options(struct Sass_Compiler* compiler) { return compiler->c_ctx; }
|
|
615
|
+
// Getters for Sass_Compiler options (query import stack)
|
|
616
|
+
size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.size(); }
|
|
617
|
+
Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.back(); }
|
|
618
|
+
Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx) { return compiler->cpp_ctx->import_stack[idx]; }
|
|
619
|
+
// Getters for Sass_Compiler options (query function stack)
|
|
620
|
+
size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->callee_stack.size(); }
|
|
621
|
+
Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler) { return &compiler->cpp_ctx->callee_stack.back(); }
|
|
622
|
+
Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx) { return &compiler->cpp_ctx->callee_stack[idx]; }
|
|
623
|
+
|
|
624
|
+
// Calculate the size of the stored null terminated array
|
|
625
|
+
size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx)
|
|
626
|
+
{ size_t l = 0; auto i = ctx->included_files; while (i && *i) { ++i; ++l; } return l; }
|
|
627
|
+
|
|
628
|
+
// Create getter and setters for options
|
|
629
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(int, precision);
|
|
630
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(enum Sass_Output_Style, output_style);
|
|
631
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_comments);
|
|
632
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_embed);
|
|
633
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_contents);
|
|
634
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_file_urls);
|
|
635
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, omit_source_map_url);
|
|
636
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, is_indented_syntax_src);
|
|
637
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Function_List, c_functions);
|
|
638
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_importers);
|
|
639
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_headers);
|
|
640
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, indent);
|
|
641
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, linefeed);
|
|
642
|
+
IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, plugin_path, 0);
|
|
643
|
+
IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, include_path, 0);
|
|
644
|
+
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, input_path, 0);
|
|
645
|
+
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, output_path, 0);
|
|
646
|
+
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_file, 0);
|
|
647
|
+
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_root, 0);
|
|
648
|
+
|
|
649
|
+
// Create getter and setters for context
|
|
650
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(int, error_status);
|
|
651
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_json);
|
|
652
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_message);
|
|
653
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_text);
|
|
654
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_file);
|
|
655
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_src);
|
|
656
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_line);
|
|
657
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_column);
|
|
658
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, output_string);
|
|
659
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, source_map_string);
|
|
660
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(char**, included_files);
|
|
661
|
+
|
|
662
|
+
// Take ownership of memory (value on context is set to 0)
|
|
663
|
+
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_json);
|
|
664
|
+
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_message);
|
|
665
|
+
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_text);
|
|
666
|
+
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_file);
|
|
667
|
+
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_src);
|
|
668
|
+
IMPLEMENT_SASS_CONTEXT_TAKER(char*, output_string);
|
|
669
|
+
IMPLEMENT_SASS_CONTEXT_TAKER(char*, source_map_string);
|
|
670
|
+
IMPLEMENT_SASS_CONTEXT_TAKER(char**, included_files);
|
|
671
|
+
|
|
672
|
+
// Push function for include paths (no manipulation support for now)
|
|
673
|
+
void ADDCALL sass_option_push_include_path(struct Sass_Options* options, const char* path)
|
|
674
|
+
{
|
|
675
|
+
|
|
676
|
+
struct string_list* include_path = (struct string_list*) calloc(1, sizeof(struct string_list));
|
|
677
|
+
if (include_path == 0) return;
|
|
678
|
+
include_path->string = path ? sass_copy_c_string(path) : 0;
|
|
679
|
+
struct string_list* last = options->include_paths;
|
|
680
|
+
if (!options->include_paths) {
|
|
681
|
+
options->include_paths = include_path;
|
|
682
|
+
} else {
|
|
683
|
+
while (last->next)
|
|
684
|
+
last = last->next;
|
|
685
|
+
last->next = include_path;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// Push function for include paths (no manipulation support for now)
|
|
691
|
+
size_t ADDCALL sass_option_get_include_path_size(struct Sass_Options* options)
|
|
692
|
+
{
|
|
693
|
+
size_t len = 0;
|
|
694
|
+
struct string_list* cur = options->include_paths;
|
|
695
|
+
while (cur) { len ++; cur = cur->next; }
|
|
696
|
+
return len;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// Push function for include paths (no manipulation support for now)
|
|
700
|
+
const char* ADDCALL sass_option_get_include_path(struct Sass_Options* options, size_t i)
|
|
701
|
+
{
|
|
702
|
+
struct string_list* cur = options->include_paths;
|
|
703
|
+
while (i) { i--; cur = cur->next; }
|
|
704
|
+
return cur->string;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// Push function for plugin paths (no manipulation support for now)
|
|
708
|
+
size_t ADDCALL sass_option_get_plugin_path_size(struct Sass_Options* options)
|
|
709
|
+
{
|
|
710
|
+
size_t len = 0;
|
|
711
|
+
struct string_list* cur = options->plugin_paths;
|
|
712
|
+
while (cur) { len++; cur = cur->next; }
|
|
713
|
+
return len;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
// Push function for plugin paths (no manipulation support for now)
|
|
717
|
+
const char* ADDCALL sass_option_get_plugin_path(struct Sass_Options* options, size_t i)
|
|
718
|
+
{
|
|
719
|
+
struct string_list* cur = options->plugin_paths;
|
|
720
|
+
while (i) { i--; cur = cur->next; }
|
|
721
|
+
return cur->string;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// Push function for plugin paths (no manipulation support for now)
|
|
725
|
+
void ADDCALL sass_option_push_plugin_path(struct Sass_Options* options, const char* path)
|
|
726
|
+
{
|
|
727
|
+
|
|
728
|
+
struct string_list* plugin_path = (struct string_list*) calloc(1, sizeof(struct string_list));
|
|
729
|
+
if (plugin_path == 0) return;
|
|
730
|
+
plugin_path->string = path ? sass_copy_c_string(path) : 0;
|
|
731
|
+
struct string_list* last = options->plugin_paths;
|
|
732
|
+
if (!options->plugin_paths) {
|
|
733
|
+
options->plugin_paths = plugin_path;
|
|
734
|
+
} else {
|
|
735
|
+
while (last->next)
|
|
736
|
+
last = last->next;
|
|
737
|
+
last->next = plugin_path;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
}
|