sassc 1.11.4 → 1.12.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 (137) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +2 -2
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/README.md +4 -1
  5. data/ext/libsass/.editorconfig +1 -1
  6. data/ext/libsass/.github/CONTRIBUTING.md +7 -7
  7. data/ext/libsass/.github/ISSUE_TEMPLATE.md +31 -6
  8. data/ext/libsass/.gitignore +3 -0
  9. data/ext/libsass/.travis.yml +37 -18
  10. data/ext/libsass/GNUmakefile.am +23 -37
  11. data/ext/libsass/Makefile +10 -6
  12. data/ext/libsass/Makefile.conf +3 -0
  13. data/ext/libsass/Readme.md +68 -63
  14. data/ext/libsass/appveyor.yml +7 -3
  15. data/ext/libsass/configure.ac +10 -14
  16. data/ext/libsass/docs/api-context-internal.md +29 -21
  17. data/ext/libsass/docs/api-context.md +26 -6
  18. data/ext/libsass/docs/api-doc.md +49 -16
  19. data/ext/libsass/docs/api-function-example.md +1 -1
  20. data/ext/libsass/docs/api-function.md +31 -7
  21. data/ext/libsass/docs/api-importer.md +19 -19
  22. data/ext/libsass/docs/api-value.md +4 -2
  23. data/ext/libsass/docs/build-on-windows.md +4 -4
  24. data/ext/libsass/docs/build-with-mingw.md +3 -3
  25. data/ext/libsass/docs/build.md +9 -9
  26. data/ext/libsass/docs/custom-functions-internal.md +10 -8
  27. data/ext/libsass/docs/implementations.md +20 -8
  28. data/ext/libsass/docs/unicode.md +16 -10
  29. data/ext/libsass/include/sass/base.h +0 -3
  30. data/ext/libsass/include/sass/context.h +20 -2
  31. data/ext/libsass/include/sass/functions.h +31 -0
  32. data/ext/libsass/include/sass/values.h +3 -1
  33. data/ext/libsass/include/sass/version.h +1 -1
  34. data/ext/libsass/include/sass/version.h.in +1 -1
  35. data/ext/libsass/include/sass2scss.h +1 -1
  36. data/ext/libsass/res/resource.rc +6 -6
  37. data/ext/libsass/script/ci-build-libsass +10 -5
  38. data/ext/libsass/script/ci-build-plugin +62 -0
  39. data/ext/libsass/script/ci-install-compiler +1 -1
  40. data/ext/libsass/script/ci-install-deps +4 -7
  41. data/ext/libsass/script/ci-report-coverage +13 -3
  42. data/ext/libsass/script/tap-driver +1 -1
  43. data/ext/libsass/script/tap-runner +1 -1
  44. data/ext/libsass/src/GNUmakefile.am +1 -1
  45. data/ext/libsass/src/ast.cpp +537 -762
  46. data/ext/libsass/src/ast.hpp +377 -419
  47. data/ext/libsass/src/ast_def_macros.hpp +26 -1
  48. data/ext/libsass/src/ast_fwd_decl.cpp +29 -0
  49. data/ext/libsass/src/ast_fwd_decl.hpp +94 -21
  50. data/ext/libsass/src/b64/encode.h +3 -1
  51. data/ext/libsass/src/backtrace.cpp +46 -0
  52. data/ext/libsass/src/backtrace.hpp +7 -54
  53. data/ext/libsass/src/bind.cpp +72 -50
  54. data/ext/libsass/src/bind.hpp +0 -1
  55. data/ext/libsass/src/cencode.c +6 -0
  56. data/ext/libsass/src/check_nesting.cpp +157 -135
  57. data/ext/libsass/src/check_nesting.hpp +11 -10
  58. data/ext/libsass/src/color_maps.cpp +10 -6
  59. data/ext/libsass/src/color_maps.hpp +6 -8
  60. data/ext/libsass/src/constants.cpp +4 -3
  61. data/ext/libsass/src/constants.hpp +4 -3
  62. data/ext/libsass/src/context.cpp +110 -47
  63. data/ext/libsass/src/context.hpp +11 -1
  64. data/ext/libsass/src/cssize.cpp +105 -94
  65. data/ext/libsass/src/cssize.hpp +4 -5
  66. data/ext/libsass/src/debugger.hpp +247 -244
  67. data/ext/libsass/src/emitter.cpp +30 -6
  68. data/ext/libsass/src/emitter.hpp +7 -0
  69. data/ext/libsass/src/environment.cpp +67 -16
  70. data/ext/libsass/src/environment.hpp +28 -7
  71. data/ext/libsass/src/error_handling.cpp +92 -64
  72. data/ext/libsass/src/error_handling.hpp +64 -43
  73. data/ext/libsass/src/eval.cpp +494 -544
  74. data/ext/libsass/src/eval.hpp +17 -23
  75. data/ext/libsass/src/expand.cpp +182 -154
  76. data/ext/libsass/src/expand.hpp +4 -5
  77. data/ext/libsass/src/extend.cpp +299 -291
  78. data/ext/libsass/src/extend.hpp +46 -11
  79. data/ext/libsass/src/file.cpp +103 -36
  80. data/ext/libsass/src/file.hpp +21 -4
  81. data/ext/libsass/src/functions.cpp +561 -312
  82. data/ext/libsass/src/functions.hpp +8 -5
  83. data/ext/libsass/src/inspect.cpp +108 -53
  84. data/ext/libsass/src/inspect.hpp +5 -2
  85. data/ext/libsass/src/lexer.cpp +15 -7
  86. data/ext/libsass/src/lexer.hpp +13 -4
  87. data/ext/libsass/src/listize.cpp +3 -2
  88. data/ext/libsass/src/listize.hpp +0 -1
  89. data/ext/libsass/src/memory/SharedPtr.cpp +16 -18
  90. data/ext/libsass/src/memory/SharedPtr.hpp +47 -43
  91. data/ext/libsass/src/node.cpp +34 -38
  92. data/ext/libsass/src/node.hpp +6 -8
  93. data/ext/libsass/src/operation.hpp +2 -2
  94. data/ext/libsass/src/operators.cpp +240 -0
  95. data/ext/libsass/src/operators.hpp +30 -0
  96. data/ext/libsass/src/output.cpp +22 -20
  97. data/ext/libsass/src/parser.cpp +719 -358
  98. data/ext/libsass/src/parser.hpp +57 -22
  99. data/ext/libsass/src/plugins.cpp +28 -10
  100. data/ext/libsass/src/position.cpp +21 -3
  101. data/ext/libsass/src/position.hpp +2 -1
  102. data/ext/libsass/src/prelexer.cpp +104 -19
  103. data/ext/libsass/src/prelexer.hpp +10 -3
  104. data/ext/libsass/src/remove_placeholders.cpp +9 -10
  105. data/ext/libsass/src/remove_placeholders.hpp +1 -5
  106. data/ext/libsass/src/sass.cpp +62 -4
  107. data/ext/libsass/src/sass.hpp +5 -2
  108. data/ext/libsass/src/sass_context.cpp +96 -58
  109. data/ext/libsass/src/sass_context.hpp +7 -5
  110. data/ext/libsass/src/sass_functions.cpp +63 -1
  111. data/ext/libsass/src/sass_functions.hpp +19 -1
  112. data/ext/libsass/src/sass_util.cpp +3 -3
  113. data/ext/libsass/src/sass_util.hpp +4 -4
  114. data/ext/libsass/src/sass_values.cpp +42 -39
  115. data/ext/libsass/src/sass_values.hpp +2 -1
  116. data/ext/libsass/src/source_map.cpp +16 -18
  117. data/ext/libsass/src/subset_map.cpp +6 -8
  118. data/ext/libsass/src/subset_map.hpp +6 -6
  119. data/ext/libsass/src/to_c.cpp +2 -2
  120. data/ext/libsass/src/to_value.cpp +8 -3
  121. data/ext/libsass/src/to_value.hpp +1 -0
  122. data/ext/libsass/src/units.cpp +349 -45
  123. data/ext/libsass/src/units.hpp +39 -22
  124. data/ext/libsass/src/utf8/checked.h +7 -0
  125. data/ext/libsass/src/utf8/unchecked.h +7 -0
  126. data/ext/libsass/src/utf8_string.cpp +1 -1
  127. data/ext/libsass/src/util.cpp +139 -45
  128. data/ext/libsass/src/util.hpp +4 -7
  129. data/ext/libsass/src/values.cpp +15 -23
  130. data/ext/libsass/win/libsass.sln +13 -2
  131. data/ext/libsass/win/libsass.sln.DotSettings +9 -0
  132. data/ext/libsass/win/libsass.targets +3 -0
  133. data/ext/libsass/win/libsass.vcxproj.filters +9 -0
  134. data/lib/sassc/version.rb +1 -1
  135. data/sassc.gemspec +1 -1
  136. data/test/native_test.rb +1 -1
  137. metadata +11 -4
@@ -46,7 +46,7 @@ namespace Sass {
46
46
  src = exactly<beg>(src);
47
47
  if (!src) return 0;
48
48
  const char* stop;
49
- while (1) {
49
+ while (true) {
50
50
  if (!*src) return 0;
51
51
  stop = exactly<end>(src);
52
52
  if (stop && (!esc || *(src - 1) != '\\')) return stop;
@@ -139,7 +139,7 @@ namespace Sass {
139
139
  src = exactly<beg>(src);
140
140
  if (!src) return 0;
141
141
  const char* stop;
142
- while (1) {
142
+ while (true) {
143
143
  if (!*src) return 0;
144
144
  stop = exactly<end>(src);
145
145
  if (stop && (!esc || *(src - 1) != '\\')) return stop;
@@ -264,7 +264,6 @@ namespace Sass {
264
264
  const char* kwd_while_directive(const char* src);
265
265
 
266
266
  const char* re_nothing(const char* src);
267
- const char* re_type_selector2(const char* src);
268
267
 
269
268
  const char* re_special_fun(const char* src);
270
269
 
@@ -355,6 +354,10 @@ namespace Sass {
355
354
  const char* ie_keyword_arg_value(const char* src);
356
355
  const char* ie_keyword_arg_property(const char* src);
357
356
 
357
+ // characters that terminate parsing of a list
358
+ const char* list_terminator(const char* src);
359
+ const char* space_list_terminator(const char* src);
360
+
358
361
  // match url()
359
362
  const char* H(const char* src);
360
363
  const char* W(const char* src);
@@ -362,6 +365,7 @@ namespace Sass {
362
365
  const char* UUNICODE(const char* src);
363
366
  const char* NONASCII(const char* src);
364
367
  const char* ESCAPE(const char* src);
368
+ const char* real_uri(const char* src);
365
369
  const char* real_uri_suffix(const char* src);
366
370
  // const char* real_uri_prefix(const char* src);
367
371
  const char* real_uri_value(const char* src);
@@ -376,6 +380,9 @@ namespace Sass {
376
380
  const char* static_property(const char* src);
377
381
  const char* static_value(const char* src);
378
382
 
383
+ const char* css_variable_value(const char* src);
384
+ const char* css_variable_top_level_value(const char* src);
385
+
379
386
  // Utility functions for finding and counting characters in a string.
380
387
  template<char c>
381
388
  const char* find_first(const char* src) {
@@ -6,13 +6,12 @@
6
6
 
7
7
  namespace Sass {
8
8
 
9
- Remove_Placeholders::Remove_Placeholders(Context& ctx)
10
- : ctx(ctx)
9
+ Remove_Placeholders::Remove_Placeholders()
11
10
  { }
12
11
 
13
12
  void Remove_Placeholders::operator()(Block_Ptr b) {
14
13
  for (size_t i = 0, L = b->length(); i < L; ++i) {
15
- Statement_Ptr st = &b->at(i);
14
+ Statement_Ptr st = b->at(i);
16
15
  st->perform(this);
17
16
  }
18
17
  }
@@ -34,19 +33,19 @@ namespace Sass {
34
33
 
35
34
  void Remove_Placeholders::operator()(Ruleset_Ptr r) {
36
35
  // Create a new selector group without placeholders
37
- Selector_List_Obj sl = SASS_MEMORY_CAST(Selector_List, r->selector());
36
+ Selector_List_Obj sl = Cast<Selector_List>(r->selector());
38
37
 
39
38
  if (sl) {
40
39
  // Set the new placeholder selector list
41
- r->selector(remove_placeholders(&sl));
40
+ r->selector(remove_placeholders(sl));
42
41
  // Remove placeholders in wrapped selectors
43
42
  for (Complex_Selector_Obj cs : sl->elements()) {
44
43
  while (cs) {
45
44
  if (cs->head()) {
46
45
  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);
46
+ if (Wrapped_Selector_Ptr ws = Cast<Wrapped_Selector>(ss)) {
47
+ if (Selector_List_Ptr wsl = Cast<Selector_List>(ws->selector())) {
48
+ Selector_List_Ptr clean = remove_placeholders(wsl);
50
49
  // also clean superflous parent selectors
51
50
  // probably not really the correct place
52
51
  clean->remove_parent_selectors();
@@ -72,10 +71,10 @@ namespace Sass {
72
71
  }
73
72
 
74
73
  void Remove_Placeholders::operator()(Media_Block_Ptr m) {
75
- operator()(&m->block());
74
+ operator()(m->block());
76
75
  }
77
76
  void Remove_Placeholders::operator()(Supports_Block_Ptr m) {
78
- operator()(&m->block());
77
+ operator()(m->block());
79
78
  }
80
79
 
81
80
  void Remove_Placeholders::operator()(Directive_Ptr a) {
@@ -9,19 +9,15 @@
9
9
  namespace Sass {
10
10
 
11
11
 
12
- class Context;
13
-
14
12
  class Remove_Placeholders : public Operation_CRTP<void, Remove_Placeholders> {
15
13
 
16
- Context& ctx;
17
-
18
14
  void fallback_impl(AST_Node_Ptr n) {}
19
15
 
20
16
  public:
21
17
  Selector_List_Ptr remove_placeholders(Selector_List_Ptr);
22
18
 
23
19
  public:
24
- Remove_Placeholders(Context&);
20
+ Remove_Placeholders();
25
21
  ~Remove_Placeholders() { }
26
22
 
27
23
  void operator()(Block_Ptr);
@@ -7,6 +7,23 @@
7
7
  #include "sass.h"
8
8
  #include "file.hpp"
9
9
  #include "util.hpp"
10
+ #include "sass_context.hpp"
11
+ #include "sass_functions.hpp"
12
+
13
+ namespace Sass {
14
+
15
+ // helper to convert string list to vector
16
+ std::vector<std::string> list2vec(struct string_list* cur)
17
+ {
18
+ std::vector<std::string> list;
19
+ while (cur) {
20
+ list.push_back(cur->string);
21
+ cur = cur->next;
22
+ }
23
+ return list;
24
+ }
25
+
26
+ }
10
27
 
11
28
  extern "C" {
12
29
  using namespace Sass;
@@ -16,8 +33,10 @@ extern "C" {
16
33
  void* ADDCALL sass_alloc_memory(size_t size)
17
34
  {
18
35
  void* ptr = malloc(size);
19
- if (ptr == NULL)
20
- out_of_memory();
36
+ if (ptr == NULL) {
37
+ std::cerr << "Out of memory.\n";
38
+ exit(EXIT_FAILURE);
39
+ }
21
40
  return ptr;
22
41
  }
23
42
 
@@ -49,11 +68,50 @@ extern "C" {
49
68
  return sass_copy_c_string(unquoted.c_str());
50
69
  }
51
70
 
71
+ char* ADDCALL sass_compiler_find_include (const char* file, struct Sass_Compiler* compiler)
72
+ {
73
+ // get the last import entry to get current base directory
74
+ Sass_Import_Entry import = sass_compiler_get_last_import(compiler);
75
+ const std::vector<std::string>& incs = compiler->cpp_ctx->include_paths;
76
+ // create the vector with paths to lookup
77
+ std::vector<std::string> paths(1 + incs.size());
78
+ paths.push_back(File::dir_name(import->abs_path));
79
+ paths.insert( paths.end(), incs.begin(), incs.end() );
80
+ // now resolve the file path relative to lookup paths
81
+ std::string resolved(File::find_include(file, paths));
82
+ return sass_copy_c_string(resolved.c_str());
83
+ }
84
+
85
+ char* ADDCALL sass_compiler_find_file (const char* file, struct Sass_Compiler* compiler)
86
+ {
87
+ // get the last import entry to get current base directory
88
+ Sass_Import_Entry import = sass_compiler_get_last_import(compiler);
89
+ const std::vector<std::string>& incs = compiler->cpp_ctx->include_paths;
90
+ // create the vector with paths to lookup
91
+ std::vector<std::string> paths(1 + incs.size());
92
+ paths.push_back(File::dir_name(import->abs_path));
93
+ paths.insert( paths.end(), incs.begin(), incs.end() );
94
+ // now resolve the file path relative to lookup paths
95
+ std::string resolved(File::find_file(file, paths));
96
+ return sass_copy_c_string(resolved.c_str());
97
+ }
98
+
52
99
  // Make sure to free the returned value!
53
100
  // Incs array has to be null terminated!
54
- char* ADDCALL sass_resolve_file (const char* file, const char* paths[])
101
+ // this has the original resolve logic for sass include
102
+ char* ADDCALL sass_find_include (const char* file, struct Sass_Options* opt)
55
103
  {
56
- std::string resolved(File::find_file(file, paths));
104
+ std::vector<std::string> vec(list2vec(opt->include_paths));
105
+ std::string resolved(File::find_include(file, vec));
106
+ return sass_copy_c_string(resolved.c_str());
107
+ }
108
+
109
+ // Make sure to free the returned value!
110
+ // Incs array has to be null terminated!
111
+ char* ADDCALL sass_find_file (const char* file, struct Sass_Options* opt)
112
+ {
113
+ std::vector<std::string> vec(list2vec(opt->include_paths));
114
+ std::string resolved(File::find_file(file, vec));
57
115
  return sass_copy_c_string(resolved.c_str());
58
116
  }
59
117
 
@@ -90,10 +90,13 @@ struct Sass_Inspect_Options {
90
90
  // Precision for fractional numbers
91
91
  int precision;
92
92
 
93
+ // Do not compress colors in selectors
94
+ bool in_selector;
95
+
93
96
  // initialization list (constructor with defaults)
94
97
  Sass_Inspect_Options(Sass_Output_Style style = Sass::NESTED,
95
- int precision = 5)
96
- : output_style(style), precision(precision)
98
+ int precision = 5, bool in_selector = false)
99
+ : output_style(style), precision(precision), in_selector(in_selector)
97
100
  { }
98
101
 
99
102
  };
@@ -35,7 +35,6 @@ namespace Sass {
35
35
  catch (Exception::Base& e) {
36
36
  std::stringstream msg_stream;
37
37
  std::string cwd(Sass::File::get_cwd());
38
-
39
38
  std::string msg_prefix(e.errtype());
40
39
  bool got_newline = false;
41
40
  msg_stream << msg_prefix << ": ";
@@ -55,41 +54,49 @@ namespace Sass {
55
54
  ++msg;
56
55
  }
57
56
  if (!got_newline) msg_stream << "\n";
58
- if (e.import_stack) {
59
- for (size_t i = 1; i < e.import_stack->size() - 1; ++i) {
60
- std::string path((*e.import_stack)[i]->imp_path);
61
- std::string rel_path(Sass::File::abs2rel(path, cwd, cwd));
62
- msg_stream << std::string(msg_prefix.size() + 2, ' ');
63
- msg_stream << (i == 1 ? " on line " : " from line ");
64
- msg_stream << e.pstate.line + 1 << " of " << rel_path << "\n";
65
- }
66
- }
67
- else {
57
+
58
+ if (e.traces.empty()) {
59
+ // we normally should have some traces, still here as a fallback
68
60
  std::string rel_path(Sass::File::abs2rel(e.pstate.path, cwd, cwd));
69
61
  msg_stream << std::string(msg_prefix.size() + 2, ' ');
70
62
  msg_stream << " on line " << e.pstate.line + 1 << " of " << rel_path << "\n";
71
63
  }
64
+ else {
65
+ std::string rel_path(Sass::File::abs2rel(e.pstate.path, cwd, cwd));
66
+ msg_stream << traces_to_string(e.traces, " ");
67
+ }
72
68
 
73
69
  // now create the code trace (ToDo: maybe have util functions?)
74
70
  if (e.pstate.line != std::string::npos && e.pstate.column != std::string::npos) {
75
- size_t line = e.pstate.line;
71
+ size_t lines = e.pstate.line;
76
72
  const char* line_beg = e.pstate.src;
77
- while (line_beg && *line_beg && line) {
78
- if (*line_beg == '\n') --line;
79
- ++line_beg;
73
+ // scan through src until target line
74
+ // move line_beg pointer to line start
75
+ while (line_beg && *line_beg && lines != 0) {
76
+ if (*line_beg == '\n') --lines;
77
+ utf8::unchecked::next(line_beg);
80
78
  }
81
79
  const char* line_end = line_beg;
80
+ // move line_end before next newline character
82
81
  while (line_end && *line_end && *line_end != '\n') {
83
82
  if (*line_end == '\n') break;
84
83
  if (*line_end == '\r') break;
85
- line_end++;
84
+ utf8::unchecked::next(line_end);
86
85
  }
87
- size_t max_left = 42; size_t max_right = 78;
88
- size_t move_in = e.pstate.column > max_left ? e.pstate.column - max_left : 0;
89
- size_t shorten = (line_end - line_beg) - move_in > max_right ?
90
- (line_end - line_beg) - move_in - max_right : 0;
91
- msg_stream << ">> " << std::string(line_beg + move_in, line_end - shorten) << "\n";
92
- msg_stream << " " << std::string(e.pstate.column - move_in, '-') << "^\n";
86
+ if (line_end && *line_end != 0) ++ line_end;
87
+ size_t line_len = line_end - line_beg;
88
+ size_t move_in = 0; size_t shorten = 0;
89
+ size_t left_chars = 42; size_t max_chars = 76;
90
+ // reported excerpt should not exceed `max_chars` chars
91
+ if (e.pstate.column > line_len) left_chars = e.pstate.column;
92
+ if (e.pstate.column > left_chars) move_in = e.pstate.column - left_chars;
93
+ if (line_len > max_chars + move_in) shorten = line_len - move_in - max_chars;
94
+ utf8::advance(line_beg, move_in, line_end);
95
+ utf8::retreat(line_end, shorten, line_beg);
96
+ std::string sanitized; std::string marker(e.pstate.column - move_in, '-');
97
+ utf8::replace_invalid(line_beg, line_end, std::back_inserter(sanitized));
98
+ msg_stream << ">> " << sanitized << "\n";
99
+ msg_stream << " " << marker << "^\n";
93
100
  }
94
101
 
95
102
  JsonNode* json_err = json_mkobject();
@@ -199,7 +206,6 @@ namespace Sass {
199
206
  static int handle_errors(Sass_Context* c_ctx) {
200
207
  try { return handle_error(c_ctx); }
201
208
  catch (...) { return handle_error(c_ctx); }
202
- return c_ctx->error_status;
203
209
  }
204
210
 
205
211
  static Block_Obj sass_parse_block(Sass_Compiler* compiler) throw()
@@ -272,10 +278,14 @@ extern "C" {
272
278
  #define IMPLEMENT_SASS_OPTION_ACCESSOR(type, option) \
273
279
  type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return options->option; } \
274
280
  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); } \
281
+ #define IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \
282
+ type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return safe_str(options->option, def); }
283
+ #define IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def) \
277
284
  void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) \
278
285
  { free(options->option); options->option = option || def ? sass_copy_c_string(option ? option : def) : 0; }
286
+ #define IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(type, option, def) \
287
+ IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \
288
+ IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def)
279
289
 
280
290
  #define IMPLEMENT_SASS_CONTEXT_GETTER(type, option) \
281
291
  type ADDCALL sass_context_get_##option (struct Sass_Context* ctx) { return ctx->option; }
@@ -327,7 +337,9 @@ extern "C" {
327
337
  c_ctx->error_column = std::string::npos;
328
338
 
329
339
  // allocate a new compiler instance
330
- Sass_Compiler* compiler = (struct Sass_Compiler*) calloc(1, sizeof(struct Sass_Compiler));
340
+ void* ctxmem = calloc(1, sizeof(struct Sass_Compiler));
341
+ if (ctxmem == 0) { std::cerr << "Error allocating memory for context" << std::endl; return 0; }
342
+ Sass_Compiler* compiler = (struct Sass_Compiler*) ctxmem;
331
343
  compiler->state = SASS_COMPILER_CREATED;
332
344
 
333
345
  // store in sass compiler
@@ -468,7 +480,7 @@ extern "C" {
468
480
  if (compiler->c_ctx->error_status)
469
481
  return compiler->c_ctx->error_status;
470
482
  // parse the context we have set up (file or data)
471
- compiler->root = &sass_parse_block(compiler);
483
+ compiler->root = sass_parse_block(compiler);
472
484
  // success
473
485
  return 0;
474
486
  }
@@ -512,36 +524,17 @@ extern "C" {
512
524
  options->c_headers = 0;
513
525
  options->plugin_paths = 0;
514
526
  options->include_paths = 0;
527
+ options->extensions = 0;
515
528
  }
516
529
 
517
530
  // helper function, not exported, only accessible locally
518
531
  static void sass_clear_options (struct Sass_Options* options)
519
532
  {
520
533
  if (options == 0) return;
521
- // Deallocate custom functions
522
- if (options->c_functions) {
523
- Sass_Function_List this_func_data = options->c_functions;
524
- while (this_func_data && *this_func_data) {
525
- free(*this_func_data);
526
- ++this_func_data;
527
- }
528
- }
529
- // Deallocate custom headers
530
- if (options->c_headers) {
531
- Sass_Importer_List this_head_data = options->c_headers;
532
- while (this_head_data && *this_head_data) {
533
- free(*this_head_data);
534
- ++this_head_data;
535
- }
536
- }
537
- // Deallocate custom importers
538
- if (options->c_importers) {
539
- Sass_Importer_List this_imp_data = options->c_importers;
540
- while (this_imp_data && *this_imp_data) {
541
- free(*this_imp_data);
542
- ++this_imp_data;
543
- }
544
- }
534
+ // Deallocate custom functions, headers and importes
535
+ sass_delete_function_list(options->c_functions);
536
+ sass_delete_importer_list(options->c_importers);
537
+ sass_delete_importer_list(options->c_headers);
545
538
  // Deallocate inc paths
546
539
  if (options->plugin_paths) {
547
540
  struct string_list* cur;
@@ -566,6 +559,18 @@ extern "C" {
566
559
  cur = next;
567
560
  }
568
561
  }
562
+ // Deallocate extension
563
+ if (options->extensions) {
564
+ struct string_list* cur;
565
+ struct string_list* next;
566
+ cur = options->extensions;
567
+ while (cur) {
568
+ next = cur->next;
569
+ free(cur->string);
570
+ free(cur);
571
+ cur = next;
572
+ }
573
+ }
569
574
  // Free options strings
570
575
  free(options->input_path);
571
576
  free(options->output_path);
@@ -573,11 +578,6 @@ extern "C" {
573
578
  free(options->include_path);
574
579
  free(options->source_map_file);
575
580
  free(options->source_map_root);
576
- // Free custom functions
577
- free(options->c_functions);
578
- // Free custom importers
579
- free(options->c_importers);
580
- free(options->c_headers);
581
581
  // Reset our pointers
582
582
  options->input_path = 0;
583
583
  options->output_path = 0;
@@ -590,6 +590,7 @@ extern "C" {
590
590
  options->c_headers = 0;
591
591
  options->plugin_paths = 0;
592
592
  options->include_paths = 0;
593
+ options->extensions = 0;
593
594
  }
594
595
 
595
596
  // helper function, not exported, only accessible locally
@@ -674,6 +675,10 @@ extern "C" {
674
675
  size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.size(); }
675
676
  Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.back(); }
676
677
  Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx) { return compiler->cpp_ctx->import_stack[idx]; }
678
+ // Getters for Sass_Compiler options (query function stack)
679
+ size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->callee_stack.size(); }
680
+ Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler) { return &compiler->cpp_ctx->callee_stack.back(); }
681
+ Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx) { return &compiler->cpp_ctx->callee_stack[idx]; }
677
682
 
678
683
  // Calculate the size of the stored null terminated array
679
684
  size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx)
@@ -693,10 +698,10 @@ extern "C" {
693
698
  IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_headers);
694
699
  IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, indent);
695
700
  IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, linefeed);
701
+ IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, plugin_path, 0);
702
+ IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, include_path, 0);
696
703
  IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, input_path, 0);
697
704
  IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, output_path, 0);
698
- IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, plugin_path, 0);
699
- IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, include_path, 0);
700
705
  IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_file, 0);
701
706
  IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_root, 0);
702
707
 
@@ -722,6 +727,22 @@ extern "C" {
722
727
  IMPLEMENT_SASS_CONTEXT_TAKER(char*, source_map_string);
723
728
  IMPLEMENT_SASS_CONTEXT_TAKER(char**, included_files);
724
729
 
730
+ // Push function for import extenions
731
+ void ADDCALL sass_option_push_import_extension(struct Sass_Options* options, const char* ext)
732
+ {
733
+ struct string_list* extension = (struct string_list*) calloc(1, sizeof(struct string_list));
734
+ if (extension == 0) return;
735
+ extension->string = ext ? sass_copy_c_string(ext) : 0;
736
+ struct string_list* last = options->extensions;
737
+ if (!options->extensions) {
738
+ options->extensions = extension;
739
+ } else {
740
+ while (last->next)
741
+ last = last->next;
742
+ last->next = extension;
743
+ }
744
+ }
745
+
725
746
  // Push function for include paths (no manipulation support for now)
726
747
  void ADDCALL sass_option_push_include_path(struct Sass_Options* options, const char* path)
727
748
  {
@@ -740,6 +761,23 @@ extern "C" {
740
761
 
741
762
  }
742
763
 
764
+ // Push function for include paths (no manipulation support for now)
765
+ size_t ADDCALL sass_option_get_include_path_size(struct Sass_Options* options)
766
+ {
767
+ size_t len = 0;
768
+ struct string_list* cur = options->include_paths;
769
+ while (cur) { len ++; cur = cur->next; }
770
+ return len;
771
+ }
772
+
773
+ // Push function for include paths (no manipulation support for now)
774
+ const char* ADDCALL sass_option_get_include_path(struct Sass_Options* options, size_t i)
775
+ {
776
+ struct string_list* cur = options->include_paths;
777
+ while (i) { i--; cur = cur->next; }
778
+ return cur->string;
779
+ }
780
+
743
781
  // Push function for plugin paths (no manipulation support for now)
744
782
  void ADDCALL sass_option_push_plugin_path(struct Sass_Options* options, const char* path)
745
783
  {