Skip to content
This repository was archived by the owner on Oct 24, 2025. It is now read-only.

Commit efe46c6

Browse files
committed
Merge pull request #691 from mgreter/feature/importer-parent-context
Improve custom importer to pass parent import context
2 parents 0806d56 + 34a5752 commit efe46c6

File tree

5 files changed

+76
-21
lines changed

5 files changed

+76
-21
lines changed

context.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,20 @@ namespace Sass {
4444
using std::cerr;
4545
using std::endl;
4646

47+
Sass_Queued::Sass_Queued(const string& load_path, const string& abs_path, const char* source)
48+
{
49+
this->load_path = load_path;
50+
this->abs_path = abs_path;
51+
this->source = source;
52+
}
53+
54+
4755
Context::Context(Context::Data initializers)
4856
: mem(Memory_Manager<AST_Node>()),
4957
source_c_str (initializers.source_c_str()),
5058
sources (vector<const char*>()),
5159
include_paths (initializers.include_paths()),
52-
queue (vector<pair<string, const char*> >()),
60+
queue (vector<Sass_Queued>()),
5361
style_sheets (map<string, Block*>()),
5462
source_map (resolve_relative_path(initializers.output_path(), initializers.source_map_file(), get_cwd())),
5563
c_functions (vector<Sass_C_Function_Callback>()),
@@ -96,6 +104,8 @@ namespace Sass {
96104
{
97105
// everything that gets put into sources will be freed by us
98106
for (size_t i = 0; i < sources.size(); ++i) delete[] sources[i];
107+
for (size_t n = 0; n < import_stack.size(); ++n) sass_delete_import(import_stack[n]);
108+
sources.clear(); import_stack.clear();
99109
}
100110

101111
void Context::setup_color_map()
@@ -159,7 +169,7 @@ namespace Sass {
159169
{
160170
sources.push_back(contents);
161171
included_files.push_back(abs_path);
162-
queue.push_back(make_pair(load_path, contents));
172+
queue.push_back(Sass_Queued(load_path, abs_path, contents));
163173
source_map.source_index.push_back(sources.size() - 1);
164174
include_links.push_back(resolve_relative_path(abs_path, source_map_file, cwd));
165175
}
@@ -250,10 +260,18 @@ namespace Sass {
250260
{
251261
Block* root = 0;
252262
for (size_t i = 0; i < queue.size(); ++i) {
253-
Parser p(Parser::from_c_str(queue[i].second, *this, queue[i].first, Position(1 + i, 1, 1)));
263+
struct Sass_Import* import = sass_make_import(
264+
queue[i].load_path.c_str(),
265+
queue[i].abs_path.c_str(),
266+
0, 0
267+
);
268+
import_stack.push_back(import);
269+
Parser p(Parser::from_c_str(queue[i].source, *this, queue[i].load_path, Position(1 + i, 1, 1)));
254270
Block* ast = p.parse();
271+
sass_delete_import(import_stack.back());
272+
import_stack.pop_back();
255273
if (i == 0) root = ast;
256-
style_sheets[queue[i].first] = ast;
274+
style_sheets[queue[i].load_path] = ast;
257275
}
258276
Env tge;
259277
Backtrace backtrace(0, "", Position(), "");

context.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ namespace Sass {
4242

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

45+
struct Sass_Queued {
46+
string abs_path;
47+
string load_path;
48+
const char* source;
49+
public:
50+
Sass_Queued(const string& load_path, const string& abs_path, const char* source);
51+
};
52+
4553
struct Context {
4654
Memory_Manager<AST_Node> mem;
4755

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

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

7684
// overload import calls
7785
Sass_C_Import_Callback importer;
86+
vector<struct Sass_Import*> import_stack;
7887

7988
map<string, Color*> names_to_colors;
8089
map<int, string> colors_to_names;

parser.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "prelexer.hpp"
1313
#endif
1414

15+
#include "sass_functions.h"
16+
1517
#include <typeinfo>
1618

1719
namespace Sass {
@@ -158,36 +160,39 @@ namespace Sass {
158160
Sass_C_Import_Callback importer = ctx.importer;
159161
// custom importer
160162
if (importer) {
163+
Sass_Import* current = ctx.import_stack.back();
161164
Sass_C_Import_Fn fn = sass_import_get_function(importer);
162165
void* cookie = sass_import_get_cookie(importer);
163-
// get null delimited "array" of "external" imports
164-
struct Sass_Import** imports = fn(import_path.c_str(), cookie);
165-
struct Sass_Import** includes = imports;
166+
// create a new import entry
167+
string inc_path = unquote(import_path);
168+
struct Sass_Import** includes = fn(
169+
inc_path.c_str(),
170+
sass_import_get_path(current),
171+
cookie);
166172
if (includes) {
167173
while (*includes) {
168174
struct Sass_Import* include = *includes;
169175
const char *file = sass_import_get_path(include);
170176
char *source = sass_import_take_source(include);
171177
// char *srcmap = sass_import_take_srcmap(include);
172178
if (source) {
173-
string inc_path = unquote(import_path);
174179
if (file) {
175-
ctx.add_source(file, import_path, source);
180+
ctx.add_source(file, inc_path, source);
176181
imp->files().push_back(file);
177182
} else {
178-
ctx.add_source(import_path, import_path, source);
179-
imp->files().push_back(import_path);
183+
ctx.add_source(inc_path, inc_path, source);
184+
imp->files().push_back(inc_path);
180185
}
181186
} else if(file) {
182187
add_single_file(imp, file);
183188
}
184189
++includes;
185190
}
186-
// deallocate returned memory
187-
sass_delete_import_list(imports);
188191
// go for next parse loop
189192
continue;
190193
}
194+
// deallocate returned memory
195+
sass_delete_import_list(includes);
191196
// custom importer returned nothing
192197
// means we should use default loader
193198
}

sass_functions.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ extern "C" {
4343
// External import entry
4444
struct Sass_Import {
4545
char* path;
46+
char* base;
4647
char* source;
4748
char* srcmap;
4849
};
@@ -73,16 +74,23 @@ extern "C" {
7374

7475
// Creator for a single import entry returned by the custom importer inside the list
7576
// We take ownership of the memory for source and srcmap (freed when context is destroyd)
76-
struct Sass_Import* sass_make_import_entry(const char* path, char* source, char* srcmap)
77+
struct Sass_Import* sass_make_import(const char* path, const char* base, char* source, char* srcmap)
7778
{
7879
Sass_Import* v = (Sass_Import*) calloc(1, sizeof(Sass_Import));
7980
if (v == 0) return 0;
8081
v->path = strdup(path);
82+
v->base = strdup(base);
8183
v->source = source;
8284
v->srcmap = srcmap;
8385
return v;
8486
}
8587

88+
// Older style, but somehow still valid - keep around or deprecate?
89+
struct Sass_Import* sass_make_import_entry(const char* path, char* source, char* srcmap)
90+
{
91+
return sass_make_import(path, path, source, srcmap);
92+
}
93+
8694
// Setters and getters for entries on the import list
8795
void sass_import_set_list_entry(struct Sass_Import** list, size_t idx, struct Sass_Import* entry) { list[idx] = entry; }
8896
struct Sass_Import* sass_import_get_list_entry(struct Sass_Import** list, size_t idx) { return list[idx]; }
@@ -93,17 +101,25 @@ extern "C" {
93101
struct Sass_Import** it = list;
94102
if (list == 0) return;
95103
while(*list) {
96-
free((*list)->path);
97-
free((*list)->source);
98-
free((*list)->srcmap);
99-
free(*list);
104+
sass_delete_import(*list);
100105
++list;
101106
}
102107
free(it);
103108
}
104109

110+
// Just in case we have some stray import structs
111+
void sass_delete_import(struct Sass_Import* import)
112+
{
113+
free(import->path);
114+
free(import->base);
115+
free(import->source);
116+
free(import->srcmap);
117+
free(import);
118+
}
119+
105120
// Getter for import entry
106121
const char* sass_import_get_path(struct Sass_Import* entry) { return entry->path; }
122+
const char* sass_import_get_base(struct Sass_Import* entry) { return entry->base; }
107123
const char* sass_import_get_source(struct Sass_Import* entry) { return entry->source; }
108124
const char* sass_import_get_srcmap(struct Sass_Import* entry) { return entry->srcmap; }
109125

sass_functions.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ extern "C" {
99
#endif
1010

1111

12+
// Forward declaration
13+
struct Sass_Import;
14+
1215
// Forward declaration
1316
struct Sass_C_Import_Descriptor;
1417

1518
// Typedef defining the custom importer callback
1619
typedef struct Sass_C_Import_Descriptor (*Sass_C_Import_Callback);
1720
// Typedef defining the importer c function prototype
18-
typedef struct Sass_Import** (*Sass_C_Import_Fn) (const char* url, void* cookie);
21+
typedef struct Sass_Import** (*Sass_C_Import_Fn) (const char* url, const char* prev, void* cookie);
1922

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

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

3943
// Getters for import entry
4044
const char* sass_import_get_path (struct Sass_Import*);
45+
const char* sass_import_get_base (struct Sass_Import*);
4146
const char* sass_import_get_source (struct Sass_Import*);
4247
const char* sass_import_get_srcmap (struct Sass_Import*);
4348
// Explicit functions to take ownership of these items
@@ -47,6 +52,8 @@ char* sass_import_take_srcmap (struct Sass_Import*);
4752

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

5158

5259
// Forward declaration
@@ -56,7 +63,7 @@ struct Sass_C_Function_Descriptor;
5663
typedef struct Sass_C_Function_Descriptor* (*Sass_C_Function_List);
5764
typedef struct Sass_C_Function_Descriptor (*Sass_C_Function_Callback);
5865
// Typedef defining custom function prototype and its return value type
59-
typedef union Sass_Value*(*Sass_C_Function) (union Sass_Value*, void *cookie);
66+
typedef union Sass_Value*(*Sass_C_Function) (union Sass_Value*, void* cookie);
6067

6168

6269
// Creators for sass function list and function descriptors

0 commit comments

Comments
 (0)