diff --git a/docs/api-context-internal.md b/docs/api-context-internal.md index 1a2818b345..a0ae47f6e5 100644 --- a/docs/api-context-internal.md +++ b/docs/api-context-internal.md @@ -51,6 +51,10 @@ struct Sass_Options : Sass_Output_Options { // Treat source_string as sass (as opposed to scss) bool is_indented_syntax_src; + // If this options is set, nothing will be printed to stderr anymore + // The aggregated output on stderr can be fetched via stderr_string + bool suppress_stderr; + // The input path is used for source map // generation. It can be used to define // something with string compilation or to @@ -105,6 +109,9 @@ struct Sass_Context : Sass_Options // generated output data char* output_string; + // messages on stderr + char* stderr_string; + // generated source map json char* source_map_string; diff --git a/docs/api-context.md b/docs/api-context.md index d51b807705..af5674357d 100644 --- a/docs/api-context.md +++ b/docs/api-context.md @@ -46,6 +46,11 @@ bool omit_source_map_url; bool is_indented_syntax_src; ``` ```C +// If this options is set, nothing will be printed to stderr anymore +// The aggregated output on stderr can be fetched via stderr_string +bool suppress_stderr; +``` +```C // The input path is used for source map // generating. It can be used to define // something with string compilation or to @@ -111,6 +116,10 @@ enum Sass_Input_Style type; char* output_string; ``` ```C +// messages on stderr +char* stderr_string; +``` +```C // generated source map json char* source_map_string; ``` @@ -197,6 +206,7 @@ void sass_data_context_set_options (struct Sass_Data_Context* data_ctx, struct S // Getters for Sass_Context values const char* sass_context_get_output_string (struct Sass_Context* ctx); +const char* sass_context_get_stderr_string (struct Sass_Context* ctx); int sass_context_get_error_status (struct Sass_Context* ctx); const char* sass_context_get_error_json (struct Sass_Context* ctx); const char* sass_context_get_error_text (struct Sass_Context* ctx); @@ -262,6 +272,7 @@ void sass_option_set_source_map_contents (struct Sass_Options* options, bool sou void sass_option_set_source_map_file_urls (struct Sass_Options* options, bool source_map_file_urls); void sass_option_set_omit_source_map_url (struct Sass_Options* options, bool omit_source_map_url); void sass_option_set_is_indented_syntax_src (struct Sass_Options* options, bool is_indented_syntax_src); +void sass_option_set_suppress_stderr (struct Sass_Options* options, bool suppress_stderr); void sass_option_set_indent (struct Sass_Options* options, const char* indent); void sass_option_set_linefeed (struct Sass_Options* options, const char* linefeed); void sass_option_set_input_path (struct Sass_Options* options, const char* input_path); diff --git a/include/sass/context.h b/include/sass/context.h index 93c59d7206..d41886c439 100644 --- a/include/sass/context.h +++ b/include/sass/context.h @@ -96,6 +96,7 @@ ADDAPI void ADDCALL sass_option_set_source_map_contents (struct Sass_Options* op ADDAPI void ADDCALL sass_option_set_source_map_file_urls (struct Sass_Options* options, bool source_map_file_urls); ADDAPI void ADDCALL sass_option_set_omit_source_map_url (struct Sass_Options* options, bool omit_source_map_url); ADDAPI void ADDCALL sass_option_set_is_indented_syntax_src (struct Sass_Options* options, bool is_indented_syntax_src); +ADDAPI void ADDCALL sass_option_set_suppress_stderr (struct Sass_Options* options, bool suppress_stderr); ADDAPI void ADDCALL sass_option_set_indent (struct Sass_Options* options, const char* indent); ADDAPI void ADDCALL sass_option_set_linefeed (struct Sass_Options* options, const char* linefeed); ADDAPI void ADDCALL sass_option_set_input_path (struct Sass_Options* options, const char* input_path); @@ -111,6 +112,7 @@ ADDAPI void ADDCALL sass_option_set_c_functions (struct Sass_Options* options, S // Getters for Sass_Context values ADDAPI const char* ADDCALL sass_context_get_output_string (struct Sass_Context* ctx); +ADDAPI const char* ADDCALL sass_context_get_stderr_string (struct Sass_Context* ctx); ADDAPI int ADDCALL sass_context_get_error_status (struct Sass_Context* ctx); ADDAPI const char* ADDCALL sass_context_get_error_json (struct Sass_Context* ctx); ADDAPI const char* ADDCALL sass_context_get_error_text (struct Sass_Context* ctx); diff --git a/src/bind.cpp b/src/bind.cpp index e9f6bbe440..83c0e59655 100644 --- a/src/bind.cpp +++ b/src/bind.cpp @@ -11,7 +11,7 @@ namespace Sass { - void bind(std::string type, std::string name, Parameters_Obj ps, Arguments_Obj as, Env* env, Eval* eval, Backtraces& traces) + void bind(std::string type, std::string name, Parameters_Obj ps, Arguments_Obj as, Context* ctx, Env* env, Eval* eval, Backtraces& traces) { std::string callee(type + " " + name); @@ -194,7 +194,9 @@ namespace Sass { msg << (LP == 1 ? " argument" : " arguments"); msg << " but " << arg_count; msg << (arg_count == 1 ? " was passed" : " were passed."); - deprecated_bind(msg.str(), as->pstate()); + // ToDo: we only need ctx here to capture the message on stderr + // ToDo: once deprecation is gone, remove it from method args + ctx->c_options.print_stderr(deprecated_bind(msg.str(), as->pstate())); while (arglist->length() > LP - ip) { arglist->elements().erase(arglist->elements().end() - 1); diff --git a/src/bind.hpp b/src/bind.hpp index 57bcd01f97..b26ffd19a8 100644 --- a/src/bind.hpp +++ b/src/bind.hpp @@ -8,7 +8,7 @@ namespace Sass { - void bind(std::string type, std::string name, Parameters_Obj, Arguments_Obj, Env*, Eval*, Backtraces& traces); + void bind(std::string type, std::string name, Parameters_Obj, Arguments_Obj, Context* ctx, Env*, Eval*, Backtraces& traces); } diff --git a/src/context.cpp b/src/context.cpp index 088a70d3f9..da02dc4b16 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -76,6 +76,7 @@ namespace Sass { head_imports(0), plugins(), emitter(c_options), + CERR(std::cerr), ast_gc(), strings(), diff --git a/src/context.hpp b/src/context.hpp index d18cd38177..3e0d899563 100644 --- a/src/context.hpp +++ b/src/context.hpp @@ -2,6 +2,7 @@ #define SASS_CONTEXT_H #include +#include #include #include @@ -44,6 +45,8 @@ namespace Sass { Plugins plugins; Output emitter; + std::ostream& CERR; + // generic ast node garbage container // used to avoid possible circular refs CallStack ast_gc; diff --git a/src/error_handling.cpp b/src/error_handling.cpp index c0cf739eb7..6c002f0597 100644 --- a/src/error_handling.cpp +++ b/src/error_handling.cpp @@ -134,66 +134,78 @@ namespace Sass { } - - void warn(std::string msg, ParserState pstate) + std::string warn(std::string msg, ParserState pstate) { - std::cerr << "Warning: " << msg << std::endl; + std::ostringstream sstrm; + sstrm << "Warning: " << msg << std::endl; + return sstrm.str(); } - void warning(std::string msg, ParserState pstate) + std::string warning(std::string msg, ParserState pstate) { std::string cwd(Sass::File::get_cwd()); std::string abs_path(Sass::File::rel2abs(pstate.path, cwd, cwd)); std::string rel_path(Sass::File::abs2rel(pstate.path, cwd, cwd)); std::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.path)); - std::cerr << "WARNING on line " << pstate.line+1 << ", column " << pstate.column+1 << " of " << output_path << ":" << std::endl; - std::cerr << msg << std::endl << std::endl; + std::ostringstream sstrm; + sstrm << "WARNING on line " << pstate.line + 1; + sstrm << ", column " << pstate.column + 1; + sstrm << " of " << output_path << std::endl; + sstrm << msg << std::endl; + sstrm << std::endl; + return sstrm.str(); } - void warn(std::string msg, ParserState pstate, Backtrace* bt) + std::string warn(std::string msg, ParserState pstate, Backtrace* bt) { - warn(msg, pstate); + return warn(msg, pstate); } - void deprecated_function(std::string msg, ParserState pstate) + std::string deprecated_function(std::string msg, ParserState pstate) { std::string cwd(Sass::File::get_cwd()); std::string abs_path(Sass::File::rel2abs(pstate.path, cwd, cwd)); std::string rel_path(Sass::File::abs2rel(pstate.path, cwd, cwd)); std::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.path)); - std::cerr << "DEPRECATION WARNING: " << msg << std::endl; - std::cerr << "will be an error in future versions of Sass." << std::endl; - std::cerr << " on line " << pstate.line+1 << " of " << output_path << std::endl; + std::ostringstream sstrm; + sstrm << "DEPRECATION WARNING: " << msg << std::endl; + sstrm << "will be an error in future versions of Sass." << std::endl; + sstrm << " on line " << pstate.line+1 << " of " << output_path << std::endl; + return sstrm.str(); } - void deprecated(std::string msg, std::string msg2, bool with_column, ParserState pstate) + std::string deprecated(std::string msg, std::string msg2, bool with_column, ParserState pstate) { std::string cwd(Sass::File::get_cwd()); std::string abs_path(Sass::File::rel2abs(pstate.path, cwd, cwd)); std::string rel_path(Sass::File::abs2rel(pstate.path, cwd, cwd)); std::string output_path(Sass::File::path_for_console(rel_path, pstate.path, pstate.path)); - std::cerr << "DEPRECATION WARNING on line " << pstate.line + 1; - if (with_column) std::cerr << ", column " << pstate.column + pstate.offset.column + 1; - if (output_path.length()) std::cerr << " of " << output_path; - std::cerr << ":" << std::endl; - std::cerr << msg << std::endl; - if (msg2.length()) std::cerr << msg2 << std::endl; - std::cerr << std::endl; + std::ostringstream sstrm; + sstrm << "DEPRECATION WARNING on line " << pstate.line + 1; + if (with_column) sstrm << ", column " << pstate.column + pstate.offset.column + 1; + if (output_path.length()) sstrm << " of " << output_path; + sstrm << ":" << std::endl; + sstrm << msg << std::endl; + if (msg2.length()) sstrm << msg2 << std::endl; + sstrm << std::endl; + return sstrm.str(); } - void deprecated_bind(std::string msg, ParserState pstate) + std::string deprecated_bind(std::string msg, ParserState pstate) { std::string cwd(Sass::File::get_cwd()); std::string abs_path(Sass::File::rel2abs(pstate.path, cwd, cwd)); std::string rel_path(Sass::File::abs2rel(pstate.path, cwd, cwd)); std::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.path)); - std::cerr << "WARNING: " << msg << std::endl; - std::cerr << " on line " << pstate.line+1 << " of " << output_path << std::endl; - std::cerr << "This will be an error in future versions of Sass." << std::endl; + std::ostringstream sstrm; + sstrm << "WARNING: " << msg << std::endl; + sstrm << " on line " << pstate.line+1 << " of " << output_path << std::endl; + sstrm << "This will be an error in future versions of Sass." << std::endl; + return sstrm.str(); } // should be replaced with error with backtraces diff --git a/src/error_handling.hpp b/src/error_handling.hpp index 24fedec4c0..c6d7d687d2 100644 --- a/src/error_handling.hpp +++ b/src/error_handling.hpp @@ -212,14 +212,13 @@ namespace Sass { } - void warn(std::string msg, ParserState pstate); - void warn(std::string msg, ParserState pstate, Backtrace* bt); - void warning(std::string msg, ParserState pstate); - - void deprecated_function(std::string msg, ParserState pstate); - void deprecated(std::string msg, std::string msg2, bool with_column, ParserState pstate); - void deprecated_bind(std::string msg, ParserState pstate); - // void deprecated(std::string msg, ParserState pstate, Backtrace* bt); + std::string warn(std::string msg, ParserState pstate); + std::string warn(std::string msg, ParserState pstate, Backtrace* bt); + std::string warning(std::string msg, ParserState pstate); + + std::string deprecated_function(std::string msg, ParserState pstate); + std::string deprecated(std::string msg, std::string msg2, bool with_column, ParserState pstate); + std::string deprecated_bind(std::string msg, ParserState pstate); void coreError(std::string msg, ParserState pstate); void error(std::string msg, ParserState pstate, Backtraces& traces); diff --git a/src/eval.cpp b/src/eval.cpp index 71bd0aea2d..226db6368c 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -389,9 +389,11 @@ namespace Sass { std::string result(unquote(message->to_sass())); std::cerr << "WARNING: " << result << std::endl; + std::ostringstream sstrm; traces.push_back(Backtrace(w->pstate())); - std::cerr << traces_to_string(traces, " "); - std::cerr << std::endl; + sstrm << traces_to_string(traces, " "); + sstrm << std::endl; + ctx.c_options.print_stderr(sstrm.str()); options().output_style = outstyle; traces.pop_back(); return 0; @@ -485,8 +487,11 @@ namespace Sass { std::string output_path(Sass::File::path_for_console(rel_path, abs_path, d->pstate().path)); options().output_style = outstyle; - std::cerr << output_path << ":" << d->pstate().line+1 << " DEBUG: " << result; - std::cerr << std::endl; + std::ostringstream sstrm; + sstrm << output_path << ":" << d->pstate().line+1 << " DEBUG: " << result; + sstrm << std::endl; + ctx.c_options.print_stderr(sstrm.str()); + return 0; } @@ -1048,7 +1053,7 @@ namespace Sass { env_stack().push_back(&fn_env); if (func || body) { - bind(std::string("Function"), c->name(), params, args, &fn_env, this, traces); + bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this, traces); std::string msg(", in function `" + c->name() + "`"); traces.push_back(Backtrace(c->pstate(), msg)); callee_stack().push_back({ @@ -1088,7 +1093,7 @@ namespace Sass { // populates env with default values for params std::string ff(c->name()); - bind(std::string("Function"), c->name(), params, args, &fn_env, this, traces); + bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this, traces); std::string msg(", in function `" + c->name() + "`"); traces.push_back(Backtrace(c->pstate(), msg)); callee_stack().push_back({ diff --git a/src/expand.cpp b/src/expand.cpp index 0a40410ed4..ad7cac7b83 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -685,11 +685,11 @@ namespace Sass { d->name() == "expression" || d->name() == "url" )) { - deprecated( + ctx.c_options.print_stderr(deprecated( "Naming a function \"" + d->name() + "\" is disallowed and will be an error in future versions of Sass.", "This name conflicts with an existing CSS function with special parse rules.", false, d->pstate() - ); + )); } // set the static link so we can have lexical scoping @@ -746,7 +746,7 @@ namespace Sass { new_env.local_frame()["@content[m]"] = thunk; } - bind(std::string("Mixin"), c->name(), params, args, &new_env, &eval, traces); + bind(std::string("Mixin"), c->name(), params, args, &ctx, &new_env, &eval, traces); Block_Obj trace_block = SASS_MEMORY_NEW(Block, c->pstate()); Trace_Obj trace = SASS_MEMORY_NEW(Trace, c->pstate(), c->name(), trace_block); diff --git a/src/fn_strings.cpp b/src/fn_strings.cpp index 1b0ef38a82..dd500dc2e3 100644 --- a/src/fn_strings.cpp +++ b/src/fn_strings.cpp @@ -56,7 +56,7 @@ namespace Sass { val = Cast(arg) ? "null" : val; ctx.c_options.output_style = oldstyle; - deprecated_function("Passing " + val + ", a non-string value, to unquote()", pstate); + ctx.c_options.print_stderr(deprecated_function("Passing " + val + ", a non-string value, to unquote()", pstate)); return ex; } throw std::runtime_error("Invalid Data Type for unquote"); diff --git a/src/operators.cpp b/src/operators.cpp index bf312b8f35..533deda598 100644 --- a/src/operators.cpp +++ b/src/operators.cpp @@ -58,14 +58,14 @@ namespace Sass { bool gte(Expression_Obj lhs, Expression_Obj rhs) { return !cmp(lhs, rhs, Sass_OP::GTE) || eq(lhs, rhs); } /* colour math deprecation warning */ - void op_color_deprecation(enum Sass_OP op, std::string lsh, std::string rhs, const ParserState& pstate) + void op_color_deprecation(enum Sass_OP op, std::string lsh, std::string rhs, struct Sass_Inspect_Options opt, const ParserState& pstate) { - deprecated( + opt.print_stderr(deprecated( "The operation `" + lsh + " " + sass_op_to_name(op) + " " + rhs + "` is deprecated and will be an error in future versions.", "Consider using Sass's color functions instead.\n" "https://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions", - /*with_column=*/false, pstate); + /*with_column=*/false, pstate)); } /* static function, throws OperationError, has no traces but optional pstate for returned value */ @@ -130,7 +130,7 @@ namespace Sass { throw Exception::ZeroDivisionError(lhs, rhs); } - op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate); + op_color_deprecation(op, lhs.to_string(), rhs.to_string(), opt, pstate); return SASS_MEMORY_NEW(Color_RGBA, pstate, @@ -218,7 +218,7 @@ namespace Sass { switch (op) { case Sass_OP::ADD: case Sass_OP::MUL: { - op_color_deprecation(op, lhs.to_string(), rhs.to_string(opt), pstate); + op_color_deprecation(op, lhs.to_string(), rhs.to_string(opt), opt, pstate); return SASS_MEMORY_NEW(Color_RGBA, pstate, ops[op](lval, rhs.r()), @@ -229,7 +229,7 @@ namespace Sass { case Sass_OP::SUB: case Sass_OP::DIV: { std::string color(rhs.to_string(opt)); - op_color_deprecation(op, lhs.to_string(), color, pstate); + op_color_deprecation(op, lhs.to_string(), color, opt, pstate); return SASS_MEMORY_NEW(String_Quoted, pstate, lhs.to_string(opt) @@ -251,7 +251,7 @@ namespace Sass { throw Exception::ZeroDivisionError(lhs, rhs); } - op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate); + op_color_deprecation(op, lhs.to_string(), rhs.to_string(), opt, pstate); return SASS_MEMORY_NEW(Color_RGBA, pstate, diff --git a/src/parser.cpp b/src/parser.cpp index cfb389d48f..6af7eb7949 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1679,7 +1679,8 @@ namespace Sass { if (lex< ampersand >()) { if (match< ampersand >()) { - warning("In Sass, \"&&\" means two copies of the parent selector. You probably want to use \"and\" instead.", pstate); + ctx.c_options.print_stderr(warning("In Sass, \"&&\" means two copies of the parent" + " selector. You probably want to use \"and\" instead.", pstate)); } return SASS_MEMORY_NEW(Parent_Reference, pstate); } diff --git a/src/sass.hpp b/src/sass.hpp index 014e4fa1a9..17703bca42 100644 --- a/src/sass.hpp +++ b/src/sass.hpp @@ -53,6 +53,8 @@ // For C++ helper #include +#include +#include // output behaviours namespace Sass { @@ -96,12 +98,30 @@ struct Sass_Inspect_Options { // Precision for fractional numbers int precision; + // If this options is set, nothing will be printed to stderr anymore + // The aggregated output on stderr can be fetched via stderr_string + bool suppress_stderr; + + // messages on stderr + std::string stderr_str; + // initialization list (constructor with defaults) Sass_Inspect_Options(Sass_Output_Style style = Sass::NESTED, - int precision = 10) - : output_style(style), precision(precision) + int precision = 10, + bool suppress_stderr = false, + std::string stderr_str = "") + : output_style(style), precision(precision), + suppress_stderr(suppress_stderr), + stderr_str(stderr_str) { } + void print_stderr(const std::string& msg) { + stderr_str += msg; + if (!suppress_stderr) { + std::cerr << msg; + } + } + }; // sass config options structure diff --git a/src/sass_context.cpp b/src/sass_context.cpp index cca864f1cd..dde81ad0fe 100644 --- a/src/sass_context.cpp +++ b/src/sass_context.cpp @@ -119,6 +119,7 @@ namespace Sass { c_ctx->error_column = e.pstate.column + 1; c_ctx->error_src = e.pstate.src; c_ctx->output_string = 0; + c_ctx->stderr_string = 0; c_ctx->source_map_string = 0; json_delete(json_err); } @@ -135,6 +136,7 @@ namespace Sass { c_ctx->error_text = sass_copy_c_string(ba.what()); c_ctx->error_status = 2; c_ctx->output_string = 0; + c_ctx->stderr_string = 0; c_ctx->source_map_string = 0; json_delete(json_err); } @@ -151,6 +153,7 @@ namespace Sass { c_ctx->error_text = sass_copy_c_string(e.what()); c_ctx->error_status = 3; c_ctx->output_string = 0; + c_ctx->stderr_string = 0; c_ctx->source_map_string = 0; json_delete(json_err); } @@ -167,6 +170,7 @@ namespace Sass { c_ctx->error_text = sass_copy_c_string(e.c_str()); c_ctx->error_status = 4; c_ctx->output_string = 0; + c_ctx->stderr_string = 0; c_ctx->source_map_string = 0; json_delete(json_err); } @@ -183,6 +187,7 @@ namespace Sass { c_ctx->error_text = sass_copy_c_string(e); c_ctx->error_status = 4; c_ctx->output_string = 0; + c_ctx->stderr_string = 0; c_ctx->source_map_string = 0; json_delete(json_err); } @@ -198,6 +203,7 @@ namespace Sass { c_ctx->error_text = sass_copy_c_string("unknown"); c_ctx->error_status = 5; c_ctx->output_string = 0; + c_ctx->stderr_string = 0; c_ctx->source_map_string = 0; json_delete(json_err); } @@ -504,9 +510,19 @@ extern "C" { // compile the parsed root block try { compiler->c_ctx->output_string = cpp_ctx->render(root); } // pass catched errors to generic error handler - catch (...) { return handle_errors(compiler->c_ctx) | 1; } + catch (...) { + // get aggregated messages on stderr as char* + std::string STDERR_STR = cpp_ctx->c_options.stderr_str; + char* STDERR = sass_copy_string(STDERR_STR.c_str()); + compiler->c_ctx->stderr_string = STDERR; + return handle_errors(compiler->c_ctx) | 1; + } // generate source map json and store on context compiler->c_ctx->source_map_string = cpp_ctx->render_srcmap(); + // get aggregated messages on stderr as char* + std::string STDERR_STR = cpp_ctx->c_options.stderr_str; + char* STDERR = sass_copy_string(STDERR_STR.c_str()); + compiler->c_ctx->stderr_string = STDERR; // success return 0; } @@ -589,6 +605,7 @@ extern "C" { if (ctx == 0) return; // release the allocated memory (mostly via sass_copy_c_string) if (ctx->output_string) free(ctx->output_string); + if (ctx->stderr_string) free(ctx->stderr_string); if (ctx->source_map_string) free(ctx->source_map_string); if (ctx->error_message) free(ctx->error_message); if (ctx->error_text) free(ctx->error_text); @@ -597,6 +614,7 @@ extern "C" { free_string_array(ctx->included_files); // play safe and reset properties ctx->output_string = 0; + ctx->stderr_string = 0; ctx->source_map_string = 0; ctx->error_message = 0; ctx->error_text = 0; @@ -682,6 +700,7 @@ extern "C" { IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_file_urls); IMPLEMENT_SASS_OPTION_ACCESSOR(bool, omit_source_map_url); IMPLEMENT_SASS_OPTION_ACCESSOR(bool, is_indented_syntax_src); + IMPLEMENT_SASS_OPTION_ACCESSOR(bool, suppress_stderr); IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Function_List, c_functions); IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_importers); IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_headers); @@ -704,6 +723,7 @@ extern "C" { IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_column); IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_src); IMPLEMENT_SASS_CONTEXT_GETTER(const char*, output_string); + IMPLEMENT_SASS_CONTEXT_GETTER(const char*, stderr_string); IMPLEMENT_SASS_CONTEXT_GETTER(const char*, source_map_string); IMPLEMENT_SASS_CONTEXT_GETTER(char**, included_files); @@ -713,6 +733,7 @@ extern "C" { IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_text); IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_file); IMPLEMENT_SASS_CONTEXT_TAKER(char*, output_string); + IMPLEMENT_SASS_CONTEXT_TAKER(char*, stderr_string); IMPLEMENT_SASS_CONTEXT_TAKER(char*, source_map_string); IMPLEMENT_SASS_CONTEXT_TAKER(char**, included_files); diff --git a/src/sass_context.hpp b/src/sass_context.hpp index 8ae1fb12cd..271812615d 100644 --- a/src/sass_context.hpp +++ b/src/sass_context.hpp @@ -78,6 +78,9 @@ struct Sass_Context : Sass_Options // generated output data char* output_string; + // messages on stderr + char* stderr_string; + // generated source map json char* source_map_string;