forked from nickjs/sassc-ruby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctions_handler.rb
92 lines (72 loc) · 2.66 KB
/
functions_handler.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
module SassC
class FunctionsHandler
def initialize(options)
@options = options
end
def setup(native_options)
@callbacks = {}
@function_names = {}
list = Native.make_function_list(Script.custom_functions.count)
functions = FunctionWrapper.extend(Script::Functions)
functions.options = @options
Script.custom_functions.each_with_index do |custom_function, i|
@callbacks[custom_function] = FFI::Function.new(:pointer, [:pointer, :pointer]) do |native_argument_list, cookie|
native_argument_list_length = Native.list_get_length(native_argument_list)
custom_function_arguments = []
error_tag = nil
(0...native_argument_list_length).each do |i|
native_value = Native.list_get_value(native_argument_list, i)
case value_tag = Native.value_get_tag(native_value)
when :sass_null
# no-op
when :sass_string
native_string = Native.string_get_value(native_value)
argument = Script::String.new(Script::String.unquote(native_string), Script::String.type(native_string))
custom_function_arguments << argument
else
error_tag = error("Sass argument of type #{value_tag} unsupported")
break
end
end
next error_tag if error_tag
begin
value = functions.send(custom_function, *custom_function_arguments)
if value
value = Script::String.new(Script::String.unquote(value.to_s), value.type)
value.to_native
else
Script::String.new("").to_native
end
rescue StandardError => exception
error(exception.message)
end
end
@function_names[custom_function] = Script.formatted_function_name(custom_function)
callback = Native.make_function(
@function_names[custom_function],
@callbacks[custom_function],
nil
)
Native::function_set_list_entry(list, i, callback)
end
Native::option_set_c_functions(native_options, list)
end
private
def error(message)
value = Native::SassValue.new
value[:unknown] = Native::SassUnknown.new
error = Native::SassError.new
error[:tag] = :sass_error
Native.error_set_message(error, Native.native_string(message))
$stderr.puts "[SassC::FunctionsHandler] #{message}"
value[:unknown][:tag] = :sass_error
value[:error] = error
value.pointer
end
class FunctionWrapper
class << self
attr_accessor :options
end
end
end
end