sassc 0.0.10 → 0.0.11

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