Skip to content

Commit

Permalink
Merge pull request #691 from mgreter/feature/importer-parent-context
Browse files Browse the repository at this point in the history
Improve custom importer to pass parent import context
  • Loading branch information
mgreter committed Dec 13, 2014
2 parents 0806d56 + 34a5752 commit efe46c6
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 21 deletions.
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 @@ -159,7 +169,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 @@ -250,10 +260,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

0 comments on commit efe46c6

Please sign in to comment.