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 sass_make_function_list(size_t length)15 Sass_Function_List ADDCALL sass_make_function_list(size_t length) 16 { 17 return (Sass_Function_List) calloc(length + 1, sizeof(Sass_Function_Entry)); 18 } 19 sass_make_function(const char * signature,Sass_Function_Fn function,void * cookie)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(1, sizeof(Sass_Function)); 23 if (cb == 0) return 0; 24 cb->signature = sass_copy_c_string(signature); 25 cb->function = function; 26 cb->cookie = cookie; 27 return cb; 28 } 29 sass_delete_function(Sass_Function_Entry entry)30 void ADDCALL sass_delete_function(Sass_Function_Entry entry) 31 { 32 free(entry->signature); 33 free(entry); 34 } 35 36 // Deallocator for the allocated memory sass_delete_function_list(Sass_Function_List list)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(*list); 43 ++list; 44 } 45 free(it); 46 } 47 48 // Setters and getters for callbacks on function lists sass_function_get_list_entry(Sass_Function_List list,size_t pos)49 Sass_Function_Entry ADDCALL sass_function_get_list_entry(Sass_Function_List list, size_t pos) { return list[pos]; } sass_function_set_list_entry(Sass_Function_List list,size_t pos,Sass_Function_Entry cb)50 void sass_function_set_list_entry(Sass_Function_List list, size_t pos, Sass_Function_Entry cb) { list[pos] = cb; } 51 sass_function_get_signature(Sass_Function_Entry cb)52 const char* ADDCALL sass_function_get_signature(Sass_Function_Entry cb) { return cb->signature; } sass_function_get_function(Sass_Function_Entry cb)53 Sass_Function_Fn ADDCALL sass_function_get_function(Sass_Function_Entry cb) { return cb->function; } sass_function_get_cookie(Sass_Function_Entry cb)54 void* ADDCALL sass_function_get_cookie(Sass_Function_Entry cb) { return cb->cookie; } 55 sass_make_importer(Sass_Importer_Fn importer,double priority,void * cookie)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(1, 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 sass_importer_get_function(Sass_Importer_Entry cb)66 Sass_Importer_Fn ADDCALL sass_importer_get_function(Sass_Importer_Entry cb) { return cb->importer; } sass_importer_get_priority(Sass_Importer_Entry cb)67 double ADDCALL sass_importer_get_priority (Sass_Importer_Entry cb) { return cb->priority; } sass_importer_get_cookie(Sass_Importer_Entry cb)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 sass_delete_importer(Sass_Importer_Entry cb)71 void ADDCALL sass_delete_importer (Sass_Importer_Entry cb) 72 { 73 free(cb); 74 } 75 76 // Creator for sass custom importer function list sass_make_importer_list(size_t length)77 Sass_Importer_List ADDCALL sass_make_importer_list(size_t length) 78 { 79 return (Sass_Importer_List) calloc(length + 1, sizeof(Sass_Importer_Entry)); 80 } 81 82 // Deallocator for the allocated memory sass_delete_importer_list(Sass_Importer_List list)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(*list); 89 ++list; 90 } 91 free(it); 92 } 93 sass_importer_get_list_entry(Sass_Importer_List list,size_t idx)94 Sass_Importer_Entry ADDCALL sass_importer_get_list_entry(Sass_Importer_List list, size_t idx) { return list[idx]; } sass_importer_set_list_entry(Sass_Importer_List list,size_t idx,Sass_Importer_Entry cb)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 sass_make_import_list(size_t length)98 Sass_Import_List ADDCALL sass_make_import_list(size_t length) 99 { 100 return (Sass_Import**) calloc(length + 1, 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) sass_make_import(const char * imp_path,const char * abs_path,char * source,char * srcmap)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(1, sizeof(Sass_Import)); 108 if (v == 0) return 0; 109 v->imp_path = imp_path ? sass_copy_c_string(imp_path) : 0; 110 v->abs_path = abs_path ? sass_copy_c_string(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? sass_make_import_entry(const char * path,char * source,char * srcmap)120 Sass_Import_Entry ADDCALL sass_make_import_entry(const char* path, char* source, char* srcmap) 121 { 122 return sass_make_import(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) sass_import_set_error(Sass_Import_Entry import,const char * error,size_t line,size_t col)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(import->error); 130 import->error = error ? sass_copy_c_string(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 sass_import_set_list_entry(Sass_Import_List list,size_t idx,Sass_Import_Entry entry)137 void ADDCALL sass_import_set_list_entry(Sass_Import_List list, size_t idx, Sass_Import_Entry entry) { list[idx] = entry; } sass_import_get_list_entry(Sass_Import_List list,size_t idx)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 sass_delete_import_list(Sass_Import_List list)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(it); 150 } 151 152 // Just in case we have some stray import structs sass_delete_import(Sass_Import_Entry import)153 void ADDCALL sass_delete_import(Sass_Import_Entry import) 154 { 155 free(import->imp_path); 156 free(import->abs_path); 157 free(import->source); 158 free(import->srcmap); 159 free(import->error); 160 free(import); 161 } 162 163 // Getter for callee entry sass_callee_get_name(Sass_Callee_Entry entry)164 const char* ADDCALL sass_callee_get_name(Sass_Callee_Entry entry) { return entry->name; } sass_callee_get_path(Sass_Callee_Entry entry)165 const char* ADDCALL sass_callee_get_path(Sass_Callee_Entry entry) { return entry->path; } sass_callee_get_line(Sass_Callee_Entry entry)166 size_t ADDCALL sass_callee_get_line(Sass_Callee_Entry entry) { return entry->line; } sass_callee_get_column(Sass_Callee_Entry entry)167 size_t ADDCALL sass_callee_get_column(Sass_Callee_Entry entry) { return entry->column; } sass_callee_get_type(Sass_Callee_Entry entry)168 enum Sass_Callee_Type ADDCALL sass_callee_get_type(Sass_Callee_Entry entry) { return entry->type; } sass_callee_get_env(Sass_Callee_Entry entry)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) sass_env_get_lexical(Sass_Env_Frame env,const char * name)172 union Sass_Value* ADDCALL sass_env_get_lexical (Sass_Env_Frame env, const char* name) { 173 Expression* ex = Cast<Expression>((*env->frame)[name]); 174 return ex != NULL ? ast_node_to_sass_value(ex) : NULL; 175 } sass_env_set_lexical(Sass_Env_Frame env,const char * name,union Sass_Value * val)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 } sass_env_get_local(Sass_Env_Frame env,const char * name)179 union Sass_Value* ADDCALL sass_env_get_local (Sass_Env_Frame env, const char* name) { 180 Expression* ex = Cast<Expression>(env->frame->get_local(name)); 181 return ex != NULL ? ast_node_to_sass_value(ex) : NULL; 182 } sass_env_set_local(Sass_Env_Frame env,const char * name,union Sass_Value * val)183 void ADDCALL sass_env_set_local (Sass_Env_Frame env, const char* name, union Sass_Value* val) { 184 env->frame->set_local(name, sass_value_to_ast_node(val)); 185 } sass_env_get_global(Sass_Env_Frame env,const char * name)186 union Sass_Value* ADDCALL sass_env_get_global (Sass_Env_Frame env, const char* name) { 187 Expression* ex = Cast<Expression>(env->frame->get_global(name)); 188 return ex != NULL ? ast_node_to_sass_value(ex) : NULL; 189 } sass_env_set_global(Sass_Env_Frame env,const char * name,union Sass_Value * val)190 void ADDCALL sass_env_set_global (Sass_Env_Frame env, const char* name, union Sass_Value* val) { 191 env->frame->set_global(name, sass_value_to_ast_node(val)); 192 } 193 194 // Getter for import entry sass_import_get_imp_path(Sass_Import_Entry entry)195 const char* ADDCALL sass_import_get_imp_path(Sass_Import_Entry entry) { return entry->imp_path; } sass_import_get_abs_path(Sass_Import_Entry entry)196 const char* ADDCALL sass_import_get_abs_path(Sass_Import_Entry entry) { return entry->abs_path; } sass_import_get_source(Sass_Import_Entry entry)197 const char* ADDCALL sass_import_get_source(Sass_Import_Entry entry) { return entry->source; } sass_import_get_srcmap(Sass_Import_Entry entry)198 const char* ADDCALL sass_import_get_srcmap(Sass_Import_Entry entry) { return entry->srcmap; } 199 200 // Getter for import error entry sass_import_get_error_line(Sass_Import_Entry entry)201 size_t ADDCALL sass_import_get_error_line(Sass_Import_Entry entry) { return entry->line; } sass_import_get_error_column(Sass_Import_Entry entry)202 size_t ADDCALL sass_import_get_error_column(Sass_Import_Entry entry) { return entry->column; } sass_import_get_error_message(Sass_Import_Entry entry)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 sass_import_take_source(Sass_Import_Entry entry)207 char* ADDCALL sass_import_take_source(Sass_Import_Entry entry) { char* ptr = entry->source; entry->source = 0; return ptr; } sass_import_take_srcmap(Sass_Import_Entry entry)208 char* ADDCALL sass_import_take_srcmap(Sass_Import_Entry entry) { char* ptr = entry->srcmap; entry->srcmap = 0; return ptr; } 209 210 } 211