sassc 1.9.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -3
  3. data/ext/libsass/.gitignore +3 -0
  4. data/ext/libsass/.travis.yml +1 -1
  5. data/ext/libsass/GNUmakefile.am +7 -7
  6. data/ext/libsass/Makefile +7 -4
  7. data/ext/libsass/Makefile.conf +0 -1
  8. data/ext/libsass/appveyor.yml +6 -2
  9. data/ext/libsass/docs/api-context.md +4 -4
  10. data/ext/libsass/docs/api-doc.md +29 -11
  11. data/ext/libsass/docs/api-importer-example.md +5 -5
  12. data/ext/libsass/docs/build-on-windows.md +1 -1
  13. data/ext/libsass/include/sass/base.h +10 -0
  14. data/ext/libsass/include/sass/version.h +4 -0
  15. data/ext/libsass/include/sass/version.h.in +4 -0
  16. data/ext/libsass/include/sass2scss.h +1 -1
  17. data/ext/libsass/script/ci-build-libsass +15 -3
  18. data/ext/libsass/src/ast.cpp +161 -6
  19. data/ext/libsass/src/ast.hpp +71 -44
  20. data/ext/libsass/src/ast_factory.hpp +1 -1
  21. data/ext/libsass/src/ast_fwd_decl.hpp +2 -2
  22. data/ext/libsass/src/constants.cpp +2 -4
  23. data/ext/libsass/src/constants.hpp +3 -4
  24. data/ext/libsass/src/context.cpp +16 -17
  25. data/ext/libsass/src/context.hpp +2 -2
  26. data/ext/libsass/src/cssize.cpp +19 -8
  27. data/ext/libsass/src/cssize.hpp +5 -2
  28. data/ext/libsass/src/debugger.hpp +6 -3
  29. data/ext/libsass/src/emitter.cpp +1 -1
  30. data/ext/libsass/src/environment.cpp +1 -1
  31. data/ext/libsass/src/eval.cpp +42 -14
  32. data/ext/libsass/src/eval.hpp +1 -1
  33. data/ext/libsass/src/expand.cpp +24 -8
  34. data/ext/libsass/src/expand.hpp +2 -1
  35. data/ext/libsass/src/extend.cpp +55 -15
  36. data/ext/libsass/src/extend.hpp +5 -1
  37. data/ext/libsass/src/functions.cpp +10 -5
  38. data/ext/libsass/src/inspect.cpp +25 -19
  39. data/ext/libsass/src/inspect.hpp +2 -2
  40. data/ext/libsass/src/json.cpp +20 -9
  41. data/ext/libsass/src/json.hpp +5 -5
  42. data/ext/libsass/src/lexer.cpp +4 -1
  43. data/ext/libsass/src/lexer.hpp +21 -0
  44. data/ext/libsass/src/listize.cpp +2 -1
  45. data/ext/libsass/src/operation.hpp +4 -4
  46. data/ext/libsass/src/output.cpp +1 -1
  47. data/ext/libsass/src/output.hpp +1 -1
  48. data/ext/libsass/src/parser.cpp +189 -90
  49. data/ext/libsass/src/parser.hpp +42 -2
  50. data/ext/libsass/src/prelexer.cpp +474 -7
  51. data/ext/libsass/src/prelexer.hpp +15 -2
  52. data/ext/libsass/src/remove_placeholders.cpp +5 -5
  53. data/ext/libsass/src/remove_placeholders.hpp +3 -2
  54. data/ext/libsass/src/sass.cpp +33 -3
  55. data/ext/libsass/src/sass2scss.cpp +7 -0
  56. data/ext/libsass/src/sass_context.cpp +32 -62
  57. data/ext/libsass/src/sass_functions.cpp +3 -3
  58. data/ext/libsass/src/sass_values.cpp +5 -5
  59. data/ext/libsass/src/utf8/unchecked.h +16 -16
  60. data/ext/libsass/src/util.cpp +51 -30
  61. data/ext/libsass/src/util.hpp +6 -1
  62. data/ext/libsass/win/libsass.targets +0 -2
  63. data/ext/libsass/win/libsass.vcxproj.filters +0 -6
  64. data/lib/sassc/engine.rb +4 -1
  65. data/lib/sassc/error.rb +23 -1
  66. data/lib/sassc/version.rb +1 -1
  67. data/test/error_test.rb +27 -0
  68. data/test/native_test.rb +1 -1
  69. metadata +5 -5
  70. data/ext/libsass/include/sass/interface.h +0 -105
  71. data/ext/libsass/src/sass_interface.cpp +0 -215
@@ -277,8 +277,24 @@ namespace Sass {
277
277
  // extra <std::vector> internally to maintain insertion order for interation.
278
278
  /////////////////////////////////////////////////////////////////////////////
279
279
  class Hashed {
280
+ struct HashExpression {
281
+ size_t operator() (Expression* ex) const {
282
+ return ex ? ex->hash() : 0;
283
+ }
284
+ };
285
+ struct CompareExpression {
286
+ bool operator()(const Expression* lhs, const Expression* rhs) const {
287
+ return lhs && rhs && *lhs == *rhs;
288
+ }
289
+ };
290
+ typedef std::unordered_map<
291
+ Expression*, // key
292
+ Expression*, // value
293
+ HashExpression, // hasher
294
+ CompareExpression // compare
295
+ > ExpressionMap;
280
296
  private:
281
- std::unordered_map<Expression*, Expression*> elements_;
297
+ ExpressionMap elements_;
282
298
  std::vector<Expression*> list_;
283
299
  protected:
284
300
  size_t hash_;
@@ -287,7 +303,7 @@ namespace Sass {
287
303
  void reset_duplicate_key() { duplicate_key_ = 0; }
288
304
  virtual void adjust_after_pushing(std::pair<Expression*, Expression*> p) { }
289
305
  public:
290
- Hashed(size_t s = 0) : elements_(std::unordered_map<Expression*, Expression*>(s)), list_(std::vector<Expression*>())
306
+ Hashed(size_t s = 0) : elements_(ExpressionMap(s)), list_(std::vector<Expression*>())
291
307
  { elements_.reserve(s); list_.reserve(s); reset_duplicate_key(); }
292
308
  virtual ~Hashed();
293
309
  size_t length() const { return list_.size(); }
@@ -296,7 +312,7 @@ namespace Sass {
296
312
  Expression* at(Expression* k) const;
297
313
  bool has_duplicate_key() const { return duplicate_key_ != 0; }
298
314
  Expression* get_duplicate_key() const { return duplicate_key_; }
299
- const std::unordered_map<Expression*, Expression*> elements() { return elements_; }
315
+ const ExpressionMap elements() { return elements_; }
300
316
  Hashed& operator<<(std::pair<Expression*, Expression*> p)
301
317
  {
302
318
  reset_hash();
@@ -324,7 +340,7 @@ namespace Sass {
324
340
  reset_duplicate_key();
325
341
  return *this;
326
342
  }
327
- const std::unordered_map<Expression*, Expression*>& pairs() const { return elements_; }
343
+ const ExpressionMap& pairs() const { return elements_; }
328
344
  const std::vector<Expression*>& keys() const { return list_; }
329
345
 
330
346
  std::unordered_map<Expression*, Expression*>::iterator end() { return elements_.end(); }
@@ -508,12 +524,12 @@ namespace Sass {
508
524
  // At-rules -- arbitrary directives beginning with "@" that may have an
509
525
  // optional statement block.
510
526
  ///////////////////////////////////////////////////////////////////////
511
- class At_Rule : public Has_Block {
527
+ class Directive : public Has_Block {
512
528
  ADD_PROPERTY(std::string, keyword)
513
529
  ADD_PROPERTY(Selector*, selector)
514
530
  ADD_PROPERTY(Expression*, value)
515
531
  public:
516
- At_Rule(ParserState pstate, std::string kwd, Selector* sel = 0, Block* b = 0, Expression* val = 0)
532
+ Directive(ParserState pstate, std::string kwd, Selector* sel = 0, Block* b = 0, Expression* val = 0)
517
533
  : Has_Block(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed
518
534
  { statement_type(DIRECTIVE); }
519
535
  bool bubbles() { return is_keyframes() || is_media(); }
@@ -660,7 +676,7 @@ namespace Sass {
660
676
  : Statement(pstate), text_(txt), is_important_(is_important)
661
677
  { statement_type(COMMENT); }
662
678
  virtual bool is_invisible() const
663
- { return is_important() == false; }
679
+ { return /* is_important() == */ false; }
664
680
  ATTACH_OPERATIONS()
665
681
  };
666
682
 
@@ -840,6 +856,7 @@ namespace Sass {
840
856
  // The @content directive for mixin content blocks.
841
857
  ///////////////////////////////////////////////////
842
858
  class Content : public Statement {
859
+ ADD_PROPERTY(Media_Block*, media_block)
843
860
  public:
844
861
  Content(ParserState pstate) : Statement(pstate)
845
862
  { statement_type(CONTENT); }
@@ -855,12 +872,15 @@ namespace Sass {
855
872
  private:
856
873
  ADD_PROPERTY(enum Sass_Separator, separator)
857
874
  ADD_PROPERTY(bool, is_arglist)
875
+ ADD_PROPERTY(bool, from_selector)
858
876
  public:
859
877
  List(ParserState pstate,
860
878
  size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false)
861
879
  : Value(pstate),
862
880
  Vectorized<Expression*>(size),
863
- separator_(sep), is_arglist_(argl)
881
+ separator_(sep),
882
+ is_arglist_(argl),
883
+ from_selector_(false)
864
884
  { concrete_type(LIST); }
865
885
  std::string type() { return is_arglist_ ? "arglist" : "list"; }
866
886
  static std::string type_name() { return "list"; }
@@ -1011,6 +1031,12 @@ namespace Sass {
1011
1031
  return is_left_interpolant() ||
1012
1032
  is_right_interpolant();
1013
1033
  }
1034
+ virtual bool can_delay() const;
1035
+ void reset_whitespace()
1036
+ {
1037
+ op_.ws_before = false;
1038
+ op_.ws_after = false;
1039
+ }
1014
1040
  virtual void set_delayed(bool delayed)
1015
1041
  {
1016
1042
  right()->set_delayed(delayed);
@@ -1447,6 +1473,9 @@ namespace Sass {
1447
1473
  { concrete_type(STRING); }
1448
1474
  static std::string type_name() { return "string"; }
1449
1475
  virtual ~String() = 0;
1476
+ virtual void rtrim() = 0;
1477
+ virtual void ltrim() = 0;
1478
+ virtual void trim() = 0;
1450
1479
  virtual bool operator==(const Expression& rhs) const = 0;
1451
1480
  ATTACH_OPERATIONS()
1452
1481
  };
@@ -1475,6 +1504,9 @@ namespace Sass {
1475
1504
  }
1476
1505
  return false;
1477
1506
  }
1507
+ virtual void rtrim();
1508
+ virtual void ltrim();
1509
+ virtual void trim();
1478
1510
 
1479
1511
  virtual size_t hash()
1480
1512
  {
@@ -1515,6 +1547,9 @@ namespace Sass {
1515
1547
  std::string type() { return "string"; }
1516
1548
  static std::string type_name() { return "string"; }
1517
1549
  virtual bool is_invisible() const;
1550
+ virtual void rtrim();
1551
+ virtual void ltrim();
1552
+ virtual void trim();
1518
1553
 
1519
1554
  virtual size_t hash()
1520
1555
  {
@@ -1672,42 +1707,15 @@ namespace Sass {
1672
1707
  /////////////////////////////////////////////////
1673
1708
  // At root expressions (for use inside @at-root).
1674
1709
  /////////////////////////////////////////////////
1675
- class At_Root_Expression : public Expression {
1710
+ class At_Root_Query : public Expression {
1676
1711
  private:
1677
- ADD_PROPERTY(String*, feature)
1712
+ ADD_PROPERTY(Expression*, feature)
1678
1713
  ADD_PROPERTY(Expression*, value)
1679
- ADD_PROPERTY(bool, is_interpolated)
1680
1714
  public:
1681
- At_Root_Expression(ParserState pstate, String* f = 0, Expression* v = 0, bool i = false)
1682
- : Expression(pstate), feature_(f), value_(v), is_interpolated_(i)
1715
+ At_Root_Query(ParserState pstate, Expression* f = 0, Expression* v = 0, bool i = false)
1716
+ : Expression(pstate), feature_(f), value_(v)
1683
1717
  { }
1684
- bool exclude(std::string str)
1685
- {
1686
- bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
1687
- List* l = static_cast<List*>(value());
1688
- std::string v;
1689
-
1690
- if (with)
1691
- {
1692
- if (!l || l->length() == 0) return str.compare("rule") != 0;
1693
- for (size_t i = 0, L = l->length(); i < L; ++i)
1694
- {
1695
- v = unquote((*l)[i]->to_string());
1696
- if (v.compare("all") == 0 || v == str) return false;
1697
- }
1698
- return true;
1699
- }
1700
- else
1701
- {
1702
- if (!l || !l->length()) return str.compare("rule") == 0;
1703
- for (size_t i = 0, L = l->length(); i < L; ++i)
1704
- {
1705
- v = unquote((*l)[i]->to_string());
1706
- if (v.compare("all") == 0 || v == str) return true;
1707
- }
1708
- return false;
1709
- }
1710
- }
1718
+ bool exclude(std::string str);
1711
1719
  ATTACH_OPERATIONS()
1712
1720
  };
1713
1721
 
@@ -1715,9 +1723,9 @@ namespace Sass {
1715
1723
  // At-root.
1716
1724
  ///////////
1717
1725
  class At_Root_Block : public Has_Block {
1718
- ADD_PROPERTY(At_Root_Expression*, expression)
1726
+ ADD_PROPERTY(At_Root_Query*, expression)
1719
1727
  public:
1720
- At_Root_Block(ParserState pstate, Block* b = 0, At_Root_Expression* e = 0)
1728
+ At_Root_Block(ParserState pstate, Block* b = 0, At_Root_Query* e = 0)
1721
1729
  : Has_Block(pstate, b), expression_(e)
1722
1730
  { statement_type(ATROOT); }
1723
1731
  bool is_hoistable() { return true; }
@@ -1725,7 +1733,7 @@ namespace Sass {
1725
1733
  bool exclude_node(Statement* s) {
1726
1734
  if (s->statement_type() == Statement::DIRECTIVE)
1727
1735
  {
1728
- return expression()->exclude(static_cast<At_Rule*>(s)->keyword().erase(0, 1));
1736
+ return expression()->exclude(static_cast<Directive*>(s)->keyword().erase(0, 1));
1729
1737
  }
1730
1738
  if (s->statement_type() == Statement::MEDIA)
1731
1739
  {
@@ -1739,7 +1747,7 @@ namespace Sass {
1739
1747
  {
1740
1748
  return expression()->exclude("supports");
1741
1749
  }
1742
- if (static_cast<At_Rule*>(s)->is_keyframes())
1750
+ if (static_cast<Directive*>(s)->is_keyframes())
1743
1751
  {
1744
1752
  return expression()->exclude("keyframes");
1745
1753
  }
@@ -1878,6 +1886,9 @@ namespace Sass {
1878
1886
  virtual unsigned long specificity() {
1879
1887
  return Constants::Specificity_Universal;
1880
1888
  }
1889
+ virtual void set_media_block(Media_Block* mb) {
1890
+ media_block(mb);
1891
+ }
1881
1892
  };
1882
1893
  inline Selector::~Selector() { }
1883
1894
 
@@ -1892,6 +1903,7 @@ namespace Sass {
1892
1903
  Selector_Schema(ParserState pstate, String* c)
1893
1904
  : Selector(pstate), contents_(c), at_root_(false)
1894
1905
  { }
1906
+ virtual bool has_parent_ref();
1895
1907
  virtual size_t hash() {
1896
1908
  if (hash_ == 0) {
1897
1909
  hash_combine(hash_, contents_->hash());
@@ -2140,6 +2152,10 @@ namespace Sass {
2140
2152
  return Constants::Specificity_Type;
2141
2153
  return Constants::Specificity_Pseudo;
2142
2154
  }
2155
+ bool operator==(const Simple_Selector& rhs) const;
2156
+ bool operator==(const Pseudo_Selector& rhs) const;
2157
+ bool operator<(const Simple_Selector& rhs) const;
2158
+ bool operator<(const Pseudo_Selector& rhs) const;
2143
2159
  virtual Compound_Selector* unify_with(Compound_Selector*, Context&);
2144
2160
  ATTACH_OPERATIONS()
2145
2161
  };
@@ -2377,6 +2393,11 @@ namespace Sass {
2377
2393
  if (tail()) sum += tail()->specificity();
2378
2394
  return sum;
2379
2395
  }
2396
+ virtual void set_media_block(Media_Block* mb) {
2397
+ media_block(mb);
2398
+ if (tail_) tail_->set_media_block(mb);
2399
+ if (head_) head_->set_media_block(mb);
2400
+ }
2380
2401
  bool operator<(const Complex_Selector& rhs) const;
2381
2402
  bool operator==(const Complex_Selector& rhs) const;
2382
2403
  inline bool operator!=(const Complex_Selector& rhs) const { return !(*this == rhs); }
@@ -2479,6 +2500,12 @@ namespace Sass {
2479
2500
  }
2480
2501
  return sum;
2481
2502
  }
2503
+ virtual void set_media_block(Media_Block* mb) {
2504
+ media_block(mb);
2505
+ for (Complex_Selector* cs : elements()) {
2506
+ cs->set_media_block(mb);
2507
+ }
2508
+ }
2482
2509
  Selector_List* clone(Context&) const; // does not clone Compound_Selector*s
2483
2510
  Selector_List* cloneFully(Context&) const; // clones Compound_Selector*s
2484
2511
  virtual bool operator==(const Selector& rhs) const;
@@ -17,7 +17,7 @@ namespace Sass {
17
17
  Supports_Query* new_Supports_Query(std::string p, size_t l, Supports_Query* f, Block* b);
18
18
  Media_Query* new_Media_Query(std::string p, size_t l, List* q, Block* b);
19
19
  At_Root_Block* new_At_Root_Block(std::string p, size_t l, Selector* sel, Block* b);
20
- At_Rule* new_At_Rule(std::string p, size_t l, std::string kwd, Selector* sel, Block* b);
20
+ Directive* new_At_Rule(std::string p, size_t l, std::string kwd, Selector* sel, Block* b);
21
21
  Keyframe_Rule* new_Keyframe_Rule(std::string p, size_t l, Block* b);
22
22
  Declaration* new_Declaration(std::string p, size_t l, String* prop, List* vals);
23
23
  Assignment* new_Assignment(std::string p, size_t l, std::string var, Expression* val, bool guarded = false);
@@ -15,7 +15,7 @@ namespace Sass {
15
15
  class Bubble;
16
16
  class Media_Block;
17
17
  class Supports_Block;
18
- class At_Rule;
18
+ class Directive;
19
19
  class Keyframe_Rule;
20
20
  class At_Root_Block;
21
21
  class Declaration;
@@ -62,7 +62,7 @@ namespace Sass {
62
62
  class Supports_Negation;
63
63
  class Supports_Declaration;
64
64
  class Supports_Interpolation;
65
- class At_Root_Expression;
65
+ class At_Root_Query;
66
66
  class Null;
67
67
  class Parent_Selector;
68
68
  // parameters and arguments
@@ -88,10 +88,8 @@ namespace Sass {
88
88
  extern const char progid_kwd[] = "progid";
89
89
  extern const char expression_kwd[] = "expression";
90
90
  extern const char calc_fn_kwd[] = "calc";
91
- extern const char calc_kwd[] = "calc(";
92
- extern const char moz_calc_kwd[] = "-moz-calc(";
93
- extern const char webkit_calc_kwd[] = "-webkit-calc(";
94
- extern const char ms_calc_kwd[] = "-ms-calc(";
91
+
92
+ extern const char almost_any_value_class[] = "\"'#!;{}";
95
93
 
96
94
  // css selector keywords
97
95
  extern const char sel_deep_kwd[] = "/deep/";
@@ -87,11 +87,10 @@ namespace Sass {
87
87
  extern const char odd_kwd[];
88
88
  extern const char progid_kwd[];
89
89
  extern const char expression_kwd[];
90
- extern const char calc_kwd[];
91
90
  extern const char calc_fn_kwd[];
92
- extern const char moz_calc_kwd[];
93
- extern const char webkit_calc_kwd[];
94
- extern const char ms_calc_kwd[];
91
+
92
+ // char classes for "regular expressions"
93
+ extern const char almost_any_value_class[];
95
94
 
96
95
  // css selector keywords
97
96
  extern const char sel_deep_kwd[];
@@ -92,9 +92,9 @@ namespace Sass {
92
92
 
93
93
  // collect more paths from different options
94
94
  collect_include_paths(c_options.include_path);
95
- // collect_include_paths(c_options.include_paths);
95
+ collect_include_paths(c_options.include_paths);
96
96
  collect_plugin_paths(c_options.plugin_path);
97
- // collect_plugin_paths(c_options.plugin_paths);
97
+ collect_plugin_paths(c_options.plugin_paths);
98
98
 
99
99
  // load plugins and register custom behaviors
100
100
  for(auto plug : plugin_paths) plugins.load_plugins(plug);
@@ -162,7 +162,6 @@ namespace Sass {
162
162
 
163
163
  void Context::collect_include_paths(const char* paths_str)
164
164
  {
165
-
166
165
  if (paths_str) {
167
166
  const char* beg = paths_str;
168
167
  const char* end = Prelexer::find_first<PATH_SEP>(beg);
@@ -185,17 +184,17 @@ namespace Sass {
185
184
  }
186
185
  }
187
186
 
188
- void Context::collect_include_paths(const char** paths_array)
187
+ void Context::collect_include_paths(string_list* paths_array)
189
188
  {
190
- if (!paths_array) return;
191
- for (size_t i = 0; paths_array[i]; i++) {
192
- collect_include_paths(paths_array[i]);
189
+ while (paths_array)
190
+ {
191
+ collect_include_paths(paths_array->string);
192
+ paths_array = paths_array->next;
193
193
  }
194
194
  }
195
195
 
196
196
  void Context::collect_plugin_paths(const char* paths_str)
197
197
  {
198
-
199
198
  if (paths_str) {
200
199
  const char* beg = paths_str;
201
200
  const char* end = Prelexer::find_first<PATH_SEP>(beg);
@@ -218,15 +217,15 @@ namespace Sass {
218
217
  }
219
218
  }
220
219
 
221
- void Context::collect_plugin_paths(const char** paths_array)
220
+ void Context::collect_plugin_paths(string_list* paths_array)
222
221
  {
223
- if (!paths_array) return;
224
- for (size_t i = 0; paths_array[i]; i++) {
225
- collect_plugin_paths(paths_array[i]);
222
+ while (paths_array)
223
+ {
224
+ collect_plugin_paths(paths_array->string);
225
+ paths_array = paths_array->next;
226
226
  }
227
227
  }
228
228
 
229
-
230
229
  // resolve the imp_path in base_path or include_paths
231
230
  // looks for alternatives and returns a list from one directory
232
231
  std::vector<Include> Context::find_includes(const Importer& import)
@@ -289,7 +288,7 @@ namespace Sass {
289
288
  const char* contents = resources[idx].contents;
290
289
  // keep a copy of the path around (for parserstates)
291
290
  // ToDo: we clean it, but still not very elegant!?
292
- strings.push_back(sass_strdup(inc.abs_path.c_str()));
291
+ strings.push_back(sass_copy_c_string(inc.abs_path.c_str()));
293
292
  // create the initial parser state from resource
294
293
  ParserState pstate(strings.back(), contents, idx);
295
294
 
@@ -519,7 +518,7 @@ namespace Sass {
519
518
  }
520
519
  // create a copy of the resulting buffer string
521
520
  // this must be freed or taken over by implementor
522
- return sass_strdup(emitted.buffer.c_str());
521
+ return sass_copy_c_string(emitted.buffer.c_str());
523
522
  }
524
523
 
525
524
  void Context::apply_custom_headers(Block* root, const char* ctx_path, ParserState pstate)
@@ -606,7 +605,7 @@ namespace Sass {
606
605
 
607
606
  // ToDo: this may be resolved via custom importers
608
607
  std::string abs_path(rel2abs(entry_path));
609
- char* abs_path_c_str = sass_strdup(abs_path.c_str());
608
+ char* abs_path_c_str = sass_copy_c_string(abs_path.c_str());
610
609
  strings.push_back(abs_path_c_str);
611
610
 
612
611
  // create entry only for the import stack
@@ -693,7 +692,7 @@ namespace Sass {
693
692
  if (source_map_file == "") return 0;
694
693
  char* result = 0;
695
694
  std::string map = emitter.render_srcmap(*this);
696
- result = sass_strdup(map.c_str());
695
+ result = sass_copy_c_string(map.c_str());
697
696
  return result;
698
697
  }
699
698
 
@@ -101,9 +101,9 @@ namespace Sass {
101
101
 
102
102
  private:
103
103
  void collect_plugin_paths(const char* paths_str);
104
- void collect_plugin_paths(const char** paths_array);
104
+ void collect_plugin_paths(string_list* paths_array);
105
105
  void collect_include_paths(const char* paths_str);
106
- void collect_include_paths(const char** paths_array);
106
+ void collect_include_paths(string_list* paths_array);
107
107
  std::string format_embedded_source_map();
108
108
  std::string format_source_mapping_url(const std::string& out_path);
109
109
 
@@ -13,14 +13,22 @@ namespace Sass {
13
13
  : ctx(ctx),
14
14
  block_stack(std::vector<Block*>()),
15
15
  p_stack(std::vector<Statement*>()),
16
+ s_stack(std::vector<Selector_List*>()),
16
17
  backtrace(bt)
17
- { }
18
+ {
19
+ s_stack.push_back(NULL);
20
+ }
18
21
 
19
22
  Statement* Cssize::parent()
20
23
  {
21
24
  return p_stack.size() ? p_stack.back() : block_stack.front();
22
25
  }
23
26
 
27
+ Selector_List* Cssize::selector()
28
+ {
29
+ return s_stack.size() ? s_stack.back() : NULL;
30
+ }
31
+
24
32
  Statement* Cssize::operator()(Block* b)
25
33
  {
26
34
  Block* bb = SASS_MEMORY_NEW(ctx.mem, Block, b->pstate(), b->length(), b->is_root());
@@ -31,7 +39,7 @@ namespace Sass {
31
39
  return bb;
32
40
  }
33
41
 
34
- Statement* Cssize::operator()(At_Rule* r)
42
+ Statement* Cssize::operator()(Directive* r)
35
43
  {
36
44
  if (!r->block() || !r->block()->length()) return r;
37
45
 
@@ -41,7 +49,7 @@ namespace Sass {
41
49
  }
42
50
 
43
51
  p_stack.push_back(r);
44
- At_Rule* rr = SASS_MEMORY_NEW(ctx.mem, At_Rule,
52
+ Directive* rr = SASS_MEMORY_NEW(ctx.mem, Directive,
45
53
  r->pstate(),
46
54
  r->keyword(),
47
55
  r->selector(),
@@ -57,7 +65,7 @@ namespace Sass {
57
65
  else {
58
66
  s = static_cast<Bubble*>(s)->node();
59
67
  if (s->statement_type() != Statement::DIRECTIVE) directive_exists = false;
60
- else directive_exists = (static_cast<At_Rule*>(s)->keyword() == rr->keyword());
68
+ else directive_exists = (static_cast<Directive*>(s)->keyword() == rr->keyword());
61
69
  }
62
70
 
63
71
  }
@@ -65,7 +73,7 @@ namespace Sass {
65
73
  Block* result = SASS_MEMORY_NEW(ctx.mem, Block, rr->pstate());
66
74
  if (!(directive_exists || rr->is_keyframes()))
67
75
  {
68
- At_Rule* empty_node = static_cast<At_Rule*>(rr);
76
+ Directive* empty_node = static_cast<Directive*>(rr);
69
77
  empty_node->block(SASS_MEMORY_NEW(ctx.mem, Block, rr->block() ? rr->block()->pstate() : rr->pstate()));
70
78
  *result << empty_node;
71
79
  }
@@ -93,11 +101,14 @@ namespace Sass {
93
101
  Statement* Cssize::operator()(Ruleset* r)
94
102
  {
95
103
  p_stack.push_back(r);
104
+ s_stack.push_back(dynamic_cast<Selector_List*>(r->selector()));
96
105
  Ruleset* rr = SASS_MEMORY_NEW(ctx.mem, Ruleset,
97
106
  r->pstate(),
98
107
  r->selector(),
99
108
  r->block()->perform(this)->block());
109
+ rr->is_root(r->is_root());
100
110
  // rr->tabs(r->block()->tabs());
111
+ s_stack.pop_back();
101
112
  p_stack.pop_back();
102
113
 
103
114
  if (!rr->block()) {
@@ -213,7 +224,7 @@ namespace Sass {
213
224
  return bubble(m);
214
225
  }
215
226
 
216
- Statement* Cssize::bubble(At_Rule* m)
227
+ Statement* Cssize::bubble(Directive* m)
217
228
  {
218
229
  Block* bb = SASS_MEMORY_NEW(ctx.mem, Block, this->parent()->pstate());
219
230
  Has_Block* new_rule = static_cast<Has_Block*>(shallow_copy(this->parent()));
@@ -227,7 +238,7 @@ namespace Sass {
227
238
 
228
239
  Block* wrapper_block = SASS_MEMORY_NEW(ctx.mem, Block, m->block() ? m->block()->pstate() : m->pstate());
229
240
  *wrapper_block << new_rule;
230
- At_Rule* mm = SASS_MEMORY_NEW(ctx.mem, At_Rule,
241
+ Directive* mm = SASS_MEMORY_NEW(ctx.mem, Directive,
231
242
  m->pstate(),
232
243
  m->keyword(),
233
244
  m->selector(),
@@ -374,7 +385,7 @@ namespace Sass {
374
385
  case Statement::BUBBLE:
375
386
  return SASS_MEMORY_NEW(ctx.mem, Bubble, *static_cast<Bubble*>(s));
376
387
  case Statement::DIRECTIVE:
377
- return SASS_MEMORY_NEW(ctx.mem, At_Rule, *static_cast<At_Rule*>(s));
388
+ return SASS_MEMORY_NEW(ctx.mem, Directive, *static_cast<Directive*>(s));
378
389
  case Statement::SUPPORTS:
379
390
  return SASS_MEMORY_NEW(ctx.mem, Supports_Block, *static_cast<Supports_Block*>(s));
380
391
  case Statement::ATROOT: