sassc 1.11.1 → 1.11.2
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/.travis.yml +2 -2
- data/README.md +3 -2
- data/ext/libsass/Makefile.conf +2 -1
- data/ext/libsass/appveyor.yml +10 -5
- data/ext/libsass/docs/dev-ast-memory.md +223 -0
- data/ext/libsass/include/sass/base.h +2 -0
- data/ext/libsass/script/bootstrap +7 -4
- data/ext/libsass/script/ci-build-libsass +3 -3
- data/ext/libsass/script/ci-install-compiler +2 -0
- data/ext/libsass/script/ci-report-coverage +2 -1
- data/ext/libsass/script/test-leaks.pl +103 -0
- data/ext/libsass/src/ast.cpp +621 -495
- data/ext/libsass/src/ast.hpp +801 -367
- data/ext/libsass/src/ast_def_macros.hpp +5 -5
- data/ext/libsass/src/ast_fwd_decl.hpp +312 -14
- data/ext/libsass/src/bind.cpp +54 -51
- data/ext/libsass/src/bind.hpp +3 -7
- data/ext/libsass/src/check_nesting.cpp +117 -120
- data/ext/libsass/src/check_nesting.hpp +38 -34
- data/ext/libsass/src/color_maps.cpp +3 -3
- data/ext/libsass/src/color_maps.hpp +3 -3
- data/ext/libsass/src/context.cpp +33 -34
- data/ext/libsass/src/context.hpp +12 -14
- data/ext/libsass/src/cssize.cpp +200 -228
- data/ext/libsass/src/cssize.hpp +49 -49
- data/ext/libsass/src/debugger.hpp +260 -241
- data/ext/libsass/src/emitter.cpp +6 -6
- data/ext/libsass/src/emitter.hpp +7 -7
- data/ext/libsass/src/environment.cpp +2 -2
- data/ext/libsass/src/environment.hpp +0 -2
- data/ext/libsass/src/error_handling.cpp +5 -5
- data/ext/libsass/src/error_handling.hpp +12 -12
- data/ext/libsass/src/eval.cpp +412 -401
- data/ext/libsass/src/eval.hpp +61 -62
- data/ext/libsass/src/expand.cpp +223 -204
- data/ext/libsass/src/expand.hpp +42 -42
- data/ext/libsass/src/extend.cpp +198 -201
- data/ext/libsass/src/extend.hpp +12 -14
- data/ext/libsass/src/file.hpp +4 -5
- data/ext/libsass/src/functions.cpp +413 -418
- data/ext/libsass/src/functions.hpp +7 -10
- data/ext/libsass/src/inspect.cpp +115 -109
- data/ext/libsass/src/inspect.hpp +69 -69
- data/ext/libsass/src/listize.cpp +31 -33
- data/ext/libsass/src/listize.hpp +8 -10
- data/ext/libsass/src/memory/SharedPtr.cpp +116 -0
- data/ext/libsass/src/memory/SharedPtr.hpp +202 -0
- data/ext/libsass/src/node.cpp +45 -43
- data/ext/libsass/src/node.hpp +15 -15
- data/ext/libsass/src/operation.hpp +136 -136
- data/ext/libsass/src/output.cpp +48 -49
- data/ext/libsass/src/output.hpp +14 -14
- data/ext/libsass/src/parser.cpp +530 -554
- data/ext/libsass/src/parser.hpp +91 -96
- data/ext/libsass/src/prelexer.cpp +13 -10
- data/ext/libsass/src/remove_placeholders.cpp +25 -21
- data/ext/libsass/src/remove_placeholders.hpp +7 -7
- data/ext/libsass/src/sass2scss.cpp +2 -1
- data/ext/libsass/src/sass_context.cpp +125 -107
- data/ext/libsass/src/sass_context.hpp +1 -1
- data/ext/libsass/src/sass_util.hpp +5 -5
- data/ext/libsass/src/sass_values.cpp +27 -27
- data/ext/libsass/src/source_map.cpp +2 -2
- data/ext/libsass/src/source_map.hpp +2 -2
- data/ext/libsass/src/subset_map.cpp +57 -0
- data/ext/libsass/src/subset_map.hpp +8 -76
- data/ext/libsass/src/to_c.cpp +13 -13
- data/ext/libsass/src/to_c.hpp +14 -14
- data/ext/libsass/src/to_value.cpp +20 -20
- data/ext/libsass/src/to_value.hpp +20 -21
- data/ext/libsass/src/util.cpp +55 -88
- data/ext/libsass/src/util.hpp +9 -13
- data/ext/libsass/src/values.cpp +27 -26
- data/ext/libsass/src/values.hpp +2 -2
- data/ext/libsass/test/test_subset_map.cpp +69 -69
- data/ext/libsass/win/libsass.targets +3 -2
- data/ext/libsass/win/libsass.vcxproj.filters +9 -6
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +0 -1
- data/test/native_test.rb +1 -1
- metadata +7 -5
- data/ext/libsass/src/ast_factory.hpp +0 -92
- data/ext/libsass/src/memory_manager.cpp +0 -77
- data/ext/libsass/src/memory_manager.hpp +0 -48
data/ext/libsass/src/parser.hpp
CHANGED
@@ -26,9 +26,9 @@ namespace Sass {
|
|
26
26
|
enum Scope { Root, Mixin, Function, Media, Control, Properties, Rules };
|
27
27
|
|
28
28
|
Context& ctx;
|
29
|
-
std::vector<
|
29
|
+
std::vector<Block_Obj> block_stack;
|
30
30
|
std::vector<Scope> stack;
|
31
|
-
|
31
|
+
Media_Block_Ptr last_media_block;
|
32
32
|
const char* source;
|
33
33
|
const char* position;
|
34
34
|
const char* end;
|
@@ -42,7 +42,7 @@ namespace Sass {
|
|
42
42
|
bool in_at_root;
|
43
43
|
|
44
44
|
Parser(Context& ctx, const ParserState& pstate)
|
45
|
-
: ParserState(pstate), ctx(ctx), block_stack(
|
45
|
+
: ParserState(pstate), ctx(ctx), block_stack(), stack(0), last_media_block(),
|
46
46
|
source(0), position(0), end(0), before_token(pstate), after_token(pstate), pstate(pstate), indentation(0)
|
47
47
|
{ in_at_root = false; stack.push_back(Scope::Root); }
|
48
48
|
|
@@ -51,7 +51,7 @@ namespace Sass {
|
|
51
51
|
static Parser from_c_str(const char* beg, const char* end, Context& ctx, ParserState pstate = ParserState("[CSTRING]"), const char* source = 0);
|
52
52
|
static Parser from_token(Token t, Context& ctx, ParserState pstate = ParserState("[TOKEN]"), const char* source = 0);
|
53
53
|
// special static parsers to convert strings into certain selectors
|
54
|
-
static
|
54
|
+
static Selector_List_Obj parse_selector(const char* src, Context& ctx, ParserState pstate = ParserState("[SELECTOR]"), const char* source = 0);
|
55
55
|
|
56
56
|
#ifdef __clang__
|
57
57
|
|
@@ -231,93 +231,88 @@ namespace Sass {
|
|
231
231
|
const std::string& middle = ", was: ");
|
232
232
|
void read_bom();
|
233
233
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
234
|
+
Block_Obj parse();
|
235
|
+
Import_Obj parse_import();
|
236
|
+
Definition_Obj parse_definition(Definition::Type which_type);
|
237
|
+
Parameters_Obj parse_parameters();
|
238
|
+
Parameter_Obj parse_parameter();
|
239
|
+
Mixin_Call_Obj parse_include_directive();
|
240
|
+
Arguments_Obj parse_arguments();
|
241
|
+
Argument_Obj parse_argument();
|
242
|
+
Assignment_Obj parse_assignment();
|
243
|
+
Ruleset_Obj parse_ruleset(Lookahead lookahead, bool is_root = false);
|
244
|
+
Selector_Schema_Obj parse_selector_schema(const char* end_of_selector);
|
245
|
+
Selector_List_Obj parse_selector_list(bool at_root = false);
|
246
|
+
Complex_Selector_Obj parse_complex_selector(bool in_root = true);
|
247
|
+
Compound_Selector_Obj parse_compound_selector();
|
248
|
+
Simple_Selector_Obj parse_simple_selector();
|
249
|
+
Wrapped_Selector_Obj parse_negated_selector();
|
250
|
+
Simple_Selector_Obj parse_pseudo_selector();
|
251
|
+
Attribute_Selector_Obj parse_attribute_selector();
|
252
|
+
Block_Obj parse_block(bool is_root = false);
|
253
|
+
Block_Obj parse_css_block(bool is_root = false);
|
254
254
|
bool parse_block_nodes(bool is_root = false);
|
255
255
|
bool parse_block_node(bool is_root = false);
|
256
256
|
|
257
257
|
bool parse_number_prefix();
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
For* parse_for_directive();
|
289
|
-
Each* parse_each_directive();
|
290
|
-
While* parse_while_directive();
|
291
|
-
Return* parse_return_directive();
|
292
|
-
Content* parse_content_directive();
|
258
|
+
Declaration_Obj parse_declaration();
|
259
|
+
Expression_Obj parse_map();
|
260
|
+
Expression_Obj parse_list(bool delayed = false);
|
261
|
+
Expression_Obj parse_comma_list(bool delayed = false);
|
262
|
+
Expression_Obj parse_space_list();
|
263
|
+
Expression_Obj parse_disjunction();
|
264
|
+
Expression_Obj parse_conjunction();
|
265
|
+
Expression_Obj parse_relation();
|
266
|
+
Expression_Obj parse_expression();
|
267
|
+
Expression_Obj parse_operators();
|
268
|
+
Expression_Obj parse_factor();
|
269
|
+
Expression_Obj parse_value();
|
270
|
+
Function_Call_Obj parse_calc_function();
|
271
|
+
Function_Call_Obj parse_function_call();
|
272
|
+
Function_Call_Schema_Obj parse_function_call_schema();
|
273
|
+
String_Obj parse_url_function_string();
|
274
|
+
String_Obj parse_url_function_argument();
|
275
|
+
String_Obj parse_interpolated_chunk(Token, bool constant = false);
|
276
|
+
String_Obj parse_string();
|
277
|
+
String_Constant_Obj parse_static_value();
|
278
|
+
String_Obj parse_ie_property();
|
279
|
+
String_Obj parse_ie_keyword_arg();
|
280
|
+
String_Schema_Obj parse_value_schema(const char* stop);
|
281
|
+
String_Obj parse_identifier_schema();
|
282
|
+
If_Obj parse_if_directive(bool else_if = false);
|
283
|
+
For_Obj parse_for_directive();
|
284
|
+
Each_Obj parse_each_directive();
|
285
|
+
While_Obj parse_while_directive();
|
286
|
+
Return_Obj parse_return_directive();
|
287
|
+
Content_Obj parse_content_directive();
|
293
288
|
void parse_charset_directive();
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
289
|
+
Media_Block_Obj parse_media_block();
|
290
|
+
List_Obj parse_media_queries();
|
291
|
+
Media_Query_Obj parse_media_query();
|
292
|
+
Media_Query_Expression_Obj parse_media_expression();
|
293
|
+
Supports_Block_Obj parse_supports_directive();
|
294
|
+
Supports_Condition_Obj parse_supports_condition();
|
295
|
+
Supports_Condition_Obj parse_supports_negation();
|
296
|
+
Supports_Condition_Obj parse_supports_operator();
|
297
|
+
Supports_Condition_Obj parse_supports_interpolation();
|
298
|
+
Supports_Condition_Obj parse_supports_declaration();
|
299
|
+
Supports_Condition_Obj parse_supports_condition_in_parens();
|
300
|
+
At_Root_Block_Obj parse_at_root_block();
|
301
|
+
At_Root_Query_Obj parse_at_root_query();
|
302
|
+
String_Schema_Obj parse_almost_any_value();
|
303
|
+
Directive_Obj parse_special_directive();
|
304
|
+
Directive_Obj parse_prefixed_directive();
|
305
|
+
Directive_Obj parse_directive();
|
306
|
+
Warning_Obj parse_warning();
|
307
|
+
Error_Obj parse_error();
|
308
|
+
Debug_Obj parse_debug();
|
314
309
|
|
315
310
|
// be more like ruby sass
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
311
|
+
Expression_Obj lex_almost_any_value_token();
|
312
|
+
Expression_Obj lex_almost_any_value_chars();
|
313
|
+
Expression_Obj lex_interp_string();
|
314
|
+
Expression_Obj lex_interp_uri();
|
315
|
+
Expression_Obj lex_interpolation();
|
321
316
|
|
322
317
|
// these will throw errors
|
323
318
|
Token lex_variable();
|
@@ -329,35 +324,35 @@ namespace Sass {
|
|
329
324
|
Lookahead lookahead_for_selector(const char* start = 0);
|
330
325
|
Lookahead lookahead_for_include(const char* start = 0);
|
331
326
|
|
332
|
-
|
333
|
-
|
327
|
+
Expression_Obj fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, Operand op);
|
328
|
+
Expression_Obj fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, std::vector<Operand>& ops, size_t i = 0);
|
334
329
|
|
335
330
|
void throw_syntax_error(std::string message, size_t ln = 0);
|
336
331
|
void throw_read_error(std::string message, size_t ln = 0);
|
337
332
|
|
338
333
|
|
339
334
|
template <Prelexer::prelexer open, Prelexer::prelexer close>
|
340
|
-
|
335
|
+
Expression_Obj lex_interp()
|
341
336
|
{
|
342
337
|
if (lex < open >(false)) {
|
343
|
-
|
338
|
+
String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
|
344
339
|
// std::cerr << "LEX [[" << std::string(lexed) << "]]\n";
|
345
|
-
|
340
|
+
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
|
346
341
|
if (position[0] == '#' && position[1] == '{') {
|
347
|
-
|
348
|
-
if (itpl)
|
342
|
+
Expression_Obj itpl = lex_interpolation();
|
343
|
+
if (&itpl) schema->append(&itpl);
|
349
344
|
while (lex < close >(false)) {
|
350
345
|
// std::cerr << "LEX [[" << std::string(lexed) << "]]\n";
|
351
|
-
|
346
|
+
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
|
352
347
|
if (position[0] == '#' && position[1] == '{') {
|
353
|
-
|
354
|
-
if (itpl)
|
348
|
+
Expression_Obj itpl = lex_interpolation();
|
349
|
+
if (&itpl) schema->append(&itpl);
|
355
350
|
} else {
|
356
|
-
return schema;
|
351
|
+
return &schema;
|
357
352
|
}
|
358
353
|
}
|
359
354
|
} else {
|
360
|
-
return SASS_MEMORY_NEW(
|
355
|
+
return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
|
361
356
|
}
|
362
357
|
}
|
363
358
|
return 0;
|
@@ -243,16 +243,19 @@ namespace Sass {
|
|
243
243
|
exactly <'l'>,
|
244
244
|
exactly <'('>,
|
245
245
|
W,
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
246
|
+
alternatives<
|
247
|
+
quoted_string,
|
248
|
+
non_greedy<
|
249
|
+
alternatives<
|
250
|
+
class_char< real_uri_chars >,
|
251
|
+
uri_character,
|
252
|
+
NONASCII,
|
253
|
+
ESCAPE
|
254
|
+
>,
|
255
|
+
alternatives<
|
256
|
+
sequence < W, exactly <')'> >,
|
257
|
+
exactly< hash_lbrace >
|
258
|
+
>
|
256
259
|
>
|
257
260
|
>
|
258
261
|
>(src);
|
@@ -10,19 +10,20 @@ namespace Sass {
|
|
10
10
|
: ctx(ctx)
|
11
11
|
{ }
|
12
12
|
|
13
|
-
void Remove_Placeholders::operator()(
|
13
|
+
void Remove_Placeholders::operator()(Block_Ptr b) {
|
14
14
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
15
|
-
|
15
|
+
Statement_Ptr st = &b->at(i);
|
16
|
+
st->perform(this);
|
16
17
|
}
|
17
18
|
}
|
18
19
|
|
19
|
-
|
20
|
+
Selector_List_Ptr Remove_Placeholders::remove_placeholders(Selector_List_Ptr sl)
|
20
21
|
{
|
21
|
-
|
22
|
+
Selector_List_Ptr new_sl = SASS_MEMORY_NEW(Selector_List, sl->pstate());
|
22
23
|
|
23
24
|
for (size_t i = 0, L = sl->length(); i < L; ++i) {
|
24
|
-
if (!(
|
25
|
-
|
25
|
+
if (!sl->at(i)->contains_placeholder()) {
|
26
|
+
new_sl->append(sl->at(i));
|
26
27
|
}
|
27
28
|
}
|
28
29
|
|
@@ -31,21 +32,21 @@ namespace Sass {
|
|
31
32
|
}
|
32
33
|
|
33
34
|
|
34
|
-
void Remove_Placeholders::operator()(
|
35
|
+
void Remove_Placeholders::operator()(Ruleset_Ptr r) {
|
35
36
|
// Create a new selector group without placeholders
|
36
|
-
|
37
|
+
Selector_List_Obj sl = SASS_MEMORY_CAST(Selector_List, r->selector());
|
37
38
|
|
38
39
|
if (sl) {
|
39
40
|
// Set the new placeholder selector list
|
40
|
-
r->selector(remove_placeholders(sl));
|
41
|
+
r->selector(remove_placeholders(&sl));
|
41
42
|
// Remove placeholders in wrapped selectors
|
42
|
-
for (
|
43
|
+
for (Complex_Selector_Obj cs : sl->elements()) {
|
43
44
|
while (cs) {
|
44
45
|
if (cs->head()) {
|
45
|
-
for (
|
46
|
-
if (
|
47
|
-
if (
|
48
|
-
|
46
|
+
for (Simple_Selector_Obj& ss : cs->head()->elements()) {
|
47
|
+
if (Wrapped_Selector_Ptr ws = SASS_MEMORY_CAST(Wrapped_Selector, ss)) {
|
48
|
+
if (Selector_List_Ptr sl = SASS_MEMORY_CAST(Selector_List, ws->selector())) {
|
49
|
+
Selector_List_Ptr clean = remove_placeholders(sl);
|
49
50
|
// also clean superflous parent selectors
|
50
51
|
// probably not really the correct place
|
51
52
|
clean->remove_parent_selectors();
|
@@ -60,21 +61,24 @@ namespace Sass {
|
|
60
61
|
}
|
61
62
|
|
62
63
|
// Iterate into child blocks
|
63
|
-
|
64
|
+
Block_Obj b = r->block();
|
64
65
|
|
65
66
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
66
|
-
if ((
|
67
|
+
if (b->at(i)) {
|
68
|
+
Statement_Obj st = b->at(i);
|
69
|
+
st->perform(this);
|
70
|
+
}
|
67
71
|
}
|
68
72
|
}
|
69
73
|
|
70
|
-
void Remove_Placeholders::operator()(
|
71
|
-
operator()(m->block());
|
74
|
+
void Remove_Placeholders::operator()(Media_Block_Ptr m) {
|
75
|
+
operator()(&m->block());
|
72
76
|
}
|
73
|
-
void Remove_Placeholders::operator()(
|
74
|
-
operator()(m->block());
|
77
|
+
void Remove_Placeholders::operator()(Supports_Block_Ptr m) {
|
78
|
+
operator()(&m->block());
|
75
79
|
}
|
76
80
|
|
77
|
-
void Remove_Placeholders::operator()(
|
81
|
+
void Remove_Placeholders::operator()(Directive_Ptr a) {
|
78
82
|
if (a->block()) a->block()->perform(this);
|
79
83
|
}
|
80
84
|
|
@@ -15,20 +15,20 @@ namespace Sass {
|
|
15
15
|
|
16
16
|
Context& ctx;
|
17
17
|
|
18
|
-
void fallback_impl(
|
18
|
+
void fallback_impl(AST_Node_Ptr n) {}
|
19
19
|
|
20
20
|
public:
|
21
|
-
|
21
|
+
Selector_List_Ptr remove_placeholders(Selector_List_Ptr);
|
22
22
|
|
23
23
|
public:
|
24
24
|
Remove_Placeholders(Context&);
|
25
25
|
~Remove_Placeholders() { }
|
26
26
|
|
27
|
-
void operator()(
|
28
|
-
void operator()(
|
29
|
-
void operator()(
|
30
|
-
void operator()(
|
31
|
-
void operator()(
|
27
|
+
void operator()(Block_Ptr);
|
28
|
+
void operator()(Ruleset_Ptr);
|
29
|
+
void operator()(Media_Block_Ptr);
|
30
|
+
void operator()(Supports_Block_Ptr);
|
31
|
+
void operator()(Directive_Ptr);
|
32
32
|
|
33
33
|
template <typename U>
|
34
34
|
void fallback(U x) { return fallback_impl(x); }
|
@@ -587,7 +587,8 @@ namespace Sass
|
|
587
587
|
sass.substr(pos_left, 5) == "@warn" ||
|
588
588
|
sass.substr(pos_left, 6) == "@debug" ||
|
589
589
|
sass.substr(pos_left, 6) == "@error" ||
|
590
|
-
sass.substr(pos_left, 8) == "@charset"
|
590
|
+
sass.substr(pos_left, 8) == "@charset" ||
|
591
|
+
sass.substr(pos_left, 10) == "@namespace"
|
591
592
|
) { sass = indent + sass.substr(pos_left); }
|
592
593
|
// replace some specific sass shorthand directives (if not fallowed by a white space character)
|
593
594
|
else if (sass.substr(pos_left, 1) == "=")
|
@@ -6,6 +6,7 @@
|
|
6
6
|
#include <vector>
|
7
7
|
|
8
8
|
#include "sass.h"
|
9
|
+
#include "ast.hpp"
|
9
10
|
#include "file.hpp"
|
10
11
|
#include "json.hpp"
|
11
12
|
#include "util.hpp"
|
@@ -26,39 +27,10 @@ namespace Sass {
|
|
26
27
|
std::string str(stream.str());
|
27
28
|
return json_mkstring(str.c_str());
|
28
29
|
}
|
29
|
-
}
|
30
|
-
|
31
|
-
extern "C" {
|
32
|
-
using namespace Sass;
|
33
|
-
|
34
|
-
static void sass_clear_options (struct Sass_Options* options);
|
35
|
-
static void sass_reset_options (struct Sass_Options* options);
|
36
|
-
static void copy_options(struct Sass_Options* to, struct Sass_Options* from) {
|
37
|
-
// free assigned memory
|
38
|
-
sass_clear_options(to);
|
39
|
-
// move memory
|
40
|
-
*to = *from;
|
41
|
-
// Reset pointers on source
|
42
|
-
sass_reset_options(from);
|
43
|
-
}
|
44
|
-
|
45
|
-
#define IMPLEMENT_SASS_OPTION_ACCESSOR(type, option) \
|
46
|
-
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return options->option; } \
|
47
|
-
void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) { options->option = option; }
|
48
|
-
#define IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(type, option, def) \
|
49
|
-
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return safe_str(options->option, def); } \
|
50
|
-
void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) \
|
51
|
-
{ free(options->option); options->option = option || def ? sass_copy_c_string(option ? option : def) : 0; }
|
52
|
-
|
53
|
-
#define IMPLEMENT_SASS_CONTEXT_GETTER(type, option) \
|
54
|
-
type ADDCALL sass_context_get_##option (struct Sass_Context* ctx) { return ctx->option; }
|
55
|
-
#define IMPLEMENT_SASS_CONTEXT_TAKER(type, option) \
|
56
|
-
type sass_context_take_##option (struct Sass_Context* ctx) \
|
57
|
-
{ type foo = ctx->option; ctx->option = 0; return foo; }
|
58
30
|
|
59
31
|
static int handle_error(Sass_Context* c_ctx) {
|
60
32
|
try {
|
61
|
-
|
33
|
+
throw;
|
62
34
|
}
|
63
35
|
catch (Exception::Base& e) {
|
64
36
|
std::stringstream msg_stream;
|
@@ -68,17 +40,19 @@ extern "C" {
|
|
68
40
|
bool got_newline = false;
|
69
41
|
msg_stream << msg_prefix << ": ";
|
70
42
|
const char* msg = e.what();
|
71
|
-
while(msg && *msg) {
|
43
|
+
while (msg && *msg) {
|
72
44
|
if (*msg == '\r') {
|
73
45
|
got_newline = true;
|
74
|
-
}
|
46
|
+
}
|
47
|
+
else if (*msg == '\n') {
|
75
48
|
got_newline = true;
|
76
|
-
}
|
49
|
+
}
|
50
|
+
else if (got_newline) {
|
77
51
|
msg_stream << std::string(msg_prefix.size() + 2, ' ');
|
78
52
|
got_newline = false;
|
79
53
|
}
|
80
54
|
msg_stream << *msg;
|
81
|
-
++
|
55
|
+
++msg;
|
82
56
|
}
|
83
57
|
if (!got_newline) msg_stream << "\n";
|
84
58
|
if (e.import_stack) {
|
@@ -87,12 +61,13 @@ extern "C" {
|
|
87
61
|
std::string rel_path(Sass::File::abs2rel(path, cwd, cwd));
|
88
62
|
msg_stream << std::string(msg_prefix.size() + 2, ' ');
|
89
63
|
msg_stream << (i == 1 ? " on line " : " from line ");
|
90
|
-
msg_stream << e.pstate.line+1 << " of " << rel_path << "\n";
|
64
|
+
msg_stream << e.pstate.line + 1 << " of " << rel_path << "\n";
|
91
65
|
}
|
92
|
-
}
|
66
|
+
}
|
67
|
+
else {
|
93
68
|
std::string rel_path(Sass::File::abs2rel(e.pstate.path, cwd, cwd));
|
94
69
|
msg_stream << std::string(msg_prefix.size() + 2, ' ');
|
95
|
-
msg_stream << " on line " << e.pstate.line+1 << " of " << rel_path << "\n";
|
70
|
+
msg_stream << " on line " << e.pstate.line + 1 << " of " << rel_path << "\n";
|
96
71
|
}
|
97
72
|
|
98
73
|
// now create the code trace (ToDo: maybe have util functions?)
|
@@ -100,19 +75,19 @@ extern "C" {
|
|
100
75
|
size_t line = e.pstate.line;
|
101
76
|
const char* line_beg = e.pstate.src;
|
102
77
|
while (line_beg && *line_beg && line) {
|
103
|
-
if (*line_beg == '\n') --
|
104
|
-
++
|
78
|
+
if (*line_beg == '\n') --line;
|
79
|
+
++line_beg;
|
105
80
|
}
|
106
81
|
const char* line_end = line_beg;
|
107
82
|
while (line_end && *line_end && *line_end != '\n') {
|
108
83
|
if (*line_end == '\n') break;
|
109
84
|
if (*line_end == '\r') break;
|
110
|
-
line_end
|
85
|
+
line_end++;
|
111
86
|
}
|
112
87
|
size_t max_left = 42; size_t max_right = 78;
|
113
88
|
size_t move_in = e.pstate.column > max_left ? e.pstate.column - max_left : 0;
|
114
89
|
size_t shorten = (line_end - line_beg) - move_in > max_right ?
|
115
|
-
|
90
|
+
(line_end - line_beg) - move_in - max_right : 0;
|
116
91
|
msg_stream << ">> " << std::string(line_beg + move_in, line_end - shorten) << "\n";
|
117
92
|
msg_stream << " " << std::string(e.pstate.column - move_in, '-') << "^\n";
|
118
93
|
}
|
@@ -120,17 +95,18 @@ extern "C" {
|
|
120
95
|
JsonNode* json_err = json_mkobject();
|
121
96
|
json_append_member(json_err, "status", json_mknumber(1));
|
122
97
|
json_append_member(json_err, "file", json_mkstring(e.pstate.path));
|
123
|
-
json_append_member(json_err, "line", json_mknumber((double)(e.pstate.line+1)));
|
124
|
-
json_append_member(json_err, "column", json_mknumber((double)(e.pstate.column+1)));
|
98
|
+
json_append_member(json_err, "line", json_mknumber((double)(e.pstate.line + 1)));
|
99
|
+
json_append_member(json_err, "column", json_mknumber((double)(e.pstate.column + 1)));
|
125
100
|
json_append_member(json_err, "message", json_mkstring(e.what()));
|
126
101
|
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
127
|
-
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
102
|
+
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
103
|
+
catch (...) {}
|
128
104
|
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
129
105
|
c_ctx->error_text = sass_copy_c_string(e.what());
|
130
106
|
c_ctx->error_status = 1;
|
131
107
|
c_ctx->error_file = sass_copy_c_string(e.pstate.path);
|
132
|
-
c_ctx->error_line = e.pstate.line+1;
|
133
|
-
c_ctx->error_column = e.pstate.column+1;
|
108
|
+
c_ctx->error_line = e.pstate.line + 1;
|
109
|
+
c_ctx->error_column = e.pstate.column + 1;
|
134
110
|
c_ctx->error_src = e.pstate.src;
|
135
111
|
c_ctx->output_string = 0;
|
136
112
|
c_ctx->source_map_string = 0;
|
@@ -143,7 +119,8 @@ extern "C" {
|
|
143
119
|
json_append_member(json_err, "status", json_mknumber(2));
|
144
120
|
json_append_member(json_err, "message", json_mkstring(ba.what()));
|
145
121
|
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
146
|
-
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
122
|
+
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
123
|
+
catch (...) {}
|
147
124
|
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
148
125
|
c_ctx->error_text = sass_copy_c_string(ba.what());
|
149
126
|
c_ctx->error_status = 2;
|
@@ -158,7 +135,8 @@ extern "C" {
|
|
158
135
|
json_append_member(json_err, "status", json_mknumber(3));
|
159
136
|
json_append_member(json_err, "message", json_mkstring(e.what()));
|
160
137
|
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
161
|
-
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
138
|
+
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
139
|
+
catch (...) {}
|
162
140
|
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
163
141
|
c_ctx->error_text = sass_copy_c_string(e.what());
|
164
142
|
c_ctx->error_status = 3;
|
@@ -173,7 +151,8 @@ extern "C" {
|
|
173
151
|
json_append_member(json_err, "status", json_mknumber(4));
|
174
152
|
json_append_member(json_err, "message", json_mkstring(e.c_str()));
|
175
153
|
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
176
|
-
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
154
|
+
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
155
|
+
catch (...) {}
|
177
156
|
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
178
157
|
c_ctx->error_text = sass_copy_c_string(e.c_str());
|
179
158
|
c_ctx->error_status = 4;
|
@@ -188,7 +167,8 @@ extern "C" {
|
|
188
167
|
json_append_member(json_err, "status", json_mknumber(4));
|
189
168
|
json_append_member(json_err, "message", json_mkstring(e));
|
190
169
|
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
191
|
-
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
170
|
+
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
171
|
+
catch (...) {}
|
192
172
|
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
193
173
|
c_ctx->error_text = sass_copy_c_string(e);
|
194
174
|
c_ctx->error_status = 4;
|
@@ -202,7 +182,8 @@ extern "C" {
|
|
202
182
|
msg_stream << "Unknown error occurred" << std::endl;
|
203
183
|
json_append_member(json_err, "status", json_mknumber(5));
|
204
184
|
json_append_member(json_err, "message", json_mkstring("unknown"));
|
205
|
-
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
185
|
+
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
186
|
+
catch (...) {}
|
206
187
|
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
207
188
|
c_ctx->error_text = sass_copy_c_string("unknown");
|
208
189
|
c_ctx->error_status = 5;
|
@@ -221,6 +202,88 @@ extern "C" {
|
|
221
202
|
return c_ctx->error_status;
|
222
203
|
}
|
223
204
|
|
205
|
+
static Block_Obj sass_parse_block(Sass_Compiler* compiler) throw()
|
206
|
+
{
|
207
|
+
|
208
|
+
// assert valid pointer
|
209
|
+
if (compiler == 0) return 0;
|
210
|
+
// The cpp context must be set by now
|
211
|
+
Context* cpp_ctx = compiler->cpp_ctx;
|
212
|
+
Sass_Context* c_ctx = compiler->c_ctx;
|
213
|
+
// We will take care to wire up the rest
|
214
|
+
compiler->cpp_ctx->c_compiler = compiler;
|
215
|
+
compiler->state = SASS_COMPILER_PARSED;
|
216
|
+
|
217
|
+
try {
|
218
|
+
|
219
|
+
// get input/output path from options
|
220
|
+
std::string input_path = safe_str(c_ctx->input_path);
|
221
|
+
std::string output_path = safe_str(c_ctx->output_path);
|
222
|
+
|
223
|
+
// maybe skip some entries of included files
|
224
|
+
// we do not include stdin for data contexts
|
225
|
+
bool skip = c_ctx->type == SASS_CONTEXT_DATA;
|
226
|
+
|
227
|
+
// dispatch parse call
|
228
|
+
Block_Obj root(cpp_ctx->parse());
|
229
|
+
// abort on errors
|
230
|
+
if (!root) return 0;
|
231
|
+
|
232
|
+
// skip all prefixed files? (ToDo: check srcmap)
|
233
|
+
// IMO source-maps should point to headers already
|
234
|
+
// therefore don't skip it for now. re-enable or
|
235
|
+
// remove completely once this is tested
|
236
|
+
size_t headers = cpp_ctx->head_imports;
|
237
|
+
|
238
|
+
// copy the included files on to the context (dont forget to free later)
|
239
|
+
if (copy_strings(cpp_ctx->get_included_files(skip, headers), &c_ctx->included_files) == NULL)
|
240
|
+
throw(std::bad_alloc());
|
241
|
+
|
242
|
+
// return parsed block
|
243
|
+
return root;
|
244
|
+
|
245
|
+
}
|
246
|
+
// pass errors to generic error handler
|
247
|
+
catch (...) { handle_errors(c_ctx); }
|
248
|
+
|
249
|
+
// error
|
250
|
+
return 0;
|
251
|
+
|
252
|
+
}
|
253
|
+
|
254
|
+
}
|
255
|
+
|
256
|
+
extern "C" {
|
257
|
+
using namespace Sass;
|
258
|
+
|
259
|
+
static void sass_clear_options (struct Sass_Options* options);
|
260
|
+
static void sass_reset_options (struct Sass_Options* options);
|
261
|
+
static void copy_options(struct Sass_Options* to, struct Sass_Options* from) {
|
262
|
+
// do not overwrite ourself
|
263
|
+
if (to == from) return;
|
264
|
+
// free assigned memory
|
265
|
+
sass_clear_options(to);
|
266
|
+
// move memory
|
267
|
+
*to = *from;
|
268
|
+
// Reset pointers on source
|
269
|
+
sass_reset_options(from);
|
270
|
+
}
|
271
|
+
|
272
|
+
#define IMPLEMENT_SASS_OPTION_ACCESSOR(type, option) \
|
273
|
+
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return options->option; } \
|
274
|
+
void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) { options->option = option; }
|
275
|
+
#define IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(type, option, def) \
|
276
|
+
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return safe_str(options->option, def); } \
|
277
|
+
void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) \
|
278
|
+
{ free(options->option); options->option = option || def ? sass_copy_c_string(option ? option : def) : 0; }
|
279
|
+
|
280
|
+
#define IMPLEMENT_SASS_CONTEXT_GETTER(type, option) \
|
281
|
+
type ADDCALL sass_context_get_##option (struct Sass_Context* ctx) { return ctx->option; }
|
282
|
+
#define IMPLEMENT_SASS_CONTEXT_TAKER(type, option) \
|
283
|
+
type sass_context_take_##option (struct Sass_Context* ctx) \
|
284
|
+
{ type foo = ctx->option; ctx->option = 0; return foo; }
|
285
|
+
|
286
|
+
|
224
287
|
// generic compilation function (not exported, use file/data compile instead)
|
225
288
|
static Sass_Compiler* sass_prepare_context (Sass_Context* c_ctx, Context* cpp_ctx) throw()
|
226
289
|
{
|
@@ -284,58 +347,6 @@ extern "C" {
|
|
284
347
|
|
285
348
|
}
|
286
349
|
|
287
|
-
static Block* sass_parse_block (Sass_Compiler* compiler) throw()
|
288
|
-
{
|
289
|
-
|
290
|
-
// assert valid pointer
|
291
|
-
if (compiler == 0) return 0;
|
292
|
-
// The cpp context must be set by now
|
293
|
-
Context* cpp_ctx = compiler->cpp_ctx;
|
294
|
-
Sass_Context* c_ctx = compiler->c_ctx;
|
295
|
-
// We will take care to wire up the rest
|
296
|
-
compiler->cpp_ctx->c_compiler = compiler;
|
297
|
-
compiler->state = SASS_COMPILER_PARSED;
|
298
|
-
|
299
|
-
try {
|
300
|
-
|
301
|
-
// get input/output path from options
|
302
|
-
std::string input_path = safe_str(c_ctx->input_path);
|
303
|
-
std::string output_path = safe_str(c_ctx->output_path);
|
304
|
-
|
305
|
-
// parsed root block
|
306
|
-
Block* root = 0;
|
307
|
-
|
308
|
-
// maybe skip some entries of included files
|
309
|
-
// we do not include stdin for data contexts
|
310
|
-
bool skip = c_ctx->type == SASS_CONTEXT_DATA;
|
311
|
-
|
312
|
-
// dispatch parse call
|
313
|
-
root = cpp_ctx->parse();
|
314
|
-
// abort on errors
|
315
|
-
if (!root) return 0;
|
316
|
-
|
317
|
-
// skip all prefixed files? (ToDo: check srcmap)
|
318
|
-
// IMO source-maps should point to headers already
|
319
|
-
// therefore don't skip it for now. re-enable or
|
320
|
-
// remove completely once this is tested
|
321
|
-
size_t headers = cpp_ctx->head_imports;
|
322
|
-
|
323
|
-
// copy the included files on to the context (dont forget to free later)
|
324
|
-
if (copy_strings(cpp_ctx->get_included_files(skip, headers), &c_ctx->included_files) == NULL)
|
325
|
-
throw(std::bad_alloc());
|
326
|
-
|
327
|
-
// return parsed block
|
328
|
-
return root;
|
329
|
-
|
330
|
-
}
|
331
|
-
// pass errors to generic error handler
|
332
|
-
catch (...) { handle_errors(c_ctx); }
|
333
|
-
|
334
|
-
// error
|
335
|
-
return 0;
|
336
|
-
|
337
|
-
}
|
338
|
-
|
339
350
|
// generic compilation function (not exported, use file/data compile instead)
|
340
351
|
static int sass_compile_context (Sass_Context* c_ctx, Context* cpp_ctx)
|
341
352
|
{
|
@@ -373,6 +384,7 @@ extern "C" {
|
|
373
384
|
|
374
385
|
Sass_File_Context* ADDCALL sass_make_file_context(const char* input_path)
|
375
386
|
{
|
387
|
+
SharedObj::setTaint(true); // needed for static colors
|
376
388
|
struct Sass_File_Context* ctx = (struct Sass_File_Context*) calloc(1, sizeof(struct Sass_File_Context));
|
377
389
|
if (ctx == 0) { std::cerr << "Error allocating memory for file context" << std::endl; return 0; }
|
378
390
|
ctx->type = SASS_CONTEXT_FILE;
|
@@ -456,7 +468,7 @@ extern "C" {
|
|
456
468
|
if (compiler->c_ctx->error_status)
|
457
469
|
return compiler->c_ctx->error_status;
|
458
470
|
// parse the context we have set up (file or data)
|
459
|
-
compiler->root = sass_parse_block(compiler);
|
471
|
+
compiler->root = &sass_parse_block(compiler);
|
460
472
|
// success
|
461
473
|
return 0;
|
462
474
|
}
|
@@ -468,12 +480,12 @@ extern "C" {
|
|
468
480
|
if (compiler->state != SASS_COMPILER_PARSED) return -1;
|
469
481
|
if (compiler->c_ctx == NULL) return 1;
|
470
482
|
if (compiler->cpp_ctx == NULL) return 1;
|
471
|
-
if (compiler->root
|
483
|
+
if (compiler->root.isNull()) return 1;
|
472
484
|
if (compiler->c_ctx->error_status)
|
473
485
|
return compiler->c_ctx->error_status;
|
474
486
|
compiler->state = SASS_COMPILER_EXECUTED;
|
475
487
|
Context* cpp_ctx = compiler->cpp_ctx;
|
476
|
-
|
488
|
+
Block_Obj root = compiler->root;
|
477
489
|
// compile the parsed root block
|
478
490
|
try { compiler->c_ctx->output_string = cpp_ctx->render(root); }
|
479
491
|
// pass catched errors to generic error handler
|
@@ -601,6 +613,10 @@ extern "C" {
|
|
601
613
|
ctx->error_json = 0;
|
602
614
|
ctx->error_file = 0;
|
603
615
|
ctx->included_files = 0;
|
616
|
+
// debug leaked memory
|
617
|
+
#ifdef DEBUG_SHARED_PTR
|
618
|
+
SharedObj::dumpMemLeaks();
|
619
|
+
#endif
|
604
620
|
// now clear the options
|
605
621
|
sass_clear_options(ctx);
|
606
622
|
}
|
@@ -612,7 +628,9 @@ extern "C" {
|
|
612
628
|
}
|
613
629
|
Context* cpp_ctx = compiler->cpp_ctx;
|
614
630
|
if (cpp_ctx) delete(cpp_ctx);
|
615
|
-
compiler->cpp_ctx =
|
631
|
+
compiler->cpp_ctx = NULL;
|
632
|
+
compiler->c_ctx = NULL;
|
633
|
+
compiler->root = NULL;
|
616
634
|
free(compiler);
|
617
635
|
}
|
618
636
|
|