1414
1515#include "ppport.h"
1616
17+ #include "sass.h"
1718#include "sass2scss.h"
19+ #include "sass_values.h"
1820#include "sass_context.h"
21+ #include "sass_functions.h"
1922
2023#define isSafeSv (sv ) sv && SvOK(*sv)
2124#define Constant (c ) newCONSTSUB(stash, #c, newSViv(c))
@@ -293,7 +296,7 @@ SV* sass_value_to_sv(union Sass_Value* val)
293296}
294297
295298
296- struct Sass_Import * * sass_importer (const char * url , const char * prev , void * cookie )
299+ Sass_Import_List sass_importer (const char * cur_path , Sass_Importer_Entry cb , struct Sass_Compiler * comp )
297300{
298301
299302 dSP ;
@@ -305,9 +308,13 @@ struct Sass_Import** sass_importer(const char* url, const char* prev, void* cook
305308 ENTER ;
306309 SAVETMPS ;
307310
311+ void * cookie = sass_importer_get_cookie (cb );
312+ struct Sass_Import * previous = sass_compiler_get_last_import (comp );
313+ const char * prev_path = sass_import_get_path (previous );
314+
308315 PUSHMARK (SP );
309- XPUSHs (sv_2mortal (newSVpv (url , 0 )));
310- XPUSHs (sv_2mortal (newSVpv (prev , 0 )));
316+ XPUSHs (sv_2mortal (newSVpv (cur_path , 0 )));
317+ XPUSHs (sv_2mortal (newSVpv (prev_path , 0 )));
311318 PUTBACK ;
312319
313320 // call the static function by soft name reference
@@ -439,9 +446,8 @@ struct Sass_Import** sass_importer(const char* url, const char* prev, void* cook
439446
440447}
441448
442-
443449// we are called by libsass to dispatch to registered functions
444- union Sass_Value * call_sass_function (const union Sass_Value * s_args , void * cookie )
450+ union Sass_Value * call_sass_function (const union Sass_Value * s_args , Sass_Function_Entry cb , struct Sass_Options * opts )
445451{
446452
447453 dSP ;
@@ -454,6 +460,8 @@ union Sass_Value* call_sass_function(const union Sass_Value* s_args, void* cooki
454460 ENTER ;
455461 SAVETMPS ;
456462
463+ void * cookie = sass_function_get_cookie (cb );
464+
457465 PUSHMARK (SP );
458466 for (i = 0 ; i < sass_list_get_length (s_args ); i ++ ) {
459467 // get the Sass_Value from libsass
@@ -518,8 +526,9 @@ SV* init_sass_options(struct Sass_Options* sass_options, HV* perl_options)
518526 SV * * indent_sv = hv_fetchs (perl_options , "indent" , false);
519527 SV * * source_map_root_sv = hv_fetchs (perl_options , "source_map_root" , false);
520528 SV * * source_map_file_sv = hv_fetchs (perl_options , "source_map_file" , false);
521- SV * * sass_functions_sv = hv_fetchs (perl_options , "sass_functions" , false);
522- SV * * importer_sv = hv_fetchs (perl_options , "importer" , false);
529+ SV * * sass_headers_sv = hv_fetchs (perl_options , "headers" , false);
530+ SV * * sass_importers_sv = hv_fetchs (perl_options , "importers" , false);
531+ SV * * sass_functions_sv = hv_fetchs (perl_options , "functions" , false);
523532
524533 if (input_path_sv ) sass_option_set_input_path (sass_options , safe_svpv (* input_path_sv , "" ));
525534 if (output_path_sv ) sass_option_set_output_path (sass_options , safe_svpv (* output_path_sv , "" ));
@@ -539,7 +548,67 @@ SV* init_sass_options(struct Sass_Options* sass_options, HV* perl_options)
539548 if (isSafeSv (linefeed_sv )) sass_option_set_linefeed (sass_options , SvPV_nolen (* linefeed_sv ));
540549 if (isSafeSv (precision_sv )) sass_option_set_precision (sass_options , SvUV (* precision_sv ));
541550
542- if (importer_sv ) { sass_option_set_importer (sass_options , sass_make_importer (sass_importer , * importer_sv )); }
551+ if (sass_importers_sv ) {
552+ int i ;
553+ AV * sass_importers_av ;
554+ if (!SvROK (* sass_importers_sv ) || SvTYPE (SvRV (* sass_importers_sv )) != SVt_PVAV ) {
555+ return newSVpvf ("sass_importers should be an arrayref (SvTYPE=%u)" , (unsigned )SvTYPE (SvRV (* sass_importers_sv )));
556+ }
557+ sass_importers_av = (AV * )SvRV (* sass_importers_sv );
558+
559+ Sass_Importer_List c_importers = sass_make_importer_list (av_len (sass_importers_av ) + 1 );
560+
561+ if (!c_importers ) {
562+ return newSVpv ("couldn't alloc memory for c_importers" , 0 );
563+ }
564+ for (i = 0 ; i <=av_len (sass_importers_av ); i ++ ) {
565+ SV * * entry_sv = av_fetch (sass_importers_av , i , false);
566+ AV * entry_av ;
567+ if (!SvROK (* entry_sv ) || SvTYPE (SvRV (* entry_sv )) != SVt_PVAV ) {
568+ return newSVpvf ("each sass_importer entry should be an arrayref (SvTYPE=%u)" , (unsigned )SvTYPE (SvRV (* entry_sv )));
569+ }
570+ entry_av = (AV * )SvRV (* entry_sv );
571+
572+ SV * * importer_sv = av_fetch (entry_av , 0 , false);
573+ SV * * priority_sv = av_fetch (entry_av , 1 , false);
574+ double priority = priority_sv ? SvNV (* priority_sv ) : 0 ;
575+ if (!importer_sv ) return newSVpv ("custom importer without callback" , 0 );
576+ c_importers [i ] = sass_make_importer (sass_importer , priority , * importer_sv );
577+ }
578+
579+ sass_option_set_c_importers (sass_options , c_importers );
580+ }
581+
582+ if (sass_headers_sv ) {
583+ int i ;
584+ AV * sass_headers_av ;
585+ if (!SvROK (* sass_headers_sv ) || SvTYPE (SvRV (* sass_headers_sv )) != SVt_PVAV ) {
586+ return newSVpvf ("sass_headers should be an arrayref (SvTYPE=%u)" , (unsigned )SvTYPE (SvRV (* sass_headers_sv )));
587+ }
588+ sass_headers_av = (AV * )SvRV (* sass_headers_sv );
589+
590+ Sass_Importer_List c_headers = sass_make_importer_list (av_len (sass_headers_av ) + 1 );
591+
592+ if (!c_headers ) {
593+ return newSVpv ("couldn't alloc memory for c_headers" , 0 );
594+ }
595+ for (i = 0 ; i <=av_len (sass_headers_av ); i ++ ) {
596+ SV * * entry_sv = av_fetch (sass_headers_av , i , false);
597+ AV * entry_av ;
598+ if (!SvROK (* entry_sv ) || SvTYPE (SvRV (* entry_sv )) != SVt_PVAV ) {
599+ return newSVpvf ("each sass_header entry should be an arrayref (SvTYPE=%u)" , (unsigned )SvTYPE (SvRV (* entry_sv )));
600+ }
601+ entry_av = (AV * )SvRV (* entry_sv );
602+
603+ SV * * header_sv = av_fetch (entry_av , 0 , false);
604+ SV * * priority_sv = av_fetch (entry_av , 1 , false);
605+ double priority = priority_sv ? SvNV (* priority_sv ) : 0 ;
606+ if (!header_sv ) return newSVpv ("custom header without callback" , 0 );
607+ c_headers [i ] = sass_make_importer (sass_importer , priority , * header_sv );
608+ }
609+
610+ sass_option_set_c_headers (sass_options , c_headers );
611+ }
543612
544613 if (sass_functions_sv ) {
545614 int i ;
@@ -549,7 +618,7 @@ SV* init_sass_options(struct Sass_Options* sass_options, HV* perl_options)
549618 }
550619 sass_functions_av = (AV * )SvRV (* sass_functions_sv );
551620
552- Sass_C_Function_List c_functions = sass_make_function_list (av_len (sass_functions_av ) + 1 );
621+ Sass_Function_List c_functions = sass_make_function_list (av_len (sass_functions_av ) + 1 );
553622
554623 if (!c_functions ) {
555624 return newSVpv ("couldn't alloc memory for c_functions" , 0 );
@@ -749,6 +818,23 @@ unquote(str)
749818 OUTPUT :
750819 RETVAL
751820
821+ SV *
822+ resolve_file (file )
823+ char * file
824+ CODE :
825+ {
826+
827+ const char * paths [4 ] = { "." , "t" , "bin" , NULL };
828+ char * resolved = sass_resolve_file (file , paths );
829+
830+ RETVAL = newSVpv (resolved , 0 );
831+
832+ free (resolved );
833+
834+ }
835+ OUTPUT :
836+ RETVAL
837+
752838SV *
753839import_sv (sv )
754840 SV * sv
0 commit comments