sassc 0.0.10 → 0.0.11

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/libsass/.gitignore +6 -0
  4. data/ext/libsass/.travis.yml +5 -1
  5. data/ext/libsass/Makefile +12 -3
  6. data/ext/libsass/Makefile.am +16 -28
  7. data/ext/libsass/Readme.md +1 -0
  8. data/ext/libsass/appveyor.yml +1 -2
  9. data/ext/libsass/ast.cpp +9 -0
  10. data/ext/libsass/ast.hpp +152 -55
  11. data/ext/libsass/ast_factory.hpp +2 -0
  12. data/ext/libsass/ast_fwd_decl.hpp +1 -0
  13. data/ext/libsass/backtrace.hpp +2 -2
  14. data/ext/libsass/bind.cpp +15 -13
  15. data/ext/libsass/configure.ac +17 -5
  16. data/ext/libsass/constants.cpp +22 -2
  17. data/ext/libsass/constants.hpp +21 -2
  18. data/ext/libsass/context.cpp +79 -57
  19. data/ext/libsass/context.hpp +23 -9
  20. data/ext/libsass/contextualize.cpp +2 -28
  21. data/ext/libsass/contextualize.hpp +6 -10
  22. data/ext/libsass/contextualize_eval.cpp +93 -0
  23. data/ext/libsass/contextualize_eval.hpp +44 -0
  24. data/ext/libsass/contrib/plugin.cpp +57 -0
  25. data/ext/libsass/cssize.cpp +3 -1
  26. data/ext/libsass/debugger.hpp +242 -83
  27. data/ext/libsass/emitter.cpp +1 -1
  28. data/ext/libsass/emitter.hpp +1 -1
  29. data/ext/libsass/environment.hpp +109 -25
  30. data/ext/libsass/error_handling.cpp +3 -3
  31. data/ext/libsass/error_handling.hpp +0 -1
  32. data/ext/libsass/eval.cpp +145 -61
  33. data/ext/libsass/eval.hpp +9 -1
  34. data/ext/libsass/expand.cpp +134 -60
  35. data/ext/libsass/expand.hpp +5 -2
  36. data/ext/libsass/extend.cpp +7 -5
  37. data/ext/libsass/file.cpp +176 -123
  38. data/ext/libsass/file.hpp +44 -7
  39. data/ext/libsass/functions.cpp +36 -17
  40. data/ext/libsass/functions.hpp +2 -2
  41. data/ext/libsass/inspect.cpp +23 -14
  42. data/ext/libsass/inspect.hpp +1 -0
  43. data/ext/libsass/json.cpp +132 -135
  44. data/ext/libsass/lexer.cpp +133 -0
  45. data/ext/libsass/lexer.hpp +239 -0
  46. data/ext/libsass/listize.cpp +83 -0
  47. data/ext/libsass/listize.hpp +41 -0
  48. data/ext/libsass/operation.hpp +2 -0
  49. data/ext/libsass/output.cpp +5 -6
  50. data/ext/libsass/parser.cpp +426 -388
  51. data/ext/libsass/parser.hpp +97 -109
  52. data/ext/libsass/plugins.cpp +15 -2
  53. data/ext/libsass/plugins.hpp +6 -4
  54. data/ext/libsass/position.cpp +52 -17
  55. data/ext/libsass/position.hpp +19 -17
  56. data/ext/libsass/prelexer.cpp +202 -235
  57. data/ext/libsass/prelexer.hpp +73 -333
  58. data/ext/libsass/sass.cpp +21 -11
  59. data/ext/libsass/sass.h +6 -6
  60. data/ext/libsass/sass_context.cpp +167 -81
  61. data/ext/libsass/sass_context.h +26 -6
  62. data/ext/libsass/sass_functions.cpp +49 -40
  63. data/ext/libsass/sass_functions.h +55 -43
  64. data/ext/libsass/sass_interface.cpp +9 -8
  65. data/ext/libsass/sass_interface.h +3 -3
  66. data/ext/libsass/sass_version.h +8 -0
  67. data/ext/libsass/sass_version.h.in +8 -0
  68. data/ext/libsass/script/ci-build-libsass +3 -3
  69. data/ext/libsass/script/ci-report-coverage +2 -1
  70. data/ext/libsass/source_map.cpp +2 -2
  71. data/ext/libsass/util.cpp +60 -11
  72. data/ext/libsass/util.hpp +6 -1
  73. data/ext/libsass/win/libsass.filters +12 -0
  74. data/ext/libsass/win/libsass.vcxproj +10 -0
  75. data/lib/sassc.rb +3 -1
  76. data/lib/sassc/cache_stores/base.rb +2 -0
  77. data/lib/sassc/dependency.rb +3 -1
  78. data/lib/sassc/engine.rb +31 -16
  79. data/lib/sassc/error.rb +3 -2
  80. data/lib/sassc/functions_handler.rb +54 -0
  81. data/lib/sassc/import_handler.rb +41 -0
  82. data/lib/sassc/importer.rb +4 -31
  83. data/lib/sassc/native.rb +1 -1
  84. data/lib/sassc/native/native_context_api.rb +3 -2
  85. data/lib/sassc/script.rb +0 -51
  86. data/lib/sassc/version.rb +1 -1
  87. data/sassc.gemspec +1 -0
  88. data/test/custom_importer_test.rb +72 -69
  89. data/test/engine_test.rb +53 -54
  90. data/test/functions_test.rb +40 -39
  91. data/test/native_test.rb +145 -149
  92. data/test/output_style_test.rb +98 -0
  93. data/test/test_helper.rb +21 -7
  94. metadata +28 -2
@@ -4,29 +4,39 @@
4
4
  #include <sstream>
5
5
 
6
6
  #include "sass.h"
7
+ #include "file.hpp"
7
8
  #include "util.hpp"
8
9
 
9
10
  extern "C" {
10
11
  using namespace std;
12
+ using namespace Sass;
13
+ using namespace File;
11
14
 
12
15
  // caller must free the returned memory
13
- char* ADDCALL sass_string_quote (const char *str, const char quote_mark) {
14
- string quoted = Sass::quote(str, quote_mark);
15
- char *cstr = (char*) malloc(quoted.length() + 1);
16
- std::strcpy(cstr, quoted.c_str());
17
- return cstr;
16
+ char* ADDCALL sass_string_quote (const char *str, const char quote_mark)
17
+ {
18
+ string quoted = quote(str, quote_mark);
19
+ return sass_strdup(quoted.c_str());
18
20
  }
19
21
 
20
22
  // caller must free the returned memory
21
- char* ADDCALL sass_string_unquote (const char *str) {
22
- string unquoted = Sass::unquote(str);
23
- char *cstr = (char*) malloc(unquoted.length() + 1);
24
- std::strcpy(cstr, unquoted.c_str());
25
- return cstr;
23
+ char* ADDCALL sass_string_unquote (const char *str)
24
+ {
25
+ string unquoted = unquote(str);
26
+ return sass_strdup(unquoted.c_str());
27
+ }
28
+
29
+ // Make sure to free the returned value!
30
+ // Incs array has to be null terminated!
31
+ char* ADDCALL sass_resolve_file (const char* file, const char* paths[])
32
+ {
33
+ string resolved(find_file(file, paths));
34
+ return sass_strdup(resolved.c_str());
26
35
  }
27
36
 
28
37
  // Get compiled libsass version
29
- const char* ADDCALL libsass_version(void) {
38
+ const char* ADDCALL libsass_version(void)
39
+ {
30
40
  return LIBSASS_VERSION;
31
41
  }
32
42
 
@@ -32,11 +32,8 @@
32
32
 
33
33
  #endif
34
34
 
35
- #ifndef LIBSASS_VERSION
36
- #define LIBSASS_VERSION "[NA]"
37
- #endif
38
-
39
35
  // include API headers
36
+ #include "sass_version.h"
40
37
  #include "sass_values.h"
41
38
  #include "sass_functions.h"
42
39
 
@@ -55,8 +52,11 @@ enum Sass_Output_Style {
55
52
  };
56
53
 
57
54
  // Some convenient string helper function
58
- ADDAPI char* ADDCALL sass_string_quote (const char *str, const char quote_mark);
59
- ADDAPI char* ADDCALL sass_string_unquote (const char *str);
55
+ ADDAPI char* ADDCALL sass_string_quote (const char* str, const char quote_mark);
56
+ ADDAPI char* ADDCALL sass_string_unquote (const char* str);
57
+
58
+ // Resolve a file via the given include paths in the include char* array
59
+ ADDAPI char* ADDCALL sass_resolve_file (const char* path, const char* incs[]);
60
60
 
61
61
  // Get compiled libsass version
62
62
  ADDAPI const char* ADDCALL libsass_version(void);
@@ -14,6 +14,7 @@
14
14
  #include "context.hpp"
15
15
  #include "sass_values.h"
16
16
  #include "sass_context.h"
17
+ #include "ast_fwd_decl.hpp"
17
18
  #include "error_handling.hpp"
18
19
 
19
20
  extern "C" {
@@ -99,10 +100,13 @@ extern "C" {
99
100
  char* source_map_root;
100
101
 
101
102
  // Custom functions that can be called from sccs code
102
- Sass_C_Function_List c_functions;
103
+ Sass_Function_List c_functions;
103
104
 
104
- // Callback to overload imports
105
- Sass_C_Import_Callback importer;
105
+ // List of custom importers
106
+ Sass_Importer_List c_importers;
107
+
108
+ // List of custom headers
109
+ Sass_Importer_List c_headers;
106
110
 
107
111
  };
108
112
 
@@ -128,6 +132,7 @@ extern "C" {
128
132
  char* error_file;
129
133
  size_t error_line;
130
134
  size_t error_column;
135
+ const char* error_src;
131
136
 
132
137
  // report imported files
133
138
  char** included_files;
@@ -150,13 +155,6 @@ extern "C" {
150
155
 
151
156
  };
152
157
 
153
- // Compiler states
154
- enum Sass_Compiler_State {
155
- SASS_COMPILER_CREATED,
156
- SASS_COMPILER_PARSED,
157
- SASS_COMPILER_EXECUTED
158
- };
159
-
160
158
  // link c and cpp context
161
159
  struct Sass_Compiler {
162
160
  // progress status
@@ -164,9 +162,9 @@ extern "C" {
164
162
  // original c context
165
163
  Sass_Context* c_ctx;
166
164
  // Sass::Context
167
- void* cpp_ctx;
165
+ Context* cpp_ctx;
168
166
  // Sass::Block
169
- void* root;
167
+ Block* root;
170
168
  };
171
169
 
172
170
  static void copy_options(struct Sass_Options* to, struct Sass_Options* from) { *to = *from; }
@@ -190,19 +188,19 @@ extern "C" {
190
188
  return str == NULL ? "" : str;
191
189
  }
192
190
 
193
- static void copy_strings(const std::vector<std::string>& strings, char*** array, int skip = 0) throw() {
191
+ static void copy_strings(const std::vector<std::string>& strings, char*** array) {
194
192
  int num = static_cast<int>(strings.size());
195
193
  char** arr = (char**) malloc(sizeof(char*) * (num + 1));
196
194
  if (arr == 0) throw(bad_alloc());
197
195
 
198
- for(int i = skip; i < num; i++) {
199
- arr[i-skip] = (char*) malloc(sizeof(char) * (strings[i].size() + 1));
200
- if (arr[i-skip] == 0) throw(bad_alloc());
201
- std::copy(strings[i].begin(), strings[i].end(), arr[i-skip]);
202
- arr[i-skip][strings[i].size()] = '\0';
196
+ for(int i = 0; i < num; i++) {
197
+ arr[i] = (char*) malloc(sizeof(char) * (strings[i].size() + 1));
198
+ if (arr[i] == 0) throw(bad_alloc());
199
+ std::copy(strings[i].begin(), strings[i].end(), arr[i]);
200
+ arr[i][strings[i].size()] = '\0';
203
201
  }
204
202
 
205
- arr[num-skip] = 0;
203
+ arr[num] = 0;
206
204
  *array = arr;
207
205
  }
208
206
 
@@ -249,6 +247,29 @@ extern "C" {
249
247
  if (!got_newline) msg_stream << "\n";
250
248
  msg_stream << string(msg_prefix.size(), ' ');
251
249
  msg_stream << " on line " << e.pstate.line+1 << " of " << rel_path << "\n";
250
+
251
+ // now create the code trace (ToDo: maybe have util functions?)
252
+ if (e.pstate.line != string::npos && e.pstate.column != string::npos) {
253
+ size_t line = e.pstate.line;
254
+ const char* line_beg = e.pstate.src;
255
+ while (line_beg && *line_beg && line) {
256
+ if (*line_beg == '\n') -- line;
257
+ ++ line_beg;
258
+ }
259
+ const char* line_end = line_beg;
260
+ while (line_end && *line_end && *line_end != '\n') {
261
+ if (*line_end == '\n') break;
262
+ if (*line_end == '\r') break;
263
+ line_end ++;
264
+ }
265
+ size_t max_left = 42; size_t max_right = 78;
266
+ size_t move_in = e.pstate.column > max_left ? e.pstate.column - max_left : 0;
267
+ size_t shorten = (line_end - line_beg) - move_in > max_right ?
268
+ (line_end - line_beg) - move_in - max_right : 0;
269
+ msg_stream << ">> " << string(line_beg + move_in, line_end - shorten) << "\n";
270
+ msg_stream << " " << string(e.pstate.column - move_in, '-') << "^\n";
271
+ }
272
+
252
273
  c_ctx->error_json = json_stringify(json_err, " ");;
253
274
  c_ctx->error_message = sass_strdup(msg_stream.str().c_str());
254
275
  c_ctx->error_text = strdup(e.message.c_str());
@@ -256,6 +277,7 @@ extern "C" {
256
277
  c_ctx->error_file = sass_strdup(e.pstate.path.c_str());
257
278
  c_ctx->error_line = e.pstate.line+1;
258
279
  c_ctx->error_column = e.pstate.column+1;
280
+ c_ctx->error_src = e.pstate.src;
259
281
  c_ctx->output_string = 0;
260
282
  c_ctx->source_map_string = 0;
261
283
  json_delete(json_err);
@@ -320,7 +342,7 @@ extern "C" {
320
342
  }
321
343
 
322
344
  // generic compilation function (not exported, use file/data compile instead)
323
- static Context* sass_prepare_context (Sass_Context* c_ctx, Context::Data cpp_opt)
345
+ static Sass_Compiler* sass_prepare_context (Sass_Context* c_ctx, Context::Data cpp_opt) throw()
324
346
  {
325
347
  try {
326
348
 
@@ -364,7 +386,9 @@ extern "C" {
364
386
  }
365
387
 
366
388
  // transfer the options to c++
367
- cpp_opt.input_path(input_path)
389
+ cpp_opt.c_compiler(0)
390
+ .c_options(c_ctx)
391
+ .input_path(input_path)
368
392
  .output_path(output_path)
369
393
  .output_style((Output_Style) c_ctx->output_style)
370
394
  .is_indented_syntax_src(c_ctx->is_indented_syntax_src)
@@ -376,14 +400,13 @@ extern "C" {
376
400
  .omit_source_map_url(c_ctx->omit_source_map_url)
377
401
  .include_paths_c_str(c_ctx->include_path)
378
402
  .plugin_paths_c_str(c_ctx->plugin_path)
379
- .include_paths_array(include_paths)
380
- .plugin_paths_array(plugin_paths)
403
+ // .include_paths_array(include_paths)
404
+ // .plugin_paths_array(plugin_paths)
381
405
  .include_paths(vector<string>())
382
406
  .plugin_paths(vector<string>())
383
- .importer(c_ctx->importer)
384
- .precision(c_ctx->precision ? c_ctx->precision : 5)
385
- .linefeed(c_ctx->linefeed ? c_ctx->linefeed : LFEED)
386
- .indent(c_ctx->indent ? c_ctx->indent : " ");
407
+ .precision(c_ctx->precision)
408
+ .linefeed(c_ctx->linefeed)
409
+ .indent(c_ctx->indent);
387
410
 
388
411
  // create new c++ Context
389
412
  Context* cpp_ctx = new Context(cpp_opt);
@@ -393,25 +416,53 @@ extern "C" {
393
416
 
394
417
  // register our custom functions
395
418
  if (c_ctx->c_functions) {
396
- Sass_C_Function_List this_func_data = c_ctx->c_functions;
397
- while ((this_func_data) && (*this_func_data)) {
398
- cpp_ctx->c_functions.push_back((*this_func_data));
419
+ auto this_func_data = c_ctx->c_functions;
420
+ while (this_func_data && *this_func_data) {
421
+ cpp_ctx->add_c_function(*this_func_data);
399
422
  ++this_func_data;
400
423
  }
401
424
  }
402
425
 
426
+ // register our custom headers
427
+ if (c_ctx->c_headers) {
428
+ auto this_head_data = c_ctx->c_headers;
429
+ while (this_head_data && *this_head_data) {
430
+ cpp_ctx->add_c_header(*this_head_data);
431
+ ++this_head_data;
432
+ }
433
+ }
434
+
435
+ // register our custom importers
436
+ if (c_ctx->c_importers) {
437
+ auto this_imp_data = c_ctx->c_importers;
438
+ while (this_imp_data && *this_imp_data) {
439
+ cpp_ctx->add_c_importer(*this_imp_data);
440
+ ++this_imp_data;
441
+ }
442
+ }
443
+
403
444
  // reset error status
404
445
  c_ctx->error_json = 0;
405
446
  c_ctx->error_text = 0;
406
447
  c_ctx->error_message = 0;
407
448
  c_ctx->error_status = 0;
408
449
  // reset error position
450
+ c_ctx->error_src = 0;
409
451
  c_ctx->error_file = 0;
410
- c_ctx->error_line = -1;
411
- c_ctx->error_column = -1;
452
+ c_ctx->error_line = string::npos;
453
+ c_ctx->error_column = string::npos;
454
+
455
+ // allocate a new compiler instance
456
+ Sass_Compiler* compiler = (struct Sass_Compiler*) calloc(1, sizeof(struct Sass_Compiler));
457
+ compiler->state = SASS_COMPILER_CREATED;
458
+
459
+ // store in sass compiler
460
+ compiler->c_ctx = c_ctx;
461
+ compiler->cpp_ctx = cpp_ctx;
462
+ cpp_ctx->c_compiler = compiler;
412
463
 
413
464
  // use to parse block
414
- return cpp_ctx;
465
+ return compiler;
415
466
 
416
467
  }
417
468
  // pass errors to generic error handler
@@ -422,8 +473,18 @@ extern "C" {
422
473
 
423
474
  }
424
475
 
425
- static Block* sass_parse_block (Sass_Context* c_ctx, Context* cpp_ctx)
476
+ static Block* sass_parse_block (Sass_Compiler* compiler) throw()
426
477
  {
478
+
479
+ // assert valid pointer
480
+ if (compiler == 0) return 0;
481
+ // The cpp context must be set by now
482
+ Context* cpp_ctx = compiler->cpp_ctx;
483
+ Sass_Context* c_ctx = compiler->c_ctx;
484
+ // We will take care to wire up the rest
485
+ compiler->cpp_ctx->c_compiler = compiler;
486
+ compiler->state = SASS_COMPILER_PARSED;
487
+
427
488
  try {
428
489
 
429
490
  // get input/output path from options
@@ -445,8 +506,11 @@ extern "C" {
445
506
  skip = 1; // skip first entry of includes
446
507
  }
447
508
 
509
+ // skip all prefixed files?
510
+ skip += cpp_ctx->head_imports;
511
+
448
512
  // copy the included files on to the context (dont forget to free)
449
- if (root) copy_strings(cpp_ctx->get_included_files(skip), &c_ctx->included_files, skip);
513
+ if (root) copy_strings(cpp_ctx->get_included_files(skip), &c_ctx->included_files);
450
514
 
451
515
  // return parsed block
452
516
  return root;
@@ -464,36 +528,35 @@ extern "C" {
464
528
  static int sass_compile_context (Sass_Context* c_ctx, Context::Data cpp_opt)
465
529
  {
466
530
 
467
- // first prepare the c++ context
468
- Context* cpp_ctx = sass_prepare_context(c_ctx, cpp_opt);
469
-
470
- // parse given context and return root block
471
- Block* root = cpp_ctx ? sass_parse_block(c_ctx, cpp_ctx) : 0;
472
-
473
- if (cpp_ctx && root) {
474
-
475
- try {
476
-
477
- // now compile the parsed root block
478
- c_ctx->output_string = cpp_ctx->compile_block(root);
479
-
480
- // generate source map json and store on context
481
- c_ctx->source_map_string = cpp_ctx->generate_source_map();
482
-
483
- }
484
- // pass errors to generic error handler
485
- catch (...) { handle_errors(c_ctx); }
531
+ // prepare sass compiler with context and options
532
+ Sass_Compiler* compiler = sass_prepare_context(c_ctx, cpp_opt);
486
533
 
534
+ try {
535
+ // call each compiler step
536
+ sass_compiler_parse(compiler);
537
+ sass_compiler_execute(compiler);
487
538
  }
539
+ // pass errors to generic error handler
540
+ catch (...) { handle_errors(c_ctx); }
488
541
 
489
- delete cpp_ctx;
542
+ sass_delete_compiler(compiler);
490
543
 
491
544
  return c_ctx->error_status;
492
545
  }
493
546
 
547
+ inline void init_options (struct Sass_Options* options)
548
+ {
549
+ options->precision = 5;
550
+ options->indent = " ";
551
+ options->linefeed = LFEED;
552
+ }
553
+
494
554
  Sass_Options* ADDCALL sass_make_options (void)
495
555
  {
496
- return (struct Sass_Options*) calloc(1, sizeof(struct Sass_Options));
556
+ struct Sass_Options* options = (struct Sass_Options*) calloc(1, sizeof(struct Sass_Options));
557
+ if (options == 0) { cerr << "Error allocating memory for options" << endl; return 0; }
558
+ init_options(options);
559
+ return options;
497
560
  }
498
561
 
499
562
  Sass_File_Context* ADDCALL sass_make_file_context(const char* input_path)
@@ -501,6 +564,7 @@ extern "C" {
501
564
  struct Sass_File_Context* ctx = (struct Sass_File_Context*) calloc(1, sizeof(struct Sass_File_Context));
502
565
  if (ctx == 0) { cerr << "Error allocating memory for file context" << endl; return 0; }
503
566
  ctx->type = SASS_CONTEXT_FILE;
567
+ init_options(ctx);
504
568
  try {
505
569
  if (input_path == 0) { throw(runtime_error("File context created without an input path")); }
506
570
  if (*input_path == 0) { throw(runtime_error("File context created with empty input path")); }
@@ -516,6 +580,7 @@ extern "C" {
516
580
  struct Sass_Data_Context* ctx = (struct Sass_Data_Context*) calloc(1, sizeof(struct Sass_Data_Context));
517
581
  if (ctx == 0) { cerr << "Error allocating memory for data context" << endl; return 0; }
518
582
  ctx->type = SASS_CONTEXT_DATA;
583
+ init_options(ctx);
519
584
  try {
520
585
  if (source_string == 0) { throw(runtime_error("Data context created without a source string")); }
521
586
  if (*source_string == 0) { throw(runtime_error("Data context created with empty source string")); }
@@ -529,27 +594,17 @@ extern "C" {
529
594
  struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_Context* c_ctx)
530
595
  {
531
596
  if (c_ctx == 0) return 0;
532
- struct Sass_Compiler* compiler = (struct Sass_Compiler*) calloc(1, sizeof(struct Sass_Compiler));
533
- if (compiler == 0) { cerr << "Error allocating memory for file compiler" << endl; return 0; }
534
- compiler->state = SASS_COMPILER_CREATED;
535
- compiler->c_ctx = c_ctx;
536
597
  Context::Data cpp_opt = Context::Data();
537
598
  cpp_opt.entry_point(c_ctx->input_path);
538
- compiler->cpp_ctx = sass_prepare_context(c_ctx, cpp_opt);
539
- return compiler;
599
+ return sass_prepare_context(c_ctx, cpp_opt);
540
600
  }
541
601
 
542
602
  struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* c_ctx)
543
603
  {
544
604
  if (c_ctx == 0) return 0;
545
- struct Sass_Compiler* compiler = (struct Sass_Compiler*) calloc(1, sizeof(struct Sass_Compiler));
546
- if (compiler == 0) { cerr << "Error allocating memory for data compiler" << endl; return 0; }
547
- compiler->state = SASS_COMPILER_CREATED;
548
- compiler->c_ctx = c_ctx;
549
605
  Context::Data cpp_opt = Context::Data();
550
606
  cpp_opt.source_c_str(c_ctx->source_string);
551
- compiler->cpp_ctx = sass_prepare_context(c_ctx, cpp_opt);
552
- return compiler;
607
+ return sass_prepare_context(c_ctx, cpp_opt);
553
608
  }
554
609
 
555
610
  int ADDCALL sass_compile_data_context(Sass_Data_Context* data_ctx)
@@ -593,10 +648,8 @@ extern "C" {
593
648
  if (compiler->cpp_ctx == NULL) return 1;
594
649
  if (compiler->c_ctx->error_status)
595
650
  return compiler->c_ctx->error_status;
596
- compiler->state = SASS_COMPILER_PARSED;
597
- Context* cpp_ctx = (Context*) compiler->cpp_ctx;
598
651
  // parse the context we have set up (file or data)
599
- compiler->root = sass_parse_block(compiler->c_ctx, cpp_ctx);
652
+ compiler->root = sass_parse_block(compiler);
600
653
  // success
601
654
  return 0;
602
655
  }
@@ -630,12 +683,28 @@ extern "C" {
630
683
  if (options == 0) return;
631
684
  // Deallocate custom functions
632
685
  if (options->c_functions) {
633
- struct Sass_C_Function_Descriptor** this_func_data = options->c_functions;
634
- while ((this_func_data) && (*this_func_data)) {
635
- free((*this_func_data));
686
+ Sass_Function_List this_func_data = options->c_functions;
687
+ while (this_func_data && *this_func_data) {
688
+ free(*this_func_data);
636
689
  ++this_func_data;
637
690
  }
638
691
  }
692
+ // Deallocate custom headers
693
+ if (options->c_headers) {
694
+ Sass_Importer_List this_head_data = options->c_headers;
695
+ while (this_head_data && *this_head_data) {
696
+ free(*this_head_data);
697
+ ++this_head_data;
698
+ }
699
+ }
700
+ // Deallocate custom importers
701
+ if (options->c_importers) {
702
+ Sass_Importer_List this_imp_data = options->c_importers;
703
+ while (this_imp_data && *this_imp_data) {
704
+ free(*this_imp_data);
705
+ ++this_imp_data;
706
+ }
707
+ }
639
708
  // Deallocate inc paths
640
709
  if (options->plugin_paths) {
641
710
  struct string_list* cur;
@@ -660,13 +729,15 @@ extern "C" {
660
729
  cur = next;
661
730
  }
662
731
  }
663
- // Free custom importer
664
- free(options->importer);
665
- // Free the list container
732
+ // Free custom functions
666
733
  free(options->c_functions);
667
- // Make it null terminated
668
- options->importer = 0;
734
+ // Free custom importers
735
+ free(options->c_importers);
736
+ free(options->c_headers);
737
+ // Reset our pointers
669
738
  options->c_functions = 0;
739
+ options->c_importers = 0;
740
+ options->c_headers = 0;
670
741
  options->plugin_paths = 0;
671
742
  options->include_paths = 0;
672
743
  }
@@ -730,6 +801,18 @@ extern "C" {
730
801
  void ADDCALL sass_file_context_set_options (struct Sass_File_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }
731
802
  void ADDCALL sass_data_context_set_options (struct Sass_Data_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }
732
803
 
804
+ // Getters for Sass_Compiler options (get conected sass context)
805
+ enum Sass_Compiler_State ADDCALL sass_compiler_get_state(struct Sass_Compiler* compiler) { return compiler->state; }
806
+ struct Sass_Context* ADDCALL sass_compiler_get_context(struct Sass_Compiler* compiler) { return compiler->c_ctx; }
807
+ // Getters for Sass_Compiler options (query import stack)
808
+ size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.size(); }
809
+ Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.back(); }
810
+ Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx) { return compiler->cpp_ctx->import_stack[idx]; }
811
+
812
+ // Calculate the size of the stored null terminated array
813
+ size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx)
814
+ { size_t l = 0; auto i = ctx->included_files; while (i && *i) { ++i; ++l; } return l; }
815
+
733
816
  // Create getter and setters for options
734
817
  IMPLEMENT_SASS_OPTION_ACCESSOR(int, precision);
735
818
  IMPLEMENT_SASS_OPTION_ACCESSOR(enum Sass_Output_Style, output_style);
@@ -738,8 +821,9 @@ extern "C" {
738
821
  IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_contents);
739
822
  IMPLEMENT_SASS_OPTION_ACCESSOR(bool, omit_source_map_url);
740
823
  IMPLEMENT_SASS_OPTION_ACCESSOR(bool, is_indented_syntax_src);
741
- IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_C_Function_List, c_functions);
742
- IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_C_Import_Callback, importer);
824
+ IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Function_List, c_functions);
825
+ IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_importers);
826
+ IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_headers);
743
827
  IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, indent);
744
828
  IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, linefeed);
745
829
  IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, input_path);
@@ -757,6 +841,7 @@ extern "C" {
757
841
  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_file);
758
842
  IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_line);
759
843
  IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_column);
844
+ IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_src);
760
845
  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, output_string);
761
846
  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, source_map_string);
762
847
  IMPLEMENT_SASS_CONTEXT_GETTER(char**, included_files);
@@ -768,6 +853,7 @@ extern "C" {
768
853
  IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_file);
769
854
  IMPLEMENT_SASS_CONTEXT_TAKER(char*, output_string);
770
855
  IMPLEMENT_SASS_CONTEXT_TAKER(char*, source_map_string);
856
+ IMPLEMENT_SASS_CONTEXT_TAKER(char**, included_files);
771
857
 
772
858
  // Push function for include paths (no manipulation support for now)
773
859
  void ADDCALL sass_option_push_include_path(struct Sass_Options* options, const char* path)