sassc 1.11.1 → 1.11.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|