Skip to content

Commit ae273d6

Browse files
committed
Refactor custom function/importer signatures
Pass `Sass_Option` pointer to custom functions. Allows implementer to access the context options.
1 parent 4a522c3 commit ae273d6

17 files changed

+269
-191
lines changed

ast.hpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -644,24 +644,27 @@ namespace Sass {
644644
ADD_PROPERTY(Env*, environment);
645645
ADD_PROPERTY(Type, type);
646646
ADD_PROPERTY(Native_Function, native_function);
647-
ADD_PROPERTY(Sass_C_Function, c_function);
647+
ADD_PROPERTY(Sass_Function_Entry, c_cb);
648648
ADD_PROPERTY(void*, cookie);
649+
ADD_PROPERTY(Context*, ctx);
649650
ADD_PROPERTY(bool, is_overload_stub);
650651
ADD_PROPERTY(Signature, signature);
651652
public:
652653
Definition(ParserState pstate,
653654
string n,
654655
Parameters* params,
655656
Block* b,
657+
Context* ctx,
656658
Type t)
657659
: Has_Block(pstate, b),
658660
name_(n),
659661
parameters_(params),
660662
environment_(0),
661663
type_(t),
662664
native_function_(0),
663-
c_function_(0),
665+
c_cb_(0),
664666
cookie_(0),
667+
ctx_(ctx),
665668
is_overload_stub_(false),
666669
signature_(0)
667670
{ }
@@ -670,24 +673,26 @@ namespace Sass {
670673
string n,
671674
Parameters* params,
672675
Native_Function func_ptr,
676+
Context* ctx,
673677
bool overload_stub = false)
674678
: Has_Block(pstate, 0),
675679
name_(n),
676680
parameters_(params),
677681
environment_(0),
678682
type_(FUNCTION),
679683
native_function_(func_ptr),
680-
c_function_(0),
684+
c_cb_(0),
681685
cookie_(0),
686+
ctx_(ctx),
682687
is_overload_stub_(overload_stub),
683688
signature_(sig)
684689
{ }
685690
Definition(ParserState pstate,
686691
Signature sig,
687692
string n,
688693
Parameters* params,
689-
Sass_C_Function func_ptr,
690-
void* cookie,
694+
Sass_Function_Entry c_func,
695+
Context* ctx,
691696
bool whatever,
692697
bool whatever2)
693698
: Has_Block(pstate, 0),
@@ -696,8 +701,9 @@ namespace Sass {
696701
environment_(0),
697702
type_(FUNCTION),
698703
native_function_(0),
699-
c_function_(func_ptr),
700-
cookie_(cookie),
704+
c_cb_(c_func),
705+
cookie_(sass_function_get_cookie(c_func)),
706+
ctx_(ctx),
701707
is_overload_stub_(false),
702708
signature_(sig)
703709
{ }

context.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,23 @@ namespace Sass {
5050
this->source = source;
5151
}
5252

53-
inline bool sort_importers (const Sass_C_Importer_Call& i, const Sass_C_Importer_Call& j)
53+
inline bool sort_importers (const Sass_Importer_Entry& i, const Sass_Importer_Entry& j)
5454
{ return sass_importer_get_priority(i) < sass_importer_get_priority(j); }
5555

5656
Context::Context(Context::Data initializers)
5757
: // Output(this),
5858
mem(Memory_Manager<AST_Node>()),
59+
c_options (initializers.c_options()),
60+
c_compiler (initializers.c_compiler()),
5961
source_c_str (initializers.source_c_str()),
6062
sources (vector<const char*>()),
6163
plugin_paths (initializers.plugin_paths()),
6264
include_paths (initializers.include_paths()),
6365
queue (vector<Sass_Queued>()),
6466
style_sheets (map<string, Block*>()),
6567
emitter (this),
66-
c_functions (vector<Sass_C_Function_Call>()),
67-
c_importers (vector<Sass_C_Importer_Call>()),
68+
c_functions (vector<Sass_Function_Entry>()),
69+
c_importers (vector<Sass_Importer_Entry>()),
6870
indent (initializers.indent()),
6971
linefeed (initializers.linefeed()),
7072
input_path (make_canonical_path(initializers.input_path())),
@@ -123,11 +125,11 @@ namespace Sass {
123125

124126
}
125127

126-
void Context::add_c_function(Sass_C_Function_Call function)
128+
void Context::add_c_function(Sass_Function_Entry function)
127129
{
128130
c_functions.push_back(function);
129131
}
130-
void Context::add_c_importer(Sass_C_Importer_Call importer)
132+
void Context::add_c_importer(Sass_Importer_Entry importer)
131133
{
132134
c_importers.push_back(importer);
133135
// need to sort the array afterwards (no big deal)
@@ -279,8 +281,8 @@ namespace Sass {
279281
void register_function(Context&, Signature sig, Native_Function f, size_t arity, Env* env);
280282
void register_overload_stub(Context&, string name, Env* env);
281283
void register_built_in_functions(Context&, Env* env);
282-
void register_c_functions(Context&, Env* env, Sass_C_Function_List);
283-
void register_c_function(Context&, Env* env, Sass_C_Function_Call);
284+
void register_c_functions(Context&, Env* env, Sass_Function_List);
285+
void register_c_function(Context&, Env* env, Sass_Function_Entry);
284286

285287
char* Context::compile_block(Block* root)
286288
{
@@ -299,7 +301,7 @@ namespace Sass {
299301
{
300302
Block* root = 0;
301303
for (size_t i = 0; i < queue.size(); ++i) {
302-
struct Sass_Import* import = sass_make_import(
304+
Sass_Import_Entry import = sass_make_import(
303305
queue[i].load_path.c_str(),
304306
queue[i].abs_path.c_str(),
305307
0, 0
@@ -427,6 +429,7 @@ namespace Sass {
427429
name,
428430
0,
429431
0,
432+
&ctx,
430433
true);
431434
(*env)[name + "[f]"] = stub;
432435
}
@@ -525,21 +528,16 @@ namespace Sass {
525528
register_function(ctx, unique_id_sig, unique_id, env);
526529
}
527530

528-
void register_c_functions(Context& ctx, Env* env, Sass_C_Function_List descrs)
531+
void register_c_functions(Context& ctx, Env* env, Sass_Function_List descrs)
529532
{
530533
while (descrs && *descrs) {
531534
register_c_function(ctx, env, *descrs);
532535
++descrs;
533536
}
534537
}
535-
void register_c_function(Context& ctx, Env* env, Sass_C_Function_Call descr)
538+
void register_c_function(Context& ctx, Env* env, Sass_Function_Entry descr)
536539
{
537-
Definition* def = make_c_function(
538-
sass_function_get_signature(descr),
539-
sass_function_get_function(descr),
540-
sass_function_get_cookie(descr),
541-
ctx
542-
);
540+
Definition* def = make_c_function(descr, ctx);
543541
def->environment(env);
544542
(*env)[def->name() + "[f]"] = def;
545543
}

context.hpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include "plugins.hpp"
1919
#include "sass_functions.h"
2020

21-
struct Sass_C_Function_Descriptor;
21+
struct Sass_Function;
2222

2323
namespace Sass {
2424
using namespace std;
@@ -34,6 +34,8 @@ namespace Sass {
3434
public:
3535
Memory_Manager<AST_Node> mem;
3636

37+
struct Sass_Options* c_options;
38+
struct Sass_Compiler* c_compiler;
3739
const char* source_c_str;
3840

3941
// c-strs containing Sass file contents
@@ -52,11 +54,11 @@ namespace Sass {
5254
// SourceMap source_map;
5355
Output emitter;
5456

55-
vector<Sass_C_Function_Call> c_functions;
56-
vector<Sass_C_Importer_Call> c_importers;
57+
vector<Sass_Function_Entry> c_functions;
58+
vector<Sass_Importer_Entry> c_importers;
5759

58-
void add_c_function(Sass_C_Function_Call function);
59-
void add_c_importer(Sass_C_Importer_Call importer);
60+
void add_c_function(Sass_Function_Entry function);
61+
void add_c_importer(Sass_Importer_Entry importer);
6062

6163
string indent; // String to be used for indentation
6264
string linefeed; // String to be used for line feeds
@@ -72,14 +74,16 @@ namespace Sass {
7274
bool is_indented_syntax_src; // treat source string as sass
7375

7476
// overload import calls
75-
vector<struct Sass_Import*> import_stack;
77+
vector<Sass_Import_Entry> import_stack;
7678

7779
map<string, Color*> names_to_colors;
7880
map<int, string> colors_to_names;
7981

8082
size_t precision; // precision for outputting fractional numbers
8183

8284
KWD_ARG_SET(Data) {
85+
KWD_ARG(Data, struct Sass_Options*, c_options);
86+
KWD_ARG(Data, struct Sass_Compiler*, c_compiler);
8387
KWD_ARG(Data, const char*, source_c_str);
8488
KWD_ARG(Data, string, entry_point);
8589
KWD_ARG(Data, string, input_path);

contrib/plugin.cpp

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,52 @@
66
// gcc: g++ -shared plugin.cpp -o plugin.so -fPIC -Llib -lsass
77
// mingw: g++ -shared plugin.cpp -o plugin.dll -Llib -lsass
88

9-
union Sass_Value* call_fn_foo(const union Sass_Value* s_args, void* cookie)
9+
extern "C" const char* ADDCALL libsass_get_version() {
10+
return libsass_version();
11+
}
12+
13+
union Sass_Value* custom_function(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Options* opts)
1014
{
15+
// get the cookie from function descriptor
16+
void* cookie = sass_function_get_cookie(cb);
1117
// we actually abuse the void* to store an "int"
1218
return sass_make_number((intptr_t)cookie, "px");
1319
}
1420

15-
extern "C" const char* ADDCALL libsass_get_version() {
16-
return libsass_version();
21+
extern "C" Sass_Function_List ADDCALL libsass_load_functions()
22+
{
23+
// allocate a custom function caller
24+
Sass_Function_Entry c_func =
25+
sass_make_function("foo()", custom_function, (void*)42);
26+
// create list of all custom functions
27+
Sass_Function_List fn_list = sass_make_function_list(1);
28+
// put the only function in this plugin to the list
29+
sass_function_set_list_entry(fn_list, 0, c_func);
30+
// return the list
31+
return fn_list;
1732
}
1833

19-
extern "C" Sass_C_Function_List ADDCALL libsass_load_functions()
34+
Sass_Import_List custom_importer(const char* cur_path, Sass_Importer_Entry cb, struct Sass_Compiler* comp)
35+
{
36+
// get the cookie from importer descriptor
37+
void* cookie = sass_importer_get_cookie(cb);
38+
// create a list to hold our import entries
39+
Sass_Import_List incs = sass_make_import_list(1);
40+
// create our only import entry (route path back)
41+
incs[0] = sass_make_import_entry(cur_path, 0, 0);
42+
// return imports
43+
return incs;
44+
}
45+
46+
extern "C" Sass_Importer_List ADDCALL libsass_load_importers()
2047
{
2148
// allocate a custom function caller
22-
Sass_C_Function_Call fn_foo =
23-
sass_make_function("foo()", call_fn_foo, (void*)42);
49+
Sass_Importer_Entry c_imp =
50+
sass_make_importer(custom_importer, - 99, (void*)42);
2451
// create list of all custom functions
25-
Sass_C_Function_List fn_list = sass_make_function_list(1);
52+
Sass_Importer_List imp_list = sass_make_importer_list(1);
2653
// put the only function in this plugin to the list
27-
sass_function_set_list_entry(fn_list, 0, fn_foo);
54+
sass_importer_set_list_entry(imp_list, 0, c_imp);
2855
// return the list
29-
return fn_list;
56+
return imp_list;
3057
}

eval.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,13 @@ namespace Sass {
256256
Definition* def = static_cast<Definition*>((*env)["@warn[f]"]);
257257
// Block* body = def->block();
258258
// Native_Function func = def->native_function();
259-
Sass_C_Function c_func = def->c_function();
259+
Sass_Function_Entry c_cb = def->c_cb();
260+
Sass_Function_Fn c_func = sass_function_get_function(c_cb);
260261

261262
To_C to_c;
262263
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA);
263264
sass_list_set_value(c_args, 0, message->perform(&to_c));
264-
Sass_Value* c_val = c_func(c_args, def->cookie());
265+
Sass_Value* c_val = c_func(c_args, c_cb, ctx.c_options);
265266
sass_delete_value(c_args);
266267
sass_delete_value(c_val);
267268
return 0;
@@ -287,12 +288,13 @@ namespace Sass {
287288
Definition* def = static_cast<Definition*>((*env)["@error[f]"]);
288289
// Block* body = def->block();
289290
// Native_Function func = def->native_function();
290-
Sass_C_Function c_func = def->c_function();
291+
Sass_Function_Entry c_cb = def->c_cb();
292+
Sass_Function_Fn c_func = sass_function_get_function(c_cb);
291293

292294
To_C to_c;
293295
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA);
294296
sass_list_set_value(c_args, 0, message->perform(&to_c));
295-
Sass_Value* c_val = c_func(c_args, def->cookie());
297+
Sass_Value* c_val = c_func(c_args, c_cb, ctx.c_options);
296298
sass_delete_value(c_args);
297299
sass_delete_value(c_val);
298300
return 0;
@@ -315,12 +317,13 @@ namespace Sass {
315317
Definition* def = static_cast<Definition*>((*env)["@debug[f]"]);
316318
// Block* body = def->block();
317319
// Native_Function func = def->native_function();
318-
Sass_C_Function c_func = def->c_function();
320+
Sass_Function_Entry c_cb = def->c_cb();
321+
Sass_Function_Fn c_func = sass_function_get_function(c_cb);
319322

320323
To_C to_c;
321324
union Sass_Value* c_args = sass_make_list(1, SASS_COMMA);
322325
sass_list_set_value(c_args, 0, message->perform(&to_c));
323-
Sass_Value* c_val = c_func(c_args, def->cookie());
326+
Sass_Value* c_val = c_func(c_args, c_cb, ctx.c_options);
324327
sass_delete_value(c_args);
325328
sass_delete_value(c_val);
326329
return 0;
@@ -500,7 +503,7 @@ namespace Sass {
500503
Definition* def = static_cast<Definition*>((*env)[full_name]);
501504
Block* body = def->block();
502505
Native_Function func = def->native_function();
503-
Sass_C_Function c_func = def->c_function();
506+
Sass_Function_Entry c_cb = def->c_cb();
504507

505508
if (full_name != "if[f]") {
506509
for (size_t i = 0, L = args->length(); i < L; ++i) {
@@ -551,8 +554,9 @@ namespace Sass {
551554
env = old_env;
552555
}
553556
// else if it's a user-defined c function
554-
else if (c_func) {
557+
else if (c_cb) {
555558

559+
Sass_Function_Fn c_func = sass_function_get_function(c_cb);
556560
if (full_name == "*[f]") {
557561
String_Constant *str = new (ctx.mem) String_Constant(c->pstate(), c->name());
558562
Arguments* new_args = new (ctx.mem) Arguments(c->pstate());
@@ -577,7 +581,7 @@ namespace Sass {
577581
Expression* arg = static_cast<Expression*>(node);
578582
sass_list_set_value(c_args, i, arg->perform(&to_c));
579583
}
580-
Sass_Value* c_val = c_func(c_args, def->cookie());
584+
Sass_Value* c_val = c_func(c_args, c_cb, ctx.c_options);
581585
if (sass_value_get_tag(c_val) == SASS_ERROR) {
582586
error("error in C function " + c->name() + ": " + sass_error_get_message(c_val), c->pstate(), backtrace);
583587
} else if (sass_value_get_tag(c_val) == SASS_WARNING) {

expand.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ namespace Sass {
497497
"@content",
498498
new (ctx.mem) Parameters(c->pstate()),
499499
c->block(),
500+
&ctx,
500501
Definition::MIXIN);
501502
thunk->environment(env);
502503
new_env.local_frame()["@content[m]"] = thunk;

0 commit comments

Comments
 (0)