|
Packit Service |
7770af |
#include "sass.hpp"
|
|
Packit Service |
7770af |
#include <cstring>
|
|
Packit Service |
7770af |
#include <stdexcept>
|
|
Packit Service |
7770af |
#include <sstream>
|
|
Packit Service |
7770af |
#include <string>
|
|
Packit Service |
7770af |
#include <vector>
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#include "sass.h"
|
|
Packit Service |
7770af |
#include "ast.hpp"
|
|
Packit Service |
7770af |
#include "file.hpp"
|
|
Packit Service |
7770af |
#include "json.hpp"
|
|
Packit Service |
7770af |
#include "util.hpp"
|
|
Packit Service |
7770af |
#include "context.hpp"
|
|
Packit Service |
7770af |
#include "sass_context.hpp"
|
|
Packit Service |
7770af |
#include "sass_functions.hpp"
|
|
Packit Service |
7770af |
#include "ast_fwd_decl.hpp"
|
|
Packit Service |
7770af |
#include "error_handling.hpp"
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define LFEED "\n"
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// C++ helper
|
|
Packit Service |
7770af |
namespace Sass {
|
|
Packit Service |
7770af |
// see sass_copy_c_string(std::string str)
|
|
Packit Service |
7770af |
static inline JsonNode* json_mkstream(const std::stringstream& stream)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
// hold on to string on stack!
|
|
Packit Service |
7770af |
std::string str(stream.str());
|
|
Packit Service |
7770af |
return json_mkstring(str.c_str());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
static int handle_error(Sass_Context* c_ctx) {
|
|
Packit Service |
7770af |
try {
|
|
Packit Service |
7770af |
throw;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (Exception::Base& e) {
|
|
Packit Service |
7770af |
std::stringstream msg_stream;
|
|
Packit Service |
7770af |
std::string cwd(Sass::File::get_cwd());
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
std::string msg_prefix(e.errtype());
|
|
Packit Service |
7770af |
bool got_newline = false;
|
|
Packit Service |
7770af |
msg_stream << msg_prefix << ": ";
|
|
Packit Service |
7770af |
const char* msg = e.what();
|
|
Packit Service |
7770af |
while (msg && *msg) {
|
|
Packit Service |
7770af |
if (*msg == '\r') {
|
|
Packit Service |
7770af |
got_newline = true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
else if (*msg == '\n') {
|
|
Packit Service |
7770af |
got_newline = true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
else if (got_newline) {
|
|
Packit Service |
7770af |
msg_stream << std::string(msg_prefix.size() + 2, ' ');
|
|
Packit Service |
7770af |
got_newline = false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
msg_stream << *msg;
|
|
Packit Service |
7770af |
++msg;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
if (!got_newline) msg_stream << "\n";
|
|
Packit Service |
7770af |
if (e.import_stack) {
|
|
Packit Service |
7770af |
for (size_t i = 1; i < e.import_stack->size() - 1; ++i) {
|
|
Packit Service |
7770af |
std::string path((*e.import_stack)[i]->imp_path);
|
|
Packit Service |
7770af |
std::string rel_path(Sass::File::abs2rel(path, cwd, cwd));
|
|
Packit Service |
7770af |
msg_stream << std::string(msg_prefix.size() + 2, ' ');
|
|
Packit Service |
7770af |
msg_stream << (i == 1 ? " on line " : " from line ");
|
|
Packit Service |
7770af |
msg_stream << e.pstate.line + 1 << " of " << rel_path << "\n";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
else {
|
|
Packit Service |
7770af |
std::string rel_path(Sass::File::abs2rel(e.pstate.path, cwd, cwd));
|
|
Packit Service |
7770af |
msg_stream << std::string(msg_prefix.size() + 2, ' ');
|
|
Packit Service |
7770af |
msg_stream << " on line " << e.pstate.line + 1 << " of " << rel_path << "\n";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// now create the code trace (ToDo: maybe have util functions?)
|
|
Packit Service |
7770af |
if (e.pstate.line != std::string::npos && e.pstate.column != std::string::npos) {
|
|
Packit Service |
7770af |
size_t line = e.pstate.line;
|
|
Packit Service |
7770af |
const char* line_beg = e.pstate.src;
|
|
Packit Service |
7770af |
while (line_beg && *line_beg && line) {
|
|
Packit Service |
7770af |
if (*line_beg == '\n') --line;
|
|
Packit Service |
7770af |
++line_beg;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
const char* line_end = line_beg;
|
|
Packit Service |
7770af |
while (line_end && *line_end && *line_end != '\n') {
|
|
Packit Service |
7770af |
if (*line_end == '\n') break;
|
|
Packit Service |
7770af |
if (*line_end == '\r') break;
|
|
Packit Service |
7770af |
line_end++;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
size_t max_left = 42; size_t max_right = 78;
|
|
Packit Service |
7770af |
size_t move_in = e.pstate.column > max_left ? e.pstate.column - max_left : 0;
|
|
Packit Service |
7770af |
size_t shorten = (line_end - line_beg) - move_in > max_right ?
|
|
Packit Service |
7770af |
(line_end - line_beg) - move_in - max_right : 0;
|
|
Packit Service |
7770af |
msg_stream << ">> " << std::string(line_beg + move_in, line_end - shorten) << "\n";
|
|
Packit Service |
7770af |
msg_stream << " " << std::string(e.pstate.column - move_in, '-') << "^\n";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
JsonNode* json_err = json_mkobject();
|
|
Packit Service |
7770af |
json_append_member(json_err, "status", json_mknumber(1));
|
|
Packit Service |
7770af |
json_append_member(json_err, "file", json_mkstring(e.pstate.path));
|
|
Packit Service |
7770af |
json_append_member(json_err, "line", json_mknumber((double)(e.pstate.line + 1)));
|
|
Packit Service |
7770af |
json_append_member(json_err, "column", json_mknumber((double)(e.pstate.column + 1)));
|
|
Packit Service |
7770af |
json_append_member(json_err, "message", json_mkstring(e.what()));
|
|
Packit Service |
7770af |
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
|
Packit Service |
7770af |
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
|
Packit Service |
7770af |
catch (...) {}
|
|
Packit Service |
7770af |
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
|
Packit Service |
7770af |
c_ctx->error_text = sass_copy_c_string(e.what());
|
|
Packit Service |
7770af |
c_ctx->error_status = 1;
|
|
Packit Service |
7770af |
c_ctx->error_file = sass_copy_c_string(e.pstate.path);
|
|
Packit Service |
7770af |
c_ctx->error_line = e.pstate.line + 1;
|
|
Packit Service |
7770af |
c_ctx->error_column = e.pstate.column + 1;
|
|
Packit Service |
7770af |
c_ctx->error_src = e.pstate.src;
|
|
Packit Service |
7770af |
c_ctx->output_string = 0;
|
|
Packit Service |
7770af |
c_ctx->source_map_string = 0;
|
|
Packit Service |
7770af |
json_delete(json_err);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (std::bad_alloc& ba) {
|
|
Packit Service |
7770af |
std::stringstream msg_stream;
|
|
Packit Service |
7770af |
JsonNode* json_err = json_mkobject();
|
|
Packit Service |
7770af |
msg_stream << "Unable to allocate memory: " << ba.what() << std::endl;
|
|
Packit Service |
7770af |
json_append_member(json_err, "status", json_mknumber(2));
|
|
Packit Service |
7770af |
json_append_member(json_err, "message", json_mkstring(ba.what()));
|
|
Packit Service |
7770af |
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
|
Packit Service |
7770af |
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
|
Packit Service |
7770af |
catch (...) {}
|
|
Packit Service |
7770af |
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
|
Packit Service |
7770af |
c_ctx->error_text = sass_copy_c_string(ba.what());
|
|
Packit Service |
7770af |
c_ctx->error_status = 2;
|
|
Packit Service |
7770af |
c_ctx->output_string = 0;
|
|
Packit Service |
7770af |
c_ctx->source_map_string = 0;
|
|
Packit Service |
7770af |
json_delete(json_err);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (std::exception& e) {
|
|
Packit Service |
7770af |
std::stringstream msg_stream;
|
|
Packit Service |
7770af |
JsonNode* json_err = json_mkobject();
|
|
Packit Service |
7770af |
msg_stream << "Internal Error: " << e.what() << std::endl;
|
|
Packit Service |
7770af |
json_append_member(json_err, "status", json_mknumber(3));
|
|
Packit Service |
7770af |
json_append_member(json_err, "message", json_mkstring(e.what()));
|
|
Packit Service |
7770af |
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
|
Packit Service |
7770af |
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
|
Packit Service |
7770af |
catch (...) {}
|
|
Packit Service |
7770af |
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
|
Packit Service |
7770af |
c_ctx->error_text = sass_copy_c_string(e.what());
|
|
Packit Service |
7770af |
c_ctx->error_status = 3;
|
|
Packit Service |
7770af |
c_ctx->output_string = 0;
|
|
Packit Service |
7770af |
c_ctx->source_map_string = 0;
|
|
Packit Service |
7770af |
json_delete(json_err);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (std::string& e) {
|
|
Packit Service |
7770af |
std::stringstream msg_stream;
|
|
Packit Service |
7770af |
JsonNode* json_err = json_mkobject();
|
|
Packit Service |
7770af |
msg_stream << "Internal Error: " << e << std::endl;
|
|
Packit Service |
7770af |
json_append_member(json_err, "status", json_mknumber(4));
|
|
Packit Service |
7770af |
json_append_member(json_err, "message", json_mkstring(e.c_str()));
|
|
Packit Service |
7770af |
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
|
Packit Service |
7770af |
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
|
Packit Service |
7770af |
catch (...) {}
|
|
Packit Service |
7770af |
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
|
Packit Service |
7770af |
c_ctx->error_text = sass_copy_c_string(e.c_str());
|
|
Packit Service |
7770af |
c_ctx->error_status = 4;
|
|
Packit Service |
7770af |
c_ctx->output_string = 0;
|
|
Packit Service |
7770af |
c_ctx->source_map_string = 0;
|
|
Packit Service |
7770af |
json_delete(json_err);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (const char* e) {
|
|
Packit Service |
7770af |
std::stringstream msg_stream;
|
|
Packit Service |
7770af |
JsonNode* json_err = json_mkobject();
|
|
Packit Service |
7770af |
msg_stream << "Internal Error: " << e << std::endl;
|
|
Packit Service |
7770af |
json_append_member(json_err, "status", json_mknumber(4));
|
|
Packit Service |
7770af |
json_append_member(json_err, "message", json_mkstring(e));
|
|
Packit Service |
7770af |
json_append_member(json_err, "formatted", json_mkstream(msg_stream));
|
|
Packit Service |
7770af |
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
|
Packit Service |
7770af |
catch (...) {}
|
|
Packit Service |
7770af |
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
|
Packit Service |
7770af |
c_ctx->error_text = sass_copy_c_string(e);
|
|
Packit Service |
7770af |
c_ctx->error_status = 4;
|
|
Packit Service |
7770af |
c_ctx->output_string = 0;
|
|
Packit Service |
7770af |
c_ctx->source_map_string = 0;
|
|
Packit Service |
7770af |
json_delete(json_err);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (...) {
|
|
Packit Service |
7770af |
std::stringstream msg_stream;
|
|
Packit Service |
7770af |
JsonNode* json_err = json_mkobject();
|
|
Packit Service |
7770af |
msg_stream << "Unknown error occurred" << std::endl;
|
|
Packit Service |
7770af |
json_append_member(json_err, "status", json_mknumber(5));
|
|
Packit Service |
7770af |
json_append_member(json_err, "message", json_mkstring("unknown"));
|
|
Packit Service |
7770af |
try { c_ctx->error_json = json_stringify(json_err, " "); }
|
|
Packit Service |
7770af |
catch (...) {}
|
|
Packit Service |
7770af |
c_ctx->error_message = sass_copy_string(msg_stream.str());
|
|
Packit Service |
7770af |
c_ctx->error_text = sass_copy_c_string("unknown");
|
|
Packit Service |
7770af |
c_ctx->error_status = 5;
|
|
Packit Service |
7770af |
c_ctx->output_string = 0;
|
|
Packit Service |
7770af |
c_ctx->source_map_string = 0;
|
|
Packit Service |
7770af |
json_delete(json_err);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return c_ctx->error_status;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// allow one error handler to throw another error
|
|
Packit Service |
7770af |
// this can happen with invalid utf8 and json lib
|
|
Packit Service |
7770af |
static int handle_errors(Sass_Context* c_ctx) {
|
|
Packit Service |
7770af |
try { return handle_error(c_ctx); }
|
|
Packit Service |
7770af |
catch (...) { return handle_error(c_ctx); }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
static Block_Obj sass_parse_block(Sass_Compiler* compiler) throw()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// assert valid pointer
|
|
Packit Service |
7770af |
if (compiler == 0) return 0;
|
|
Packit Service |
7770af |
// The cpp context must be set by now
|
|
Packit Service |
7770af |
Context* cpp_ctx = compiler->cpp_ctx;
|
|
Packit Service |
7770af |
Sass_Context* c_ctx = compiler->c_ctx;
|
|
Packit Service |
7770af |
// We will take care to wire up the rest
|
|
Packit Service |
7770af |
compiler->cpp_ctx->c_compiler = compiler;
|
|
Packit Service |
7770af |
compiler->state = SASS_COMPILER_PARSED;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
try {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// get input/output path from options
|
|
Packit Service |
7770af |
std::string input_path = safe_str(c_ctx->input_path);
|
|
Packit Service |
7770af |
std::string output_path = safe_str(c_ctx->output_path);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// maybe skip some entries of included files
|
|
Packit Service |
7770af |
// we do not include stdin for data contexts
|
|
Packit Service |
7770af |
bool skip = c_ctx->type == SASS_CONTEXT_DATA;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// dispatch parse call
|
|
Packit Service |
7770af |
Block_Obj root(cpp_ctx->parse());
|
|
Packit Service |
7770af |
// abort on errors
|
|
Packit Service |
7770af |
if (!root) return 0;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// skip all prefixed files? (ToDo: check srcmap)
|
|
Packit Service |
7770af |
// IMO source-maps should point to headers already
|
|
Packit Service |
7770af |
// therefore don't skip it for now. re-enable or
|
|
Packit Service |
7770af |
// remove completely once this is tested
|
|
Packit Service |
7770af |
size_t headers = cpp_ctx->head_imports;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// copy the included files on to the context (dont forget to free later)
|
|
Packit Service |
7770af |
if (copy_strings(cpp_ctx->get_included_files(skip, headers), &c_ctx->included_files) == NULL)
|
|
Packit Service |
7770af |
throw(std::bad_alloc());
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// return parsed block
|
|
Packit Service |
7770af |
return root;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// pass errors to generic error handler
|
|
Packit Service |
7770af |
catch (...) { handle_errors(c_ctx); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// error
|
|
Packit Service |
7770af |
return 0;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
extern "C" {
|
|
Packit Service |
7770af |
using namespace Sass;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
static void sass_clear_options (struct Sass_Options* options);
|
|
Packit Service |
7770af |
static void sass_reset_options (struct Sass_Options* options);
|
|
Packit Service |
7770af |
static void copy_options(struct Sass_Options* to, struct Sass_Options* from) {
|
|
Packit Service |
7770af |
// do not overwrite ourself
|
|
Packit Service |
7770af |
if (to == from) return;
|
|
Packit Service |
7770af |
// free assigned memory
|
|
Packit Service |
7770af |
sass_clear_options(to);
|
|
Packit Service |
7770af |
// move memory
|
|
Packit Service |
7770af |
*to = *from;
|
|
Packit Service |
7770af |
// Reset pointers on source
|
|
Packit Service |
7770af |
sass_reset_options(from);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define IMPLEMENT_SASS_OPTION_ACCESSOR(type, option) \
|
|
Packit Service |
7770af |
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return options->option; } \
|
|
Packit Service |
7770af |
void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) { options->option = option; }
|
|
Packit Service |
7770af |
#define IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \
|
|
Packit Service |
7770af |
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return safe_str(options->option, def); }
|
|
Packit Service |
7770af |
#define IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def) \
|
|
Packit Service |
7770af |
void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) \
|
|
Packit Service |
7770af |
{ free(options->option); options->option = option || def ? sass_copy_c_string(option ? option : def) : 0; }
|
|
Packit Service |
7770af |
#define IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(type, option, def) \
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def)
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define IMPLEMENT_SASS_CONTEXT_GETTER(type, option) \
|
|
Packit Service |
7770af |
type ADDCALL sass_context_get_##option (struct Sass_Context* ctx) { return ctx->option; }
|
|
Packit Service |
7770af |
#define IMPLEMENT_SASS_CONTEXT_TAKER(type, option) \
|
|
Packit Service |
7770af |
type sass_context_take_##option (struct Sass_Context* ctx) \
|
|
Packit Service |
7770af |
{ type foo = ctx->option; ctx->option = 0; return foo; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// generic compilation function (not exported, use file/data compile instead)
|
|
Packit Service |
7770af |
static Sass_Compiler* sass_prepare_context (Sass_Context* c_ctx, Context* cpp_ctx) throw()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
try {
|
|
Packit Service |
7770af |
// register our custom functions
|
|
Packit Service |
7770af |
if (c_ctx->c_functions) {
|
|
Packit Service |
7770af |
auto this_func_data = c_ctx->c_functions;
|
|
Packit Service |
7770af |
while (this_func_data && *this_func_data) {
|
|
Packit Service |
7770af |
cpp_ctx->add_c_function(*this_func_data);
|
|
Packit Service |
7770af |
++this_func_data;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// register our custom headers
|
|
Packit Service |
7770af |
if (c_ctx->c_headers) {
|
|
Packit Service |
7770af |
auto this_head_data = c_ctx->c_headers;
|
|
Packit Service |
7770af |
while (this_head_data && *this_head_data) {
|
|
Packit Service |
7770af |
cpp_ctx->add_c_header(*this_head_data);
|
|
Packit Service |
7770af |
++this_head_data;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// register our custom importers
|
|
Packit Service |
7770af |
if (c_ctx->c_importers) {
|
|
Packit Service |
7770af |
auto this_imp_data = c_ctx->c_importers;
|
|
Packit Service |
7770af |
while (this_imp_data && *this_imp_data) {
|
|
Packit Service |
7770af |
cpp_ctx->add_c_importer(*this_imp_data);
|
|
Packit Service |
7770af |
++this_imp_data;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// reset error status
|
|
Packit Service |
7770af |
c_ctx->error_json = 0;
|
|
Packit Service |
7770af |
c_ctx->error_text = 0;
|
|
Packit Service |
7770af |
c_ctx->error_message = 0;
|
|
Packit Service |
7770af |
c_ctx->error_status = 0;
|
|
Packit Service |
7770af |
// reset error position
|
|
Packit Service |
7770af |
c_ctx->error_src = 0;
|
|
Packit Service |
7770af |
c_ctx->error_file = 0;
|
|
Packit Service |
7770af |
c_ctx->error_line = std::string::npos;
|
|
Packit Service |
7770af |
c_ctx->error_column = std::string::npos;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// allocate a new compiler instance
|
|
Packit Service |
7770af |
void* ctxmem = calloc(1, sizeof(struct Sass_Compiler));
|
|
Packit Service |
7770af |
if (ctxmem == 0) { std::cerr << "Error allocating memory for context" << std::endl; return 0; }
|
|
Packit Service |
7770af |
Sass_Compiler* compiler = (struct Sass_Compiler*) ctxmem;
|
|
Packit Service |
7770af |
compiler->state = SASS_COMPILER_CREATED;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// store in sass compiler
|
|
Packit Service |
7770af |
compiler->c_ctx = c_ctx;
|
|
Packit Service |
7770af |
compiler->cpp_ctx = cpp_ctx;
|
|
Packit Service |
7770af |
cpp_ctx->c_compiler = compiler;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// use to parse block
|
|
Packit Service |
7770af |
return compiler;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// pass errors to generic error handler
|
|
Packit Service |
7770af |
catch (...) { handle_errors(c_ctx); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// error
|
|
Packit Service |
7770af |
return 0;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// generic compilation function (not exported, use file/data compile instead)
|
|
Packit Service |
7770af |
static int sass_compile_context (Sass_Context* c_ctx, Context* cpp_ctx)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// prepare sass compiler with context and options
|
|
Packit Service |
7770af |
Sass_Compiler* compiler = sass_prepare_context(c_ctx, cpp_ctx);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
try {
|
|
Packit Service |
7770af |
// call each compiler step
|
|
Packit Service |
7770af |
sass_compiler_parse(compiler);
|
|
Packit Service |
7770af |
sass_compiler_execute(compiler);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// pass errors to generic error handler
|
|
Packit Service |
7770af |
catch (...) { handle_errors(c_ctx); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
sass_delete_compiler(compiler);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
return c_ctx->error_status;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
inline void init_options (struct Sass_Options* options)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
options->precision = 5;
|
|
Packit Service |
7770af |
options->indent = " ";
|
|
Packit Service |
7770af |
options->linefeed = LFEED;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Sass_Options* ADDCALL sass_make_options (void)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
struct Sass_Options* options = (struct Sass_Options*) calloc(1, sizeof(struct Sass_Options));
|
|
Packit Service |
7770af |
if (options == 0) { std::cerr << "Error allocating memory for options" << std::endl; return 0; }
|
|
Packit Service |
7770af |
init_options(options);
|
|
Packit Service |
7770af |
return options;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Sass_File_Context* ADDCALL sass_make_file_context(const char* input_path)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
SharedObj::setTaint(true); // needed for static colors
|
|
Packit Service |
7770af |
struct Sass_File_Context* ctx = (struct Sass_File_Context*) calloc(1, sizeof(struct Sass_File_Context));
|
|
Packit Service |
7770af |
if (ctx == 0) { std::cerr << "Error allocating memory for file context" << std::endl; return 0; }
|
|
Packit Service |
7770af |
ctx->type = SASS_CONTEXT_FILE;
|
|
Packit Service |
7770af |
init_options(ctx);
|
|
Packit Service |
7770af |
try {
|
|
Packit Service |
7770af |
if (input_path == 0) { throw(std::runtime_error("File context created without an input path")); }
|
|
Packit Service |
7770af |
if (*input_path == 0) { throw(std::runtime_error("File context created with empty input path")); }
|
|
Packit Service |
7770af |
sass_option_set_input_path(ctx, input_path);
|
|
Packit Service |
7770af |
} catch (...) {
|
|
Packit Service |
7770af |
handle_errors(ctx);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return ctx;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Sass_Data_Context* ADDCALL sass_make_data_context(char* source_string)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
struct Sass_Data_Context* ctx = (struct Sass_Data_Context*) calloc(1, sizeof(struct Sass_Data_Context));
|
|
Packit Service |
7770af |
if (ctx == 0) { std::cerr << "Error allocating memory for data context" << std::endl; return 0; }
|
|
Packit Service |
7770af |
ctx->type = SASS_CONTEXT_DATA;
|
|
Packit Service |
7770af |
init_options(ctx);
|
|
Packit Service |
7770af |
try {
|
|
Packit Service |
7770af |
if (source_string == 0) { throw(std::runtime_error("Data context created without a source string")); }
|
|
Packit Service |
7770af |
if (*source_string == 0) { throw(std::runtime_error("Data context created with empty source string")); }
|
|
Packit Service |
7770af |
ctx->source_string = source_string;
|
|
Packit Service |
7770af |
} catch (...) {
|
|
Packit Service |
7770af |
handle_errors(ctx);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return ctx;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (data_ctx == 0) return 0;
|
|
Packit Service |
7770af |
Context* cpp_ctx = new Data_Context(*data_ctx);
|
|
Packit Service |
7770af |
return sass_prepare_context(data_ctx, cpp_ctx);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_Context* file_ctx)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (file_ctx == 0) return 0;
|
|
Packit Service |
7770af |
Context* cpp_ctx = new File_Context(*file_ctx);
|
|
Packit Service |
7770af |
return sass_prepare_context(file_ctx, cpp_ctx);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
int ADDCALL sass_compile_data_context(Sass_Data_Context* data_ctx)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (data_ctx == 0) return 1;
|
|
Packit Service |
7770af |
if (data_ctx->error_status)
|
|
Packit Service |
7770af |
return data_ctx->error_status;
|
|
Packit Service |
7770af |
try {
|
|
Packit Service |
7770af |
if (data_ctx->source_string == 0) { throw(std::runtime_error("Data context has no source string")); }
|
|
Packit Service |
7770af |
// empty source string is a valid case, even if not really usefull (different than with file context)
|
|
Packit Service |
7770af |
// if (*data_ctx->source_string == 0) { throw(std::runtime_error("Data context has empty source string")); }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (...) { return handle_errors(data_ctx) | 1; }
|
|
Packit Service |
7770af |
Context* cpp_ctx = new Data_Context(*data_ctx);
|
|
Packit Service |
7770af |
return sass_compile_context(data_ctx, cpp_ctx);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
int ADDCALL sass_compile_file_context(Sass_File_Context* file_ctx)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (file_ctx == 0) return 1;
|
|
Packit Service |
7770af |
if (file_ctx->error_status)
|
|
Packit Service |
7770af |
return file_ctx->error_status;
|
|
Packit Service |
7770af |
try {
|
|
Packit Service |
7770af |
if (file_ctx->input_path == 0) { throw(std::runtime_error("File context has no input path")); }
|
|
Packit Service |
7770af |
if (*file_ctx->input_path == 0) { throw(std::runtime_error("File context has empty input path")); }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (...) { return handle_errors(file_ctx) | 1; }
|
|
Packit Service |
7770af |
Context* cpp_ctx = new File_Context(*file_ctx);
|
|
Packit Service |
7770af |
return sass_compile_context(file_ctx, cpp_ctx);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
int ADDCALL sass_compiler_parse(struct Sass_Compiler* compiler)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (compiler == 0) return 1;
|
|
Packit Service |
7770af |
if (compiler->state == SASS_COMPILER_PARSED) return 0;
|
|
Packit Service |
7770af |
if (compiler->state != SASS_COMPILER_CREATED) return -1;
|
|
Packit Service |
7770af |
if (compiler->c_ctx == NULL) return 1;
|
|
Packit Service |
7770af |
if (compiler->cpp_ctx == NULL) return 1;
|
|
Packit Service |
7770af |
if (compiler->c_ctx->error_status)
|
|
Packit Service |
7770af |
return compiler->c_ctx->error_status;
|
|
Packit Service |
7770af |
// parse the context we have set up (file or data)
|
|
Packit Service |
7770af |
compiler->root = sass_parse_block(compiler);
|
|
Packit Service |
7770af |
// success
|
|
Packit Service |
7770af |
return 0;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (compiler == 0) return 1;
|
|
Packit Service |
7770af |
if (compiler->state == SASS_COMPILER_EXECUTED) return 0;
|
|
Packit Service |
7770af |
if (compiler->state != SASS_COMPILER_PARSED) return -1;
|
|
Packit Service |
7770af |
if (compiler->c_ctx == NULL) return 1;
|
|
Packit Service |
7770af |
if (compiler->cpp_ctx == NULL) return 1;
|
|
Packit Service |
7770af |
if (compiler->root.isNull()) return 1;
|
|
Packit Service |
7770af |
if (compiler->c_ctx->error_status)
|
|
Packit Service |
7770af |
return compiler->c_ctx->error_status;
|
|
Packit Service |
7770af |
compiler->state = SASS_COMPILER_EXECUTED;
|
|
Packit Service |
7770af |
Context* cpp_ctx = compiler->cpp_ctx;
|
|
Packit Service |
7770af |
Block_Obj root = compiler->root;
|
|
Packit Service |
7770af |
// compile the parsed root block
|
|
Packit Service |
7770af |
try { compiler->c_ctx->output_string = cpp_ctx->render(root); }
|
|
Packit Service |
7770af |
// pass catched errors to generic error handler
|
|
Packit Service |
7770af |
catch (...) { return handle_errors(compiler->c_ctx) | 1; }
|
|
Packit Service |
7770af |
// generate source map json and store on context
|
|
Packit Service |
7770af |
compiler->c_ctx->source_map_string = cpp_ctx->render_srcmap();
|
|
Packit Service |
7770af |
// success
|
|
Packit Service |
7770af |
return 0;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// helper function, not exported, only accessible locally
|
|
Packit Service |
7770af |
static void sass_reset_options (struct Sass_Options* options)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
// free pointer before
|
|
Packit Service |
7770af |
// or copy/move them
|
|
Packit Service |
7770af |
options->input_path = 0;
|
|
Packit Service |
7770af |
options->output_path = 0;
|
|
Packit Service |
7770af |
options->plugin_path = 0;
|
|
Packit Service |
7770af |
options->include_path = 0;
|
|
Packit Service |
7770af |
options->source_map_file = 0;
|
|
Packit Service |
7770af |
options->source_map_root = 0;
|
|
Packit Service |
7770af |
options->c_functions = 0;
|
|
Packit Service |
7770af |
options->c_importers = 0;
|
|
Packit Service |
7770af |
options->c_headers = 0;
|
|
Packit Service |
7770af |
options->plugin_paths = 0;
|
|
Packit Service |
7770af |
options->include_paths = 0;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// helper function, not exported, only accessible locally
|
|
Packit Service |
7770af |
static void sass_clear_options (struct Sass_Options* options)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (options == 0) return;
|
|
Packit Service |
7770af |
// Deallocate custom functions
|
|
Packit Service |
7770af |
if (options->c_functions) {
|
|
Packit Service |
7770af |
Sass_Function_List this_func_data = options->c_functions;
|
|
Packit Service |
7770af |
while (this_func_data && *this_func_data) {
|
|
Packit Service |
7770af |
free(*this_func_data);
|
|
Packit Service |
7770af |
++this_func_data;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// Deallocate custom headers
|
|
Packit Service |
7770af |
if (options->c_headers) {
|
|
Packit Service |
7770af |
Sass_Importer_List this_head_data = options->c_headers;
|
|
Packit Service |
7770af |
while (this_head_data && *this_head_data) {
|
|
Packit Service |
7770af |
free(*this_head_data);
|
|
Packit Service |
7770af |
++this_head_data;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// Deallocate custom importers
|
|
Packit Service |
7770af |
if (options->c_importers) {
|
|
Packit Service |
7770af |
Sass_Importer_List this_imp_data = options->c_importers;
|
|
Packit Service |
7770af |
while (this_imp_data && *this_imp_data) {
|
|
Packit Service |
7770af |
free(*this_imp_data);
|
|
Packit Service |
7770af |
++this_imp_data;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// Deallocate inc paths
|
|
Packit Service |
7770af |
if (options->plugin_paths) {
|
|
Packit Service |
7770af |
struct string_list* cur;
|
|
Packit Service |
7770af |
struct string_list* next;
|
|
Packit Service |
7770af |
cur = options->plugin_paths;
|
|
Packit Service |
7770af |
while (cur) {
|
|
Packit Service |
7770af |
next = cur->next;
|
|
Packit Service |
7770af |
free(cur->string);
|
|
Packit Service |
7770af |
free(cur);
|
|
Packit Service |
7770af |
cur = next;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// Deallocate inc paths
|
|
Packit Service |
7770af |
if (options->include_paths) {
|
|
Packit Service |
7770af |
struct string_list* cur;
|
|
Packit Service |
7770af |
struct string_list* next;
|
|
Packit Service |
7770af |
cur = options->include_paths;
|
|
Packit Service |
7770af |
while (cur) {
|
|
Packit Service |
7770af |
next = cur->next;
|
|
Packit Service |
7770af |
free(cur->string);
|
|
Packit Service |
7770af |
free(cur);
|
|
Packit Service |
7770af |
cur = next;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// Free options strings
|
|
Packit Service |
7770af |
free(options->input_path);
|
|
Packit Service |
7770af |
free(options->output_path);
|
|
Packit Service |
7770af |
free(options->plugin_path);
|
|
Packit Service |
7770af |
free(options->include_path);
|
|
Packit Service |
7770af |
free(options->source_map_file);
|
|
Packit Service |
7770af |
free(options->source_map_root);
|
|
Packit Service |
7770af |
// Free custom functions
|
|
Packit Service |
7770af |
free(options->c_functions);
|
|
Packit Service |
7770af |
// Free custom importers
|
|
Packit Service |
7770af |
free(options->c_importers);
|
|
Packit Service |
7770af |
free(options->c_headers);
|
|
Packit Service |
7770af |
// Reset our pointers
|
|
Packit Service |
7770af |
options->input_path = 0;
|
|
Packit Service |
7770af |
options->output_path = 0;
|
|
Packit Service |
7770af |
options->plugin_path = 0;
|
|
Packit Service |
7770af |
options->include_path = 0;
|
|
Packit Service |
7770af |
options->source_map_file = 0;
|
|
Packit Service |
7770af |
options->source_map_root = 0;
|
|
Packit Service |
7770af |
options->c_functions = 0;
|
|
Packit Service |
7770af |
options->c_importers = 0;
|
|
Packit Service |
7770af |
options->c_headers = 0;
|
|
Packit Service |
7770af |
options->plugin_paths = 0;
|
|
Packit Service |
7770af |
options->include_paths = 0;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// helper function, not exported, only accessible locally
|
|
Packit Service |
7770af |
// sass_free_context is also defined in old sass_interface
|
|
Packit Service |
7770af |
static void sass_clear_context (struct Sass_Context* ctx)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (ctx == 0) return;
|
|
Packit Service |
7770af |
// release the allocated memory (mostly via sass_copy_c_string)
|
|
Packit Service |
7770af |
if (ctx->output_string) free(ctx->output_string);
|
|
Packit Service |
7770af |
if (ctx->source_map_string) free(ctx->source_map_string);
|
|
Packit Service |
7770af |
if (ctx->error_message) free(ctx->error_message);
|
|
Packit Service |
7770af |
if (ctx->error_text) free(ctx->error_text);
|
|
Packit Service |
7770af |
if (ctx->error_json) free(ctx->error_json);
|
|
Packit Service |
7770af |
if (ctx->error_file) free(ctx->error_file);
|
|
Packit Service |
7770af |
free_string_array(ctx->included_files);
|
|
Packit Service |
7770af |
// play safe and reset properties
|
|
Packit Service |
7770af |
ctx->output_string = 0;
|
|
Packit Service |
7770af |
ctx->source_map_string = 0;
|
|
Packit Service |
7770af |
ctx->error_message = 0;
|
|
Packit Service |
7770af |
ctx->error_text = 0;
|
|
Packit Service |
7770af |
ctx->error_json = 0;
|
|
Packit Service |
7770af |
ctx->error_file = 0;
|
|
Packit Service |
7770af |
ctx->included_files = 0;
|
|
Packit Service |
7770af |
// debug leaked memory
|
|
Packit Service |
7770af |
#ifdef DEBUG_SHARED_PTR
|
|
Packit Service |
7770af |
SharedObj::dumpMemLeaks();
|
|
Packit Service |
7770af |
#endif
|
|
Packit Service |
7770af |
// now clear the options
|
|
Packit Service |
7770af |
sass_clear_options(ctx);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void ADDCALL sass_delete_compiler (struct Sass_Compiler* compiler)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (compiler == 0) {
|
|
Packit Service |
7770af |
return;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
Context* cpp_ctx = compiler->cpp_ctx;
|
|
Packit Service |
7770af |
if (cpp_ctx) delete(cpp_ctx);
|
|
Packit Service |
7770af |
compiler->cpp_ctx = NULL;
|
|
Packit Service |
7770af |
compiler->c_ctx = NULL;
|
|
Packit Service |
7770af |
compiler->root = NULL;
|
|
Packit Service |
7770af |
free(compiler);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void ADDCALL sass_delete_options (struct Sass_Options* options)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
sass_clear_options(options); free(options);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Deallocate all associated memory with file context
|
|
Packit Service |
7770af |
void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
// clear the context and free it
|
|
Packit Service |
7770af |
sass_clear_context(ctx); free(ctx);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// Deallocate all associated memory with data context
|
|
Packit Service |
7770af |
void ADDCALL sass_delete_data_context (struct Sass_Data_Context* ctx)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
// clean the source string if it was not passed
|
|
Packit Service |
7770af |
// we reset this member once we start parsing
|
|
Packit Service |
7770af |
if (ctx->source_string) free(ctx->source_string);
|
|
Packit Service |
7770af |
// clear the context and free it
|
|
Packit Service |
7770af |
sass_clear_context(ctx); free(ctx);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Getters for sass context from specific implementations
|
|
Packit Service |
7770af |
struct Sass_Context* ADDCALL sass_file_context_get_context(struct Sass_File_Context* ctx) { return ctx; }
|
|
Packit Service |
7770af |
struct Sass_Context* ADDCALL sass_data_context_get_context(struct Sass_Data_Context* ctx) { return ctx; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Getters for context options from Sass_Context
|
|
Packit Service |
7770af |
struct Sass_Options* ADDCALL sass_context_get_options(struct Sass_Context* ctx) { return ctx; }
|
|
Packit Service |
7770af |
struct Sass_Options* ADDCALL sass_file_context_get_options(struct Sass_File_Context* ctx) { return ctx; }
|
|
Packit Service |
7770af |
struct Sass_Options* ADDCALL sass_data_context_get_options(struct Sass_Data_Context* ctx) { return ctx; }
|
|
Packit Service |
7770af |
void ADDCALL sass_file_context_set_options (struct Sass_File_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }
|
|
Packit Service |
7770af |
void ADDCALL sass_data_context_set_options (struct Sass_Data_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Getters for Sass_Compiler options (get conected sass context)
|
|
Packit Service |
7770af |
enum Sass_Compiler_State ADDCALL sass_compiler_get_state(struct Sass_Compiler* compiler) { return compiler->state; }
|
|
Packit Service |
7770af |
struct Sass_Context* ADDCALL sass_compiler_get_context(struct Sass_Compiler* compiler) { return compiler->c_ctx; }
|
|
Packit Service |
7770af |
struct Sass_Options* ADDCALL sass_compiler_get_options(struct Sass_Compiler* compiler) { return compiler->c_ctx; }
|
|
Packit Service |
7770af |
// Getters for Sass_Compiler options (query import stack)
|
|
Packit Service |
7770af |
size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.size(); }
|
|
Packit Service |
7770af |
Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.back(); }
|
|
Packit Service |
7770af |
Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx) { return compiler->cpp_ctx->import_stack[idx]; }
|
|
Packit Service |
7770af |
// Getters for Sass_Compiler options (query function stack)
|
|
Packit Service |
7770af |
size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->callee_stack.size(); }
|
|
Packit Service |
7770af |
Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler) { return &compiler->cpp_ctx->callee_stack.back(); }
|
|
Packit Service |
7770af |
Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx) { return &compiler->cpp_ctx->callee_stack[idx]; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Calculate the size of the stored null terminated array
|
|
Packit Service |
7770af |
size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx)
|
|
Packit Service |
7770af |
{ size_t l = 0; auto i = ctx->included_files; while (i && *i) { ++i; ++l; } return l; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Create getter and setters for options
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(int, precision);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(enum Sass_Output_Style, output_style);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_comments);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_embed);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_contents);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_file_urls);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, omit_source_map_url);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, is_indented_syntax_src);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Function_List, c_functions);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_importers);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_headers);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, indent);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, linefeed);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, plugin_path, 0);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, include_path, 0);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, input_path, 0);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, output_path, 0);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_file, 0);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_root, 0);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Create getter and setters for context
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(int, error_status);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_json);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_message);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_text);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_file);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_line);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_column);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_src);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, output_string);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, source_map_string);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_GETTER(char**, included_files);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Take ownership of memory (value on context is set to 0)
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_json);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_message);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_text);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_file);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_TAKER(char*, output_string);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_TAKER(char*, source_map_string);
|
|
Packit Service |
7770af |
IMPLEMENT_SASS_CONTEXT_TAKER(char**, included_files);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Push function for include paths (no manipulation support for now)
|
|
Packit Service |
7770af |
void ADDCALL sass_option_push_include_path(struct Sass_Options* options, const char* path)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
struct string_list* include_path = (struct string_list*) calloc(1, sizeof(struct string_list));
|
|
Packit Service |
7770af |
if (include_path == 0) return;
|
|
Packit Service |
7770af |
include_path->string = path ? sass_copy_c_string(path) : 0;
|
|
Packit Service |
7770af |
struct string_list* last = options->include_paths;
|
|
Packit Service |
7770af |
if (!options->include_paths) {
|
|
Packit Service |
7770af |
options->include_paths = include_path;
|
|
Packit Service |
7770af |
} else {
|
|
Packit Service |
7770af |
while (last->next)
|
|
Packit Service |
7770af |
last = last->next;
|
|
Packit Service |
7770af |
last->next = include_path;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Push function for include paths (no manipulation support for now)
|
|
Packit Service |
7770af |
size_t ADDCALL sass_option_get_include_path_size(struct Sass_Options* options)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
size_t len = 0;
|
|
Packit Service |
7770af |
struct string_list* cur = options->include_paths;
|
|
Packit Service |
7770af |
while (cur) { len ++; cur = cur->next; }
|
|
Packit Service |
7770af |
return len;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Push function for include paths (no manipulation support for now)
|
|
Packit Service |
7770af |
const char* ADDCALL sass_option_get_include_path(struct Sass_Options* options, size_t i)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
struct string_list* cur = options->include_paths;
|
|
Packit Service |
7770af |
while (i) { i--; cur = cur->next; }
|
|
Packit Service |
7770af |
return cur->string;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Push function for plugin paths (no manipulation support for now)
|
|
Packit Service |
7770af |
void ADDCALL sass_option_push_plugin_path(struct Sass_Options* options, const char* path)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
struct string_list* plugin_path = (struct string_list*) calloc(1, sizeof(struct string_list));
|
|
Packit Service |
7770af |
if (plugin_path == 0) return;
|
|
Packit Service |
7770af |
plugin_path->string = path ? sass_copy_c_string(path) : 0;
|
|
Packit Service |
7770af |
struct string_list* last = options->plugin_paths;
|
|
Packit Service |
7770af |
if (!options->plugin_paths) {
|
|
Packit Service |
7770af |
options->plugin_paths = plugin_path;
|
|
Packit Service |
7770af |
} else {
|
|
Packit Service |
7770af |
while (last->next)
|
|
Packit Service |
7770af |
last = last->next;
|
|
Packit Service |
7770af |
last->next = plugin_path;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|