sassc 1.11.4 → 1.12.0

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