Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve custom importer to pass parent import context #691

Merged
merged 1 commit into from
Dec 13, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,20 @@ namespace Sass {
using std::cerr;
using std::endl;

Sass_Queued::Sass_Queued(const string& load_path, const string& abs_path, const char* source)
{
this->load_path = load_path;
this->abs_path = abs_path;
this->source = source;
}


Context::Context(Context::Data initializers)
: mem(Memory_Manager<AST_Node>()),
source_c_str (initializers.source_c_str()),
sources (vector<const char*>()),
include_paths (initializers.include_paths()),
queue (vector<pair<string, const char*> >()),
queue (vector<Sass_Queued>()),
style_sheets (map<string, Block*>()),
source_map (resolve_relative_path(initializers.output_path(), initializers.source_map_file(), get_cwd())),
c_functions (vector<Sass_C_Function_Callback>()),
Expand Down Expand Up @@ -96,6 +104,8 @@ namespace Sass {
{
// everything that gets put into sources will be freed by us
for (size_t i = 0; i < sources.size(); ++i) delete[] sources[i];
for (size_t n = 0; n < import_stack.size(); ++n) sass_delete_import(import_stack[n]);
sources.clear(); import_stack.clear();
}

void Context::setup_color_map()
Expand Down Expand Up @@ -155,7 +165,7 @@ namespace Sass {
{
sources.push_back(contents);
included_files.push_back(abs_path);
queue.push_back(make_pair(load_path, contents));
queue.push_back(Sass_Queued(load_path, abs_path, contents));
source_map.source_index.push_back(sources.size() - 1);
include_links.push_back(resolve_relative_path(abs_path, source_map_file, cwd));
}
Expand Down Expand Up @@ -246,10 +256,18 @@ namespace Sass {
{
Block* root = 0;
for (size_t i = 0; i < queue.size(); ++i) {
Parser p(Parser::from_c_str(queue[i].second, *this, queue[i].first, Position(1 + i, 1, 1)));
struct Sass_Import* import = sass_make_import(
queue[i].load_path.c_str(),
queue[i].abs_path.c_str(),
0, 0
);
import_stack.push_back(import);
Parser p(Parser::from_c_str(queue[i].source, *this, queue[i].load_path, Position(1 + i, 1, 1)));
Block* ast = p.parse();
sass_delete_import(import_stack.back());
import_stack.pop_back();
if (i == 0) root = ast;
style_sheets[queue[i].first] = ast;
style_sheets[queue[i].load_path] = ast;
}
Env tge;
Backtrace backtrace(0, "", Position(), "");
Expand Down
11 changes: 10 additions & 1 deletion context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ namespace Sass {

enum Output_Style { NESTED, EXPANDED, COMPACT, COMPRESSED, FORMATTED };

struct Sass_Queued {
string abs_path;
string load_path;
const char* source;
public:
Sass_Queued(const string& load_path, const string& abs_path, const char* source);
};

struct Context {
Memory_Manager<AST_Node> mem;

Expand All @@ -57,7 +65,7 @@ namespace Sass {
// vectors above have same size

vector<string> include_paths; // lookup paths for includes
vector<pair<string, const char*> > queue; // queue of files to be parsed
vector<Sass_Queued> queue; // queue of files to be parsed
map<string, Block*> style_sheets; // map of paths to ASTs
SourceMap source_map;
vector<Sass_C_Function_Callback> c_functions;
Expand All @@ -75,6 +83,7 @@ namespace Sass {

// overload import calls
Sass_C_Import_Callback importer;
vector<struct Sass_Import*> import_stack;

map<string, Color*> names_to_colors;
map<int, string> colors_to_names;
Expand Down
23 changes: 14 additions & 9 deletions parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "prelexer.hpp"
#endif

#include "sass_functions.h"

#include <typeinfo>

namespace Sass {
Expand Down Expand Up @@ -158,36 +160,39 @@ namespace Sass {
Sass_C_Import_Callback importer = ctx.importer;
// custom importer
if (importer) {
Sass_Import* current = ctx.import_stack.back();
Sass_C_Import_Fn fn = sass_import_get_function(importer);
void* cookie = sass_import_get_cookie(importer);
// get null delimited "array" of "external" imports
struct Sass_Import** imports = fn(import_path.c_str(), cookie);
struct Sass_Import** includes = imports;
// create a new import entry
string inc_path = unquote(import_path);
struct Sass_Import** includes = fn(
inc_path.c_str(),
sass_import_get_path(current),
cookie);
if (includes) {
while (*includes) {
struct Sass_Import* include = *includes;
const char *file = sass_import_get_path(include);
char *source = sass_import_take_source(include);
// char *srcmap = sass_import_take_srcmap(include);
if (source) {
string inc_path = unquote(import_path);
if (file) {
ctx.add_source(file, import_path, source);
ctx.add_source(file, inc_path, source);
imp->files().push_back(file);
} else {
ctx.add_source(import_path, import_path, source);
imp->files().push_back(import_path);
ctx.add_source(inc_path, inc_path, source);
imp->files().push_back(inc_path);
}
} else if(file) {
add_single_file(imp, file);
}
++includes;
}
// deallocate returned memory
sass_delete_import_list(imports);
// go for next parse loop
continue;
}
// deallocate returned memory
sass_delete_import_list(includes);
// custom importer returned nothing
// means we should use default loader
}
Expand Down
26 changes: 21 additions & 5 deletions sass_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ extern "C" {
// External import entry
struct Sass_Import {
char* path;
char* base;
char* source;
char* srcmap;
};
Expand Down Expand Up @@ -73,16 +74,23 @@ extern "C" {

// Creator for a single import entry returned by the custom importer inside the list
// We take ownership of the memory for source and srcmap (freed when context is destroyd)
struct Sass_Import* sass_make_import_entry(const char* path, char* source, char* srcmap)
struct Sass_Import* sass_make_import(const char* path, const char* base, char* source, char* srcmap)
{
Sass_Import* v = (Sass_Import*) calloc(1, sizeof(Sass_Import));
if (v == 0) return 0;
v->path = strdup(path);
v->base = strdup(base);
v->source = source;
v->srcmap = srcmap;
return v;
}

// Older style, but somehow still valid - keep around or deprecate?
struct Sass_Import* sass_make_import_entry(const char* path, char* source, char* srcmap)
{
return sass_make_import(path, path, source, srcmap);
}

// Setters and getters for entries on the import list
void sass_import_set_list_entry(struct Sass_Import** list, size_t idx, struct Sass_Import* entry) { list[idx] = entry; }
struct Sass_Import* sass_import_get_list_entry(struct Sass_Import** list, size_t idx) { return list[idx]; }
Expand All @@ -93,17 +101,25 @@ extern "C" {
struct Sass_Import** it = list;
if (list == 0) return;
while(*list) {
free((*list)->path);
free((*list)->source);
free((*list)->srcmap);
free(*list);
sass_delete_import(*list);
++list;
}
free(it);
}

// Just in case we have some stray import structs
void sass_delete_import(struct Sass_Import* import)
{
free(import->path);
free(import->base);
free(import->source);
free(import->srcmap);
free(import);
}

// Getter for import entry
const char* sass_import_get_path(struct Sass_Import* entry) { return entry->path; }
const char* sass_import_get_base(struct Sass_Import* entry) { return entry->base; }
const char* sass_import_get_source(struct Sass_Import* entry) { return entry->source; }
const char* sass_import_get_srcmap(struct Sass_Import* entry) { return entry->srcmap; }

Expand Down
11 changes: 9 additions & 2 deletions sass_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ extern "C" {
#endif


// Forward declaration
struct Sass_Import;

// Forward declaration
struct Sass_C_Import_Descriptor;

// Typedef defining the custom importer callback
typedef struct Sass_C_Import_Descriptor (*Sass_C_Import_Callback);
// Typedef defining the importer c function prototype
typedef struct Sass_Import** (*Sass_C_Import_Fn) (const char* url, void* cookie);
typedef struct Sass_Import** (*Sass_C_Import_Fn) (const char* url, const char* prev, void* cookie);

// Creators for custom importer callback (with some additional pointer)
// The pointer is mostly used to store the callback into the actual binding
Expand All @@ -30,6 +33,7 @@ void* sass_import_get_cookie (Sass_C_Import_Callback fn);
struct Sass_Import** sass_make_import_list (size_t length);
// Creator for a single import entry returned by the custom importer inside the list
struct Sass_Import* sass_make_import_entry (const char* path, char* source, char* srcmap);
struct Sass_Import* sass_make_import (const char* path, const char* base, char* source, char* srcmap);

// Setters to insert an entry into the import list (you may also use [] access directly)
// Since we are dealing with pointers they should have a guaranteed and fixed size
Expand All @@ -38,6 +42,7 @@ struct Sass_Import* sass_import_get_list_entry (struct Sass_Import** list, size_

// Getters for import entry
const char* sass_import_get_path (struct Sass_Import*);
const char* sass_import_get_base (struct Sass_Import*);
const char* sass_import_get_source (struct Sass_Import*);
const char* sass_import_get_srcmap (struct Sass_Import*);
// Explicit functions to take ownership of these items
Expand All @@ -47,6 +52,8 @@ char* sass_import_take_srcmap (struct Sass_Import*);

// Deallocator for associated memory (incl. entries)
void sass_delete_import_list (struct Sass_Import**);
// Just in case we have some stray import structs
void sass_delete_import (struct Sass_Import*);


// Forward declaration
Expand All @@ -56,7 +63,7 @@ struct Sass_C_Function_Descriptor;
typedef struct Sass_C_Function_Descriptor* (*Sass_C_Function_List);
typedef struct Sass_C_Function_Descriptor (*Sass_C_Function_Callback);
// Typedef defining custom function prototype and its return value type
typedef union Sass_Value*(*Sass_C_Function) (union Sass_Value*, void *cookie);
typedef union Sass_Value*(*Sass_C_Function) (union Sass_Value*, void* cookie);


// Creators for sass function list and function descriptors
Expand Down