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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/README.md +3 -2
  4. data/ext/libsass/Makefile.conf +2 -1
  5. data/ext/libsass/appveyor.yml +10 -5
  6. data/ext/libsass/docs/dev-ast-memory.md +223 -0
  7. data/ext/libsass/include/sass/base.h +2 -0
  8. data/ext/libsass/script/bootstrap +7 -4
  9. data/ext/libsass/script/ci-build-libsass +3 -3
  10. data/ext/libsass/script/ci-install-compiler +2 -0
  11. data/ext/libsass/script/ci-report-coverage +2 -1
  12. data/ext/libsass/script/test-leaks.pl +103 -0
  13. data/ext/libsass/src/ast.cpp +621 -495
  14. data/ext/libsass/src/ast.hpp +801 -367
  15. data/ext/libsass/src/ast_def_macros.hpp +5 -5
  16. data/ext/libsass/src/ast_fwd_decl.hpp +312 -14
  17. data/ext/libsass/src/bind.cpp +54 -51
  18. data/ext/libsass/src/bind.hpp +3 -7
  19. data/ext/libsass/src/check_nesting.cpp +117 -120
  20. data/ext/libsass/src/check_nesting.hpp +38 -34
  21. data/ext/libsass/src/color_maps.cpp +3 -3
  22. data/ext/libsass/src/color_maps.hpp +3 -3
  23. data/ext/libsass/src/context.cpp +33 -34
  24. data/ext/libsass/src/context.hpp +12 -14
  25. data/ext/libsass/src/cssize.cpp +200 -228
  26. data/ext/libsass/src/cssize.hpp +49 -49
  27. data/ext/libsass/src/debugger.hpp +260 -241
  28. data/ext/libsass/src/emitter.cpp +6 -6
  29. data/ext/libsass/src/emitter.hpp +7 -7
  30. data/ext/libsass/src/environment.cpp +2 -2
  31. data/ext/libsass/src/environment.hpp +0 -2
  32. data/ext/libsass/src/error_handling.cpp +5 -5
  33. data/ext/libsass/src/error_handling.hpp +12 -12
  34. data/ext/libsass/src/eval.cpp +412 -401
  35. data/ext/libsass/src/eval.hpp +61 -62
  36. data/ext/libsass/src/expand.cpp +223 -204
  37. data/ext/libsass/src/expand.hpp +42 -42
  38. data/ext/libsass/src/extend.cpp +198 -201
  39. data/ext/libsass/src/extend.hpp +12 -14
  40. data/ext/libsass/src/file.hpp +4 -5
  41. data/ext/libsass/src/functions.cpp +413 -418
  42. data/ext/libsass/src/functions.hpp +7 -10
  43. data/ext/libsass/src/inspect.cpp +115 -109
  44. data/ext/libsass/src/inspect.hpp +69 -69
  45. data/ext/libsass/src/listize.cpp +31 -33
  46. data/ext/libsass/src/listize.hpp +8 -10
  47. data/ext/libsass/src/memory/SharedPtr.cpp +116 -0
  48. data/ext/libsass/src/memory/SharedPtr.hpp +202 -0
  49. data/ext/libsass/src/node.cpp +45 -43
  50. data/ext/libsass/src/node.hpp +15 -15
  51. data/ext/libsass/src/operation.hpp +136 -136
  52. data/ext/libsass/src/output.cpp +48 -49
  53. data/ext/libsass/src/output.hpp +14 -14
  54. data/ext/libsass/src/parser.cpp +530 -554
  55. data/ext/libsass/src/parser.hpp +91 -96
  56. data/ext/libsass/src/prelexer.cpp +13 -10
  57. data/ext/libsass/src/remove_placeholders.cpp +25 -21
  58. data/ext/libsass/src/remove_placeholders.hpp +7 -7
  59. data/ext/libsass/src/sass2scss.cpp +2 -1
  60. data/ext/libsass/src/sass_context.cpp +125 -107
  61. data/ext/libsass/src/sass_context.hpp +1 -1
  62. data/ext/libsass/src/sass_util.hpp +5 -5
  63. data/ext/libsass/src/sass_values.cpp +27 -27
  64. data/ext/libsass/src/source_map.cpp +2 -2
  65. data/ext/libsass/src/source_map.hpp +2 -2
  66. data/ext/libsass/src/subset_map.cpp +57 -0
  67. data/ext/libsass/src/subset_map.hpp +8 -76
  68. data/ext/libsass/src/to_c.cpp +13 -13
  69. data/ext/libsass/src/to_c.hpp +14 -14
  70. data/ext/libsass/src/to_value.cpp +20 -20
  71. data/ext/libsass/src/to_value.hpp +20 -21
  72. data/ext/libsass/src/util.cpp +55 -88
  73. data/ext/libsass/src/util.hpp +9 -13
  74. data/ext/libsass/src/values.cpp +27 -26
  75. data/ext/libsass/src/values.hpp +2 -2
  76. data/ext/libsass/test/test_subset_map.cpp +69 -69
  77. data/ext/libsass/win/libsass.targets +3 -2
  78. data/ext/libsass/win/libsass.vcxproj.filters +9 -6
  79. data/lib/sassc/version.rb +1 -1
  80. data/sassc.gemspec +0 -1
  81. data/test/native_test.rb +1 -1
  82. metadata +7 -5
  83. data/ext/libsass/src/ast_factory.hpp +0 -92
  84. data/ext/libsass/src/memory_manager.cpp +0 -77
  85. data/ext/libsass/src/memory_manager.hpp +0 -48
@@ -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<Block*> block_stack;
29
+ std::vector<Block_Obj> block_stack;
30
30
  std::vector<Scope> stack;
31
- Media_Block* last_media_block;
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(0), stack(0), last_media_block(0),
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 CommaSequence_Selector* parse_selector(const char* src, Context& ctx, ParserState pstate = ParserState("[SELECTOR]"), const char* source = 0);
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
- Block* parse();
235
- Import* parse_import();
236
- Definition* parse_definition(Definition::Type which_type);
237
- Parameters* parse_parameters();
238
- Parameter* parse_parameter();
239
- Mixin_Call* parse_include_directive();
240
- Arguments* parse_arguments();
241
- Argument* parse_argument();
242
- Assignment* parse_assignment();
243
- Ruleset* parse_ruleset(Lookahead lookahead, bool is_root = false);
244
- Selector_Schema* parse_selector_schema(const char* end_of_selector);
245
- CommaSequence_Selector* parse_selector_list(bool at_root = false);
246
- Sequence_Selector* parse_complex_selector(bool in_root = true);
247
- SimpleSequence_Selector* parse_compound_selector();
248
- Simple_Selector* parse_simple_selector();
249
- Wrapped_Selector* parse_negated_selector();
250
- Simple_Selector* parse_pseudo_selector();
251
- Attribute_Selector* parse_attribute_selector();
252
- Block* parse_block(bool is_root = false);
253
- Block* parse_css_block(bool is_root = false);
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
- Declaration* parse_declaration();
259
- Expression* parse_map_value();
260
- Expression* parse_map();
261
- Expression* parse_list(bool delayed = false);
262
- Expression* parse_comma_list(bool delayed = false);
263
- Expression* parse_space_list();
264
- Expression* parse_disjunction();
265
- Expression* parse_conjunction();
266
- Expression* parse_relation();
267
- Expression* parse_expression();
268
- Expression* parse_operators();
269
- Expression* parse_factor();
270
- Expression* parse_value2();
271
- Expression* parse_value();
272
- Function_Call* parse_calc_function();
273
- Function_Call* parse_function_call();
274
- Function_Call_Schema* parse_function_call_schema();
275
- String* parse_url_function_string();
276
- String* parse_url_function_argument();
277
- String* parse_interpolated_chunk(Token, bool constant = false);
278
- String* parse_string();
279
- String_Constant* parse_static_expression();
280
- // String_Constant* parse_static_property();
281
- String_Constant* parse_static_value();
282
- String* parse_ie_property();
283
- String* parse_ie_keyword_arg();
284
- String_Schema* parse_value_schema(const char* stop);
285
- String* parse_identifier_schema();
286
- // String_Schema* parse_url_schema();
287
- If* parse_if_directive(bool else_if = false);
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
- Media_Block* parse_media_block();
295
- List* parse_media_queries();
296
- Media_Query* parse_media_query();
297
- Media_Query_Expression* parse_media_expression();
298
- Supports_Block* parse_supports_directive();
299
- Supports_Condition* parse_supports_condition();
300
- Supports_Condition* parse_supports_negation();
301
- Supports_Condition* parse_supports_operator();
302
- Supports_Condition* parse_supports_interpolation();
303
- Supports_Condition* parse_supports_declaration();
304
- Supports_Condition* parse_supports_condition_in_parens();
305
- At_Root_Block* parse_at_root_block();
306
- At_Root_Query* parse_at_root_query();
307
- String_Schema* parse_almost_any_value();
308
- Directive* parse_special_directive();
309
- Directive* parse_prefixed_directive();
310
- Directive* parse_directive();
311
- Warning* parse_warning();
312
- Error* parse_error();
313
- Debug* parse_debug();
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
- Expression* lex_almost_any_value_token();
317
- Expression* lex_almost_any_value_chars();
318
- Expression* lex_interp_string();
319
- Expression* lex_interp_uri();
320
- Expression* lex_interpolation();
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
- Expression* fold_operands(Expression* base, std::vector<Expression*>& operands, Operand op);
333
- Expression* fold_operands(Expression* base, std::vector<Expression*>& operands, std::vector<Operand>& ops, size_t i = 0);
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
- Expression* lex_interp()
335
+ Expression_Obj lex_interp()
341
336
  {
342
337
  if (lex < open >(false)) {
343
- String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
338
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
344
339
  // std::cerr << "LEX [[" << std::string(lexed) << "]]\n";
345
- *schema << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
340
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
346
341
  if (position[0] == '#' && position[1] == '{') {
347
- Expression* itpl = lex_interpolation();
348
- if (itpl) *schema << 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
- *schema << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
346
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
352
347
  if (position[0] == '#' && position[1] == '{') {
353
- Expression* itpl = lex_interpolation();
354
- if (itpl) *schema << 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(ctx.mem, String_Constant, pstate, lexed);
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
- non_greedy<
247
- alternatives<
248
- class_char< real_uri_chars >,
249
- uri_character,
250
- NONASCII,
251
- ESCAPE
252
- >,
253
- alternatives<
254
- sequence < W, exactly <')'> >,
255
- exactly< hash_lbrace >
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()(Block* b) {
13
+ void Remove_Placeholders::operator()(Block_Ptr b) {
14
14
  for (size_t i = 0, L = b->length(); i < L; ++i) {
15
- (*b)[i]->perform(this);
15
+ Statement_Ptr st = &b->at(i);
16
+ st->perform(this);
16
17
  }
17
18
  }
18
19
 
19
- CommaSequence_Selector* Remove_Placeholders::remove_placeholders(CommaSequence_Selector* sl)
20
+ Selector_List_Ptr Remove_Placeholders::remove_placeholders(Selector_List_Ptr sl)
20
21
  {
21
- CommaSequence_Selector* new_sl = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, sl->pstate());
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 (!(*sl)[i]->contains_placeholder()) {
25
- *new_sl << (*sl)[i];
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()(Ruleset* r) {
35
+ void Remove_Placeholders::operator()(Ruleset_Ptr r) {
35
36
  // Create a new selector group without placeholders
36
- CommaSequence_Selector* sl = static_cast<CommaSequence_Selector*>(r->selector());
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 (Sequence_Selector* cs : *sl) {
43
+ for (Complex_Selector_Obj cs : sl->elements()) {
43
44
  while (cs) {
44
45
  if (cs->head()) {
45
- for (Simple_Selector* ss : *cs->head()) {
46
- if (Wrapped_Selector* ws = dynamic_cast<Wrapped_Selector*>(ss)) {
47
- if (CommaSequence_Selector* sl = dynamic_cast<CommaSequence_Selector*>(ws->selector())) {
48
- CommaSequence_Selector* clean = remove_placeholders(sl);
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
- Block* b = r->block();
64
+ Block_Obj b = r->block();
64
65
 
65
66
  for (size_t i = 0, L = b->length(); i < L; ++i) {
66
- if ((*b)[i]) (*b)[i]->perform(this);
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()(Media_Block* m) {
71
- operator()(m->block());
74
+ void Remove_Placeholders::operator()(Media_Block_Ptr m) {
75
+ operator()(&m->block());
72
76
  }
73
- void Remove_Placeholders::operator()(Supports_Block* m) {
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()(Directive* a) {
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(AST_Node* n) {}
18
+ void fallback_impl(AST_Node_Ptr n) {}
19
19
 
20
20
  public:
21
- CommaSequence_Selector* remove_placeholders(CommaSequence_Selector*);
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()(Block*);
28
- void operator()(Ruleset*);
29
- void operator()(Media_Block*);
30
- void operator()(Supports_Block*);
31
- void operator()(Directive*);
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
- throw;
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
- } else if (*msg == '\n') {
46
+ }
47
+ else if (*msg == '\n') {
75
48
  got_newline = true;
76
- } else if (got_newline) {
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
- ++ msg;
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
- } else {
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') -- line;
104
- ++ line_beg;
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
- (line_end - line_beg) - move_in - max_right : 0;
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, " "); } catch(...) {}
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, " "); } catch(...) {}
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, " "); } catch(...) {}
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, " "); } catch(...) {}
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, " "); } catch(...) {}
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, " "); } catch(...) {}
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 == NULL) return 1;
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
- Block* root = compiler->root;
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 = 0;
631
+ compiler->cpp_ctx = NULL;
632
+ compiler->c_ctx = NULL;
633
+ compiler->root = NULL;
616
634
  free(compiler);
617
635
  }
618
636