sassc 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: