1 | // sass.hpp must go before all system headers to get the |
2 | // __EXTENSIONS__ fix on Solaris. |
3 | #include "sass.hpp" |
4 | |
5 | #include <cstring> |
6 | #include "util.hpp" |
7 | #include "context.hpp" |
8 | #include "values.hpp" |
9 | #include "sass/functions.h" |
10 | #include "sass_functions.hpp" |
11 | |
12 | extern "C" { |
13 | using namespace Sass; |
14 | |
15 | Sass_Function_List ADDCALL sass_make_function_list(size_t length) |
16 | { |
17 | return (Sass_Function_List) calloc(nmemb: length + 1, size: sizeof(Sass_Function_Entry)); |
18 | } |
19 | |
20 | Sass_Function_Entry ADDCALL sass_make_function(const char* signature, Sass_Function_Fn function, void* cookie) |
21 | { |
22 | Sass_Function_Entry cb = (Sass_Function_Entry) calloc(nmemb: 1, size: sizeof(Sass_Function)); |
23 | if (cb == 0) return 0; |
24 | cb->signature = sass_copy_c_string(str: signature); |
25 | cb->function = function; |
26 | cb->cookie = cookie; |
27 | return cb; |
28 | } |
29 | |
30 | void ADDCALL sass_delete_function(Sass_Function_Entry entry) |
31 | { |
32 | free(ptr: entry->signature); |
33 | free(ptr: entry); |
34 | } |
35 | |
36 | // Deallocator for the allocated memory |
37 | void ADDCALL sass_delete_function_list(Sass_Function_List list) |
38 | { |
39 | Sass_Function_List it = list; |
40 | if (list == 0) return; |
41 | while(*list) { |
42 | sass_delete_function(entry: *list); |
43 | ++list; |
44 | } |
45 | free(ptr: it); |
46 | } |
47 | |
48 | // Setters and getters for callbacks on function lists |
49 | Sass_Function_Entry ADDCALL sass_function_get_list_entry(Sass_Function_List list, size_t pos) { return list[pos]; } |
50 | void sass_function_set_list_entry(Sass_Function_List list, size_t pos, Sass_Function_Entry cb) { list[pos] = cb; } |
51 | |
52 | const char* ADDCALL sass_function_get_signature(Sass_Function_Entry cb) { return cb->signature; } |
53 | Sass_Function_Fn ADDCALL sass_function_get_function(Sass_Function_Entry cb) { return cb->function; } |
54 | void* ADDCALL sass_function_get_cookie(Sass_Function_Entry cb) { return cb->cookie; } |
55 | |
56 | Sass_Importer_Entry ADDCALL sass_make_importer(Sass_Importer_Fn importer, double priority, void* cookie) |
57 | { |
58 | Sass_Importer_Entry cb = (Sass_Importer_Entry) calloc(nmemb: 1, size: sizeof(Sass_Importer)); |
59 | if (cb == 0) return 0; |
60 | cb->importer = importer; |
61 | cb->priority = priority; |
62 | cb->cookie = cookie; |
63 | return cb; |
64 | } |
65 | |
66 | Sass_Importer_Fn ADDCALL sass_importer_get_function(Sass_Importer_Entry cb) { return cb->importer; } |
67 | double ADDCALL sass_importer_get_priority (Sass_Importer_Entry cb) { return cb->priority; } |
68 | void* ADDCALL sass_importer_get_cookie(Sass_Importer_Entry cb) { return cb->cookie; } |
69 | |
70 | // Just in case we have some stray import structs |
71 | void ADDCALL sass_delete_importer (Sass_Importer_Entry cb) |
72 | { |
73 | free(ptr: cb); |
74 | } |
75 | |
76 | // Creator for sass custom importer function list |
77 | Sass_Importer_List ADDCALL sass_make_importer_list(size_t length) |
78 | { |
79 | return (Sass_Importer_List) calloc(nmemb: length + 1, size: sizeof(Sass_Importer_Entry)); |
80 | } |
81 | |
82 | // Deallocator for the allocated memory |
83 | void ADDCALL sass_delete_importer_list(Sass_Importer_List list) |
84 | { |
85 | Sass_Importer_List it = list; |
86 | if (list == 0) return; |
87 | while(*list) { |
88 | sass_delete_importer(cb: *list); |
89 | ++list; |
90 | } |
91 | free(ptr: it); |
92 | } |
93 | |
94 | Sass_Importer_Entry ADDCALL sass_importer_get_list_entry(Sass_Importer_List list, size_t idx) { return list[idx]; } |
95 | void ADDCALL sass_importer_set_list_entry(Sass_Importer_List list, size_t idx, Sass_Importer_Entry cb) { list[idx] = cb; } |
96 | |
97 | // Creator for sass custom importer return argument list |
98 | Sass_Import_List ADDCALL sass_make_import_list(size_t length) |
99 | { |
100 | return (Sass_Import**) calloc(nmemb: length + 1, size: sizeof(Sass_Import*)); |
101 | } |
102 | |
103 | // Creator for a single import entry returned by the custom importer inside the list |
104 | // We take ownership of the memory for source and srcmap (freed when context is destroyed) |
105 | Sass_Import_Entry ADDCALL sass_make_import(const char* imp_path, const char* abs_path, char* source, char* srcmap) |
106 | { |
107 | Sass_Import* v = (Sass_Import*) calloc(nmemb: 1, size: sizeof(Sass_Import)); |
108 | if (v == 0) return 0; |
109 | v->imp_path = imp_path ? sass_copy_c_string(str: imp_path) : 0; |
110 | v->abs_path = abs_path ? sass_copy_c_string(str: abs_path) : 0; |
111 | v->source = source; |
112 | v->srcmap = srcmap; |
113 | v->error = 0; |
114 | v->line = -1; |
115 | v->column = -1; |
116 | return v; |
117 | } |
118 | |
119 | // Older style, but somehow still valid - keep around or deprecate? |
120 | Sass_Import_Entry ADDCALL sass_make_import_entry(const char* path, char* source, char* srcmap) |
121 | { |
122 | return sass_make_import(imp_path: path, abs_path: path, source, srcmap); |
123 | } |
124 | |
125 | // Upgrade a normal import entry to throw an error (original path can be re-used by error reporting) |
126 | Sass_Import_Entry ADDCALL sass_import_set_error(Sass_Import_Entry import, const char* error, size_t line, size_t col) |
127 | { |
128 | if (import == 0) return 0; |
129 | if (import->error) free(ptr: import->error); |
130 | import->error = error ? sass_copy_c_string(str: error) : 0; |
131 | import->line = line ? line : -1; |
132 | import->column = col ? col : -1; |
133 | return import; |
134 | } |
135 | |
136 | // Setters and getters for entries on the import list |
137 | void ADDCALL sass_import_set_list_entry(Sass_Import_List list, size_t idx, Sass_Import_Entry entry) { list[idx] = entry; } |
138 | Sass_Import_Entry ADDCALL sass_import_get_list_entry(Sass_Import_List list, size_t idx) { return list[idx]; } |
139 | |
140 | // Deallocator for the allocated memory |
141 | void ADDCALL sass_delete_import_list(Sass_Import_List list) |
142 | { |
143 | Sass_Import_List it = list; |
144 | if (list == 0) return; |
145 | while(*list) { |
146 | sass_delete_import(*list); |
147 | ++list; |
148 | } |
149 | free(ptr: it); |
150 | } |
151 | |
152 | // Just in case we have some stray import structs |
153 | void ADDCALL sass_delete_import(Sass_Import_Entry import) |
154 | { |
155 | free(ptr: import->imp_path); |
156 | free(ptr: import->abs_path); |
157 | free(ptr: import->source); |
158 | free(ptr: import->srcmap); |
159 | free(ptr: import->error); |
160 | free(ptr: import); |
161 | } |
162 | |
163 | // Getter for callee entry |
164 | const char* ADDCALL sass_callee_get_name(Sass_Callee_Entry entry) { return entry->name; } |
165 | const char* ADDCALL sass_callee_get_path(Sass_Callee_Entry entry) { return entry->path; } |
166 | size_t ADDCALL sass_callee_get_line(Sass_Callee_Entry entry) { return entry->line; } |
167 | size_t ADDCALL sass_callee_get_column(Sass_Callee_Entry entry) { return entry->column; } |
168 | enum Sass_Callee_Type ADDCALL sass_callee_get_type(Sass_Callee_Entry entry) { return entry->type; } |
169 | Sass_Env_Frame ADDCALL sass_callee_get_env (Sass_Callee_Entry entry) { return &entry->env; } |
170 | |
171 | // Getters and Setters for environments (lexical, local and global) |
172 | union Sass_Value* ADDCALL sass_env_get_lexical (Sass_Env_Frame env, const char* name) { |
173 | Expression* ex = Cast<Expression>(ptr: (*env->frame)[name]); |
174 | return ex != NULL ? ast_node_to_sass_value(val: ex) : NULL; |
175 | } |
176 | void ADDCALL sass_env_set_lexical (Sass_Env_Frame env, const char* name, union Sass_Value* val) { |
177 | (*env->frame)[name] = sass_value_to_ast_node(val); |
178 | } |
179 | union Sass_Value* ADDCALL sass_env_get_local (Sass_Env_Frame env, const char* name) { |
180 | Expression* ex = Cast<Expression>(ptr: env->frame->get_local(key: name)); |
181 | return ex != NULL ? ast_node_to_sass_value(val: ex) : NULL; |
182 | } |
183 | void ADDCALL sass_env_set_local (Sass_Env_Frame env, const char* name, union Sass_Value* val) { |
184 | env->frame->set_local(key: name, val: sass_value_to_ast_node(val)); |
185 | } |
186 | union Sass_Value* ADDCALL sass_env_get_global (Sass_Env_Frame env, const char* name) { |
187 | Expression* ex = Cast<Expression>(ptr: env->frame->get_global(key: name)); |
188 | return ex != NULL ? ast_node_to_sass_value(val: ex) : NULL; |
189 | } |
190 | void ADDCALL sass_env_set_global (Sass_Env_Frame env, const char* name, union Sass_Value* val) { |
191 | env->frame->set_global(key: name, val: sass_value_to_ast_node(val)); |
192 | } |
193 | |
194 | // Getter for import entry |
195 | const char* ADDCALL sass_import_get_imp_path(Sass_Import_Entry entry) { return entry->imp_path; } |
196 | const char* ADDCALL sass_import_get_abs_path(Sass_Import_Entry entry) { return entry->abs_path; } |
197 | const char* ADDCALL sass_import_get_source(Sass_Import_Entry entry) { return entry->source; } |
198 | const char* ADDCALL sass_import_get_srcmap(Sass_Import_Entry entry) { return entry->srcmap; } |
199 | |
200 | // Getter for import error entry |
201 | size_t ADDCALL sass_import_get_error_line(Sass_Import_Entry entry) { return entry->line; } |
202 | size_t ADDCALL sass_import_get_error_column(Sass_Import_Entry entry) { return entry->column; } |
203 | const char* ADDCALL sass_import_get_error_message(Sass_Import_Entry entry) { return entry->error; } |
204 | |
205 | // Explicit functions to take ownership of the memory |
206 | // Resets our own property since we do not know if it is still alive |
207 | char* ADDCALL sass_import_take_source(Sass_Import_Entry entry) { char* ptr = entry->source; entry->source = 0; return ptr; } |
208 | char* ADDCALL sass_import_take_srcmap(Sass_Import_Entry entry) { char* ptr = entry->srcmap; entry->srcmap = 0; return ptr; } |
209 | |
210 | } |
211 | |