Skip to content

Commit 50b9abb

Browse files
committed
Merge pull request #7 from edward/allow-optional-params
Allow optional params
2 parents de5c023 + 4b4d324 commit 50b9abb

File tree

11 files changed

+182
-60
lines changed

11 files changed

+182
-60
lines changed

Rakefile

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,12 @@ rescue LoadError
44
puts 'Cannot load bundler/gem_tasks'
55
end
66

7-
task default: :prepare
7+
require 'tasks/libsass'
88

9-
task prepare: "ext/lib/libsass.so"
9+
task default: :test
1010

11-
file "ext/lib/libsass.so" do
12-
gem_dir = File.expand_path(File.dirname(__FILE__)) + "/"
13-
cd "ext/libsass"
14-
sh 'make lib/libsass.so LDFLAGS="-Wall -O2"'
15-
cd gem_dir
16-
end
17-
18-
task test: :prepare do
11+
desc "Run all tests"
12+
task test: 'libsass:compile' do
1913
$LOAD_PATH.unshift('lib', 'test')
2014
Dir.glob('./test/**/*_test.rb') { |f| require f }
2115
end
22-
23-
task :submodule do
24-
sh "git submodule update --init"
25-
end

ext/Rakefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
require_relative '../lib/tasks/libsass'
2+
3+
task default: 'libsass:compile'

lib/sassc/functions_handler.rb

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,45 @@ def setup(native_options)
1010

1111
list = Native.make_function_list(Script.custom_functions.count)
1212

13-
functs = FunctionWrapper.extend(Script::Functions)
14-
functs.options = @options
13+
functions = FunctionWrapper.extend(Script::Functions)
14+
functions.options = @options
1515

1616
Script.custom_functions.each_with_index do |custom_function, i|
17-
@callbacks[custom_function] = FFI::Function.new(:pointer, [:pointer, :pointer]) do |s_args, cookie|
18-
length = Native.list_get_length(s_args)
17+
@callbacks[custom_function] = FFI::Function.new(:pointer, [:pointer, :pointer]) do |native_argument_list, cookie|
18+
native_argument_list_length = Native.list_get_length(native_argument_list)
19+
custom_function_arguments = []
20+
error_tag = nil
1921

20-
v = Native.list_get_value(s_args, 0)
21-
v = Native.string_get_value(v).dup
22+
(0...native_argument_list_length).each do |i|
23+
native_value = Native.list_get_value(native_argument_list, i)
2224

23-
s = Script::String.new(Script::String.unquote(v), Script::String.type(v))
25+
case value_tag = Native.value_get_tag(native_value)
26+
when :sass_null
27+
# no-op
28+
when :sass_string
29+
native_string = Native.string_get_value(native_value)
30+
argument = Script::String.new(Script::String.unquote(native_string), Script::String.type(native_string))
2431

25-
value = functs.send(custom_function, s)
32+
custom_function_arguments << argument
33+
else
34+
error_tag = error("Sass argument of type #{value_tag} unsupported")
35+
break
36+
end
37+
end
38+
39+
next error_tag if error_tag
2640

27-
if value
28-
value = Script::String.new(Script::String.unquote(value.to_s), value.type)
29-
value.to_native
30-
else
31-
Script::String.new("").to_native
41+
begin
42+
value = functions.send(custom_function, *custom_function_arguments)
43+
44+
if value
45+
value = Script::String.new(Script::String.unquote(value.to_s), value.type)
46+
value.to_native
47+
else
48+
Script::String.new("").to_native
49+
end
50+
rescue StandardError => exception
51+
error(exception.message)
3252
end
3353
end
3454

@@ -48,6 +68,21 @@ def setup(native_options)
4868

4969
private
5070

71+
def error(message)
72+
value = Native::SassValue.new
73+
value[:unknown] = Native::SassUnknown.new
74+
75+
error = Native::SassError.new
76+
error[:tag] = :sass_error
77+
78+
Native.error_set_message(error, Native.native_string(message))
79+
$stderr.puts "[SassC::FunctionsHandler] #{message}"
80+
81+
value[:unknown][:tag] = :sass_error
82+
value[:error] = error
83+
value.pointer
84+
end
85+
5186
class FunctionWrapper
5287
class << self
5388
attr_accessor :options

lib/sassc/native.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ def self.return_string_array(ptr)
4848
end
4949

5050
def self.native_string(string)
51-
string += "\0"
51+
string = string.to_s
52+
string << "\0"
5253
data = Native::LibC.malloc(string.bytesize)
5354
data.write_string(string)
5455
data

lib/sassc/native/native_functions_api.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module Native
1919

2020
# ADDAPI enum Sass_Tag ADDCALL sass_value_get_tag (const union Sass_Value* v);
2121
attach_function :sass_value_get_tag, [:sass_value_ptr], SassTag
22+
attach_function :sass_value_is_null, [:sass_value_ptr], :bool
2223

2324
# ADDAPI const char* ADDCALL sass_string_get_value (const union Sass_Value* v);
2425
attach_function :sass_string_get_value, [:sass_value_ptr], :string
@@ -28,6 +29,11 @@ module Native
2829
attach_function :sass_list_get_length, [:sass_value_ptr], :size_t
2930
attach_function :sass_list_get_value, [:sass_value_ptr, :size_t], :sass_value_ptr
3031

32+
# ADDAPI char* ADDCALL sass_error_get_message (const union Sass_Value* v);
33+
# ADDAPI void ADDCALL sass_error_set_message (union Sass_Value* v, char* msg);
34+
attach_function :sass_error_get_message, [:sass_value_ptr], :string
35+
attach_function :sass_error_set_message, [:sass_value_ptr, :pointer], :void
36+
3137
# Getters for custom function descriptors
3238
# ADDAPI const char* ADDCALL sass_function_get_signature (Sass_C_Function_Callback fn);
3339
# ADDAPI Sass_C_Function ADDCALL sass_function_get_function (Sass_C_Function_Callback fn);

lib/sassc/native/sass_value.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ class SassNull < FFI::Struct
7171

7272
class SassError < FFI::Struct
7373
layout :tag, SassTag,
74-
:messsage, :string
74+
:message, :string
7575
end
7676

7777
class SassWarning < FFI::Struct
7878
layout :tag, SassTag,
79-
:messsage, :string
79+
:message, :string
8080
end
8181

8282
class SassValue # < FFI::Union

lib/sassc/script.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ def self.custom_functions
88

99
def self.formatted_function_name(function_name)
1010
params = Functions.instance_method(function_name).parameters
11-
params = params.select { |param| param[0] == :req }
12-
.map(&:first)
13-
.map { |p| "$#{p}" }
11+
params = params.map { |param_type, name| "$#{name}#{': null' if param_type == :opt}" }
1412
.join(", ")
13+
1514
"#{function_name}(#{params})"
1615
end
1716
end

lib/sassc/script/string.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ def self.type(contents)
6666
def self.unquote(contents)
6767
s = contents.dup
6868

69-
case contents[0,1]
69+
case contents[0, 1]
7070
when "'", '"', '`'
7171
s[0] = ''
7272
end
7373

74-
case contents[-1,1]
74+
case contents[-1, 1]
7575
when "'", '"', '`'
7676
s[-1] = ''
7777
end

lib/tasks/libsass.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace :libsass do
2+
desc "Compile libsass"
3+
task compile: "ext/libsass/lib/libsass.so"
4+
5+
file "ext/libsass/.git" do
6+
sh "git submodule update --init"
7+
end
8+
9+
file "ext/libsass/lib/libsass.so" => "ext/libsass/.git" do
10+
libsass_path = ""
11+
if Dir.pwd.end_with?('/ext')
12+
libsass_path = "libsass"
13+
else
14+
libsass_path = "ext/libsass"
15+
end
16+
17+
cd libsass_path do
18+
sh 'make lib/libsass.so LDFLAGS="-Wall -O2"'
19+
end
20+
end
21+
end

sassc.gemspec

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ Gem::Specification.new do |spec|
1616
spec.files = `git ls-files -z`.split("\x0")
1717
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
1818
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19-
spec.require_paths = ["lib", "ext"]
2019

21-
spec.extensions = ["Rakefile"]
20+
spec.require_paths = ["lib"]
21+
22+
spec.extensions = ["ext/Rakefile"]
2223

2324
spec.add_development_dependency "rake"
2425
spec.add_development_dependency "minitest", "~> 5.5.1"

0 commit comments

Comments
 (0)