sassc 2.1.0.pre1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +11 -0
  5. data/CHANGELOG.md +66 -0
  6. data/CODE_OF_CONDUCT.md +10 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +68 -0
  10. data/Rakefile +30 -0
  11. data/lib/sassc/2.3/libsass.so +0 -0
  12. data/lib/sassc/2.4/libsass.so +0 -0
  13. data/lib/sassc/2.5/libsass.so +0 -0
  14. data/lib/sassc/2.6/libsass.so +0 -0
  15. data/lib/sassc/dependency.rb +17 -0
  16. data/lib/sassc/engine.rb +139 -0
  17. data/lib/sassc/error.rb +37 -0
  18. data/lib/sassc/functions_handler.rb +75 -0
  19. data/lib/sassc/import_handler.rb +50 -0
  20. data/lib/sassc/importer.rb +31 -0
  21. data/lib/sassc/native/lib_c.rb +21 -0
  22. data/lib/sassc/native/native_context_api.rb +147 -0
  23. data/lib/sassc/native/native_functions_api.rb +164 -0
  24. data/lib/sassc/native/sass2scss_api.rb +10 -0
  25. data/lib/sassc/native/sass_input_style.rb +13 -0
  26. data/lib/sassc/native/sass_output_style.rb +12 -0
  27. data/lib/sassc/native/sass_value.rb +97 -0
  28. data/lib/sassc/native/string_list.rb +10 -0
  29. data/lib/sassc/native.rb +70 -0
  30. data/lib/sassc/sass_2_scss.rb +9 -0
  31. data/lib/sassc/script/functions.rb +8 -0
  32. data/lib/sassc/script/value/bool.rb +32 -0
  33. data/lib/sassc/script/value/color.rb +95 -0
  34. data/lib/sassc/script/value/list.rb +136 -0
  35. data/lib/sassc/script/value/map.rb +69 -0
  36. data/lib/sassc/script/value/number.rb +389 -0
  37. data/lib/sassc/script/value/string.rb +96 -0
  38. data/lib/sassc/script/value.rb +137 -0
  39. data/lib/sassc/script/value_conversion/base.rb +13 -0
  40. data/lib/sassc/script/value_conversion/bool.rb +13 -0
  41. data/lib/sassc/script/value_conversion/color.rb +18 -0
  42. data/lib/sassc/script/value_conversion/list.rb +25 -0
  43. data/lib/sassc/script/value_conversion/map.rb +21 -0
  44. data/lib/sassc/script/value_conversion/number.rb +13 -0
  45. data/lib/sassc/script/value_conversion/string.rb +17 -0
  46. data/lib/sassc/script/value_conversion.rb +69 -0
  47. data/lib/sassc/script.rb +19 -0
  48. data/lib/sassc/util/normalized_map.rb +117 -0
  49. data/lib/sassc/util.rb +231 -0
  50. data/lib/sassc/version.rb +5 -0
  51. data/lib/sassc.rb +57 -0
  52. data/sassc.gemspec +57 -0
  53. data/test/custom_importer_test.rb +127 -0
  54. data/test/engine_test.rb +314 -0
  55. data/test/error_test.rb +29 -0
  56. data/test/fixtures/paths.scss +10 -0
  57. data/test/functions_test.rb +303 -0
  58. data/test/native_test.rb +213 -0
  59. data/test/output_style_test.rb +107 -0
  60. data/test/sass_2_scss_test.rb +14 -0
  61. data/test/test_helper.rb +45 -0
  62. metadata +242 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 137213d24e1402de715a72abda7db4d4bfa62edba1103693a7440ec35c92ac1a
4
+ data.tar.gz: 1cde21c700a2ed23cb1980b9a4776ae55f35b333e626a1105747261a674af58a
5
+ SHA512:
6
+ metadata.gz: 7aae31a1033573b0f6b80e090543bc175a659954ade524e0e2b062304062601a8e733aefed306facb9fd628e9f18ee15cd3c0409b98042b7ec7ef8efd02b27eb
7
+ data.tar.gz: 783cef16f7dcd949c6dfe0f2fecaa0f318b4dfd94622d2b5ba9a5f090ed369e0e995608e460758fdb984f637d089f9c646817f322495345518b28dceff85ee08
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /.rvmrc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ *.gem
16
+ mkmf.log
17
+ vendor/bundle
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "ext/libsass"]
2
+ path = ext/libsass
3
+ url = https://github.com/sass/libsass.git
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+
3
+ bundler_args: "--binstubs --standalone --without documentation --path ../bundle"
4
+ script: "bundle exec rake test"
5
+ rvm:
6
+ - 2.3.8
7
+ - 2.4.5
8
+ - 2.5.3
9
+ - 2.6.1
10
+ notifications:
11
+ email: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,66 @@
1
+ - **2.1.0.pre1**
2
+ - [Update Libsass to 3.6.0](https://github.com/sass/sassc-ruby/pull/96/files)
3
+ - [Support old Ruby versions](https://github.com/sass/sassc-ruby/pull/117/files)
4
+ - **2.0.1**
5
+ - [Relax FFI dependency](https://github.com/sass/sassc-ruby/pull/102)
6
+ - **2.0.0**
7
+ - [Remove dependency on Ruby Sass](https://github.com/sass/sassc-ruby/pull/85)
8
+ - [frozen_string_literal all files](https://github.com/sass/sassc-ruby/pull/85)
9
+ - **1.12.1**
10
+ - [Downgrade to libsass 3.5.2 to fix css imports](https://github.com/sass/sassc-ruby/pull/81)
11
+ - **1.12.0**
12
+ - [Update Libsass to 3.5.4](https://github.com/sass/sassc-ruby/pull/78)
13
+ - [bundler is a development dependency](https://github.com/sass/sassc-ruby/pull/51)
14
+ - **1.11.4**
15
+ - Fix `Value::List` related issue with sass 3.5.0
16
+ - **1.11.3**
17
+ - [Require Sass::Deprecation module](https://github.com/sass/sassc-ruby/pull/68)
18
+ - **1.11.2**
19
+ - [Update to libsass 3.4.3](https://github.com/sass/sassc-ruby/pull/65)
20
+ - **1.11.1**
21
+ - [Update to libsass 3.4.1](https://github.com/sass/sassc-ruby/pull/61)
22
+ - **1.11.0**
23
+ - [Add support for lists in functions](https://github.com/sass/sassc-ruby/pull/55)
24
+ - [Update to libsass 3.4.0](https://github.com/sass/sassc-ruby/pull/57)
25
+ - **1.10.1**
26
+ - [Add sourcemap getter](https://github.com/sass/sassc-ruby/pull/48)
27
+ - **1.10.0**
28
+ - [Improved error messages](https://github.com/sass/sassc-ruby/pull/34)
29
+ - Update to Libsass 3.3.6
30
+ - **1.9.0**
31
+ - Support boolean script support
32
+ - **1.8.5**
33
+ - Update to Libsass 3.3.4
34
+ - **1.8.4**
35
+ - Update to Libsass 3.3.3
36
+ - **1.8.3**
37
+ - [Passing empty string into engine does not raise error](https://github.com/sass/sassc-ruby/pull/31)
38
+ - **1.8.2**
39
+ - Update to Libsass 3.3.2
40
+ - **1.8.1**
41
+ - Update to Libsass 3.3.1
42
+ - **1.8.0**
43
+ - Update to Libsass 3.3.0
44
+ - **1.8.0.pre2**
45
+ - Fix bug with looking up gem_path
46
+ - **1.8.0.pre1**
47
+ - [Update to Libsass 3.3.0-beta3](https://github.com/sass/sassc-ruby/pull/20)
48
+ - **1.7.1**
49
+ - Some updates to `Engine` API.
50
+ - **1.7.0**
51
+ - [Support Precision](https://github.com/sass/sassc-ruby/pull/19)
52
+ - **1.6.0**
53
+ - [Support Sass Color types](https://github.com/bolandrm/sassc-ruby/pull/14)
54
+ - [Support quoted strings](https://github.com/bolandrm/sassc-ruby/pull/13)
55
+ - [Improve custom function error handling](https://github.com/bolandrm/sassc-ruby/pull/15)
56
+ - **1.5.1**
57
+ - 2nd attempt at fixing compilation bug (issue [#12](https://github.com/bolandrm/sassc-ruby/issues/12))
58
+ - **1.5.0**
59
+ - Add support for inline source maps
60
+ - Fix compilation bug (issue [#12](https://github.com/bolandrm/sassc-ruby/issues/12))
61
+ - **1.4.0**
62
+ - Add support for line number comments
63
+ - **1.3.0**
64
+ - Support Sass color custom function arguments
65
+ - Adds error handling for exceptions in custom functions
66
+ - Custom functions may have optional/default arguments
@@ -0,0 +1,10 @@
1
+ Sass is more than a technology; Sass is driven by the community of individuals
2
+ that power its development and use every day. As a community, we want to embrace
3
+ the very differences that have made our collaboration so powerful, and work
4
+ together to provide the best environment for learning, growing, and sharing of
5
+ ideas. It is imperative that we keep Sass a fun, welcoming, challenging, and
6
+ fair place to play.
7
+
8
+ [The full community guidelines can be found on the Sass website.][link]
9
+
10
+ [link]: https://sass-lang.com/community-guidelines
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) Ryan Boland & Contributors
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # SassC [![Build Status](https://travis-ci.org/sass/sassc-ruby.svg?branch=master)](https://travis-ci.org/sass/sassc-ruby) [![Gem Version](https://badge.fury.io/rb/sassc.svg)](http://badge.fury.io/rb/sassc)
2
+
3
+ Use `libsass` with Ruby!
4
+
5
+ This gem combines the speed of `libsass`, the [Sass C implementation](https://github.com/sass/libsass), with the ease of use of the original [Ruby Sass](https://github.com/sass/ruby-sass) library.
6
+
7
+ ### libsass Version
8
+
9
+ [3.6.0](https://github.com/sass/libsass/releases/3.6.0)
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'sassc'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ ```bash
22
+ bundle
23
+ ```
24
+
25
+ Or install it yourself as:
26
+
27
+ ```bash
28
+ gem install sassc
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ This library utilizes `libsass` to allow you to compile SCSS or SASS syntax
34
+ to CSS. To compile, use a `SassC::Engine`, e.g.:
35
+
36
+ ```ruby
37
+ SassC::Engine.new(sass, style: :compressed).render
38
+ ```
39
+
40
+ **Note**: If you want to use this library with Rails/Sprockets, check out
41
+ [sassc-rails](https://github.com/bolandrm/sassc-rails).
42
+
43
+ Additionally, you can use `SassC::Sass2Scss` to convert Sass syntax to Scss syntax.
44
+
45
+ ## Credits
46
+
47
+ This gem is maintained by [Ryan Boland](https://ryanboland.com)
48
+ and [awesome contributors](https://github.com/bolandrm/sassc-ruby/graphs/contributors).
49
+
50
+ ## Changelog
51
+
52
+ See [CHANGELOG.md](CHANGELOG.md).
53
+
54
+ ## Contributing
55
+
56
+ ### Project Setup
57
+
58
+ 1. Clone repo
59
+ 1. Install dependencies - `bundle install`
60
+ 1. Run the tests - `bundle exec rake test`
61
+
62
+ ### Code Changes
63
+
64
+ 1. Fork it ( https://github.com/sass/sassc-ruby/fork )
65
+ 1. Create your feature branch (`git checkout -b my-new-feature`)
66
+ 1. Commit your changes (`git commit -am 'Add some feature'`) - try to include tests
67
+ 1. Push to the branch (`git push origin my-new-feature`)
68
+ 1. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ task default: :test
4
+
5
+ require 'rake/extensiontask'
6
+ gem_spec = Gem::Specification.load("sassc.gemspec")
7
+ Rake::ExtensionTask.new('libsass', gem_spec) do |ext|
8
+ ext.name = 'libsass'
9
+ ext.ext_dir = 'ext'
10
+ ext.lib_dir = 'lib/sassc'
11
+ ext.cross_compile = true
12
+ ext.cross_platform = %w[x86-mingw32 x64-mingw32 x86-linux x86_64-linux]
13
+ ext.cross_compiling do |spec|
14
+ spec.files.reject! { |path| File.fnmatch?('ext/*', path) }
15
+ end
16
+ end
17
+
18
+ desc 'Compile all native gems via rake-compiler-dock (Docker)'
19
+ task 'gem:native' do
20
+ require 'rake_compiler_dock'
21
+ RakeCompilerDock.sh "bundle && gem i rake --no-document && "\
22
+ "rake cross native gem MAKE='nice make -j`nproc`' "\
23
+ "RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0"
24
+ end
25
+
26
+ desc "Run all tests"
27
+ task test: 'compile:libsass' do
28
+ $LOAD_PATH.unshift('lib', 'test')
29
+ Dir.glob('./test/**/*_test.rb') { |f| require f }
30
+ end
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ class Dependency
5
+ attr_reader :filename
6
+ attr_reader :options
7
+
8
+ def initialize(filename)
9
+ @filename = filename
10
+ @options = { filename: @filename }
11
+ end
12
+
13
+ def self.from_filenames(filenames)
14
+ filenames.map { |f| new(f) }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "error"
4
+
5
+ module SassC
6
+ class Engine
7
+ OUTPUT_STYLES = %i[
8
+ sass_style_nested
9
+ sass_style_expanded
10
+ sass_style_compact
11
+ sass_style_compressed
12
+ ]
13
+
14
+ attr_reader :template, :options
15
+
16
+ def initialize(template, options = {})
17
+ @template = template
18
+ @options = options
19
+ end
20
+
21
+ def render
22
+ return @template.dup if @template.empty?
23
+
24
+ data_context = Native.make_data_context(@template)
25
+ context = Native.data_context_get_context(data_context)
26
+ native_options = Native.context_get_options(context)
27
+
28
+ Native.option_set_is_indented_syntax_src(native_options, true) if sass?
29
+ Native.option_set_input_path(native_options, filename) if filename
30
+ Native.option_set_precision(native_options, precision) if precision
31
+ Native.option_set_include_path(native_options, load_paths)
32
+ Native.option_set_output_style(native_options, output_style_enum)
33
+ Native.option_set_source_comments(native_options, true) if line_comments?
34
+ Native.option_set_source_map_file(native_options, source_map_file) if source_map_file
35
+ Native.option_set_source_map_embed(native_options, true) if source_map_embed?
36
+ Native.option_set_source_map_contents(native_options, true) if source_map_contents?
37
+ Native.option_set_omit_source_map_url(native_options, true) if omit_source_map_url?
38
+
39
+ import_handler.setup(native_options)
40
+ functions_handler.setup(native_options)
41
+
42
+ status = Native.compile_data_context(data_context)
43
+
44
+ if status != 0
45
+ message = Native.context_get_error_message(context)
46
+ filename = Native.context_get_error_file(context)
47
+ line = Native.context_get_error_line(context)
48
+
49
+ raise SyntaxError.new(message, filename: filename, line: line)
50
+ end
51
+
52
+ css = Native.context_get_output_string(context)
53
+
54
+ @dependencies = Native.context_get_included_files(context)
55
+ @source_map = Native.context_get_source_map_string(context)
56
+
57
+ Native.delete_data_context(data_context)
58
+
59
+ css.force_encoding(@template.encoding)
60
+
61
+ return css unless quiet?
62
+ end
63
+
64
+ def dependencies
65
+ raise NotRenderedError unless @dependencies
66
+ Dependency.from_filenames(@dependencies)
67
+ end
68
+
69
+ def source_map
70
+ raise NotRenderedError unless @source_map
71
+ @source_map
72
+ end
73
+
74
+ def filename
75
+ @options[:filename]
76
+ end
77
+
78
+ private
79
+
80
+ def quiet?
81
+ @options[:quiet]
82
+ end
83
+
84
+ def precision
85
+ @options[:precision]
86
+ end
87
+
88
+ def sass?
89
+ @options[:syntax] && @options[:syntax].to_sym == :sass
90
+ end
91
+
92
+ def line_comments?
93
+ @options[:line_comments]
94
+ end
95
+
96
+ def source_map_embed?
97
+ @options[:source_map_embed]
98
+ end
99
+
100
+ def source_map_contents?
101
+ @options[:source_map_contents]
102
+ end
103
+
104
+ def omit_source_map_url?
105
+ @options[:omit_source_map_url]
106
+ end
107
+
108
+ def source_map_file
109
+ @options[:source_map_file]
110
+ end
111
+
112
+ def import_handler
113
+ @import_handler ||= ImportHandler.new(@options)
114
+ end
115
+
116
+ def functions_handler
117
+ @functions_handler = FunctionsHandler.new(@options)
118
+ end
119
+
120
+ def output_style_enum
121
+ @output_style_enum ||= Native::SassOutputStyle[output_style]
122
+ end
123
+
124
+ def output_style
125
+ @output_style ||= begin
126
+ style = @options.fetch(:style, :sass_style_nested).to_s
127
+ style = "sass_style_#{style}" unless style.include?("sass_style_")
128
+ style = style.to_sym
129
+ raise InvalidStyleError unless Native::SassOutputStyle.symbols.include?(style)
130
+ style
131
+ end
132
+ end
133
+
134
+ def load_paths
135
+ paths = (@options[:load_paths] || []) + SassC.load_paths
136
+ paths.join(File::PATH_SEPARATOR) unless paths.empty?
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+
5
+ module SassC
6
+
7
+ class BaseError < StandardError; end
8
+ class NotRenderedError < BaseError; end
9
+ class InvalidStyleError < BaseError; end
10
+ class UnsupportedValue < BaseError; end
11
+
12
+ # When dealing with SyntaxErrors,
13
+ # it's important to provide filename and line number information.
14
+ # This will be used in various error reports to users, including backtraces.
15
+
16
+ class SyntaxError < BaseError
17
+
18
+ def initialize(message, filename: nil, line: nil)
19
+ @filename = filename
20
+ @line = line
21
+ super(message)
22
+ end
23
+
24
+ def backtrace
25
+ return nil if super.nil?
26
+ sass_backtrace + super
27
+ end
28
+
29
+ # The backtrace of the error within Sass files.
30
+ def sass_backtrace
31
+ return [] unless @filename && @line
32
+ ["#{@filename}:#{@line}"]
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ class FunctionsHandler
5
+ def initialize(options)
6
+ @options = options
7
+ end
8
+
9
+ def setup(native_options)
10
+ @callbacks = {}
11
+ @function_names = {}
12
+
13
+ list = Native.make_function_list(Script.custom_functions.count)
14
+
15
+ functions = FunctionWrapper.extend(Script::Functions)
16
+ functions.options = @options
17
+
18
+ Script.custom_functions.each_with_index do |custom_function, i|
19
+ @callbacks[custom_function] = FFI::Function.new(:pointer, [:pointer, :pointer]) do |native_argument_list, cookie|
20
+ begin
21
+ function_arguments = arguments_from_native_list(native_argument_list)
22
+ result = functions.send(custom_function, *function_arguments)
23
+ to_native_value(result)
24
+ rescue StandardError => exception
25
+ # This rescues any exceptions that occur either in value conversion
26
+ # or during the execution of a custom function.
27
+ error(exception.message)
28
+ end
29
+ end
30
+
31
+ @function_names[custom_function] = Script.formatted_function_name(custom_function)
32
+
33
+ callback = Native.make_function(
34
+ @function_names[custom_function],
35
+ @callbacks[custom_function],
36
+ nil
37
+ )
38
+
39
+ Native::function_set_list_entry(list, i, callback)
40
+ end
41
+
42
+ Native::option_set_c_functions(native_options, list)
43
+ end
44
+
45
+ private
46
+
47
+ def arguments_from_native_list(native_argument_list)
48
+ native_argument_list_length = Native.list_get_length(native_argument_list)
49
+
50
+ (0...native_argument_list_length).map do |i|
51
+ native_value = Native.list_get_value(native_argument_list, i)
52
+ Script::ValueConversion.from_native(native_value, @options)
53
+ end.compact
54
+ end
55
+
56
+ def to_native_value(sass_value)
57
+ # if the custom function returns nil, we provide a "default" return
58
+ # value of an empty string
59
+ sass_value ||= SassC::Script::Value::String.new("")
60
+ sass_value.options = @options
61
+ Script::ValueConversion.to_native(sass_value)
62
+ end
63
+
64
+ def error(message)
65
+ $stderr.puts "[SassC::FunctionsHandler] #{message}"
66
+ Native.make_error(message)
67
+ end
68
+
69
+ class FunctionWrapper
70
+ class << self
71
+ attr_accessor :options
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ class ImportHandler
5
+ def initialize(options)
6
+ @importer = if options[:importer]
7
+ options[:importer].new(options)
8
+ else
9
+ nil
10
+ end
11
+ end
12
+
13
+ def setup(native_options)
14
+ return unless @importer
15
+
16
+ importer_callback = Native.make_importer(import_function, nil)
17
+
18
+ list = Native.make_function_list(1)
19
+ Native::function_set_list_entry(list, 0, importer_callback)
20
+
21
+ Native.option_set_c_importers(native_options, list)
22
+ end
23
+
24
+ private
25
+
26
+ def import_function
27
+ @import_function ||= FFI::Function.new(:pointer, [:string, :pointer, :pointer]) do |path, importer_entry, compiler|
28
+ last_import = Native::compiler_get_last_import(compiler)
29
+ parent_path = Native::import_get_abs_path(last_import)
30
+
31
+ imports = [*@importer.imports(path, parent_path)]
32
+ imports_to_native(imports)
33
+ end
34
+ end
35
+
36
+ def imports_to_native(imports)
37
+ import_list = Native.make_import_list(imports.size)
38
+
39
+ imports.each_with_index do |import, i|
40
+ source = import.source ? Native.native_string(import.source) : nil
41
+ source_map_path = nil
42
+
43
+ entry = Native.make_import_entry(import.path, source, source_map_path)
44
+ Native.import_set_list_entry(import_list, i, entry)
45
+ end
46
+
47
+ import_list
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ class Importer
5
+ attr_reader :options
6
+
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ def imports(path, parent_path)
12
+ # A custom importer must override this method.
13
+ # Custom importer may return an Import, or an array of Imports.
14
+ raise NotImplementedError
15
+ end
16
+
17
+ class Import
18
+ attr_accessor :path, :source, :source_map_path
19
+
20
+ def initialize(path, source: nil, source_map_path: nil)
21
+ @path = path
22
+ @source = source
23
+ @source_map_path = source_map_path
24
+ end
25
+
26
+ def to_s
27
+ "Import: #{path} #{source} #{source_map_path}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ module LibC
6
+ extend FFI::Library
7
+ ffi_lib FFI::Library::LIBC
8
+
9
+ # memory allocators
10
+ attach_function :malloc, [:size_t], :pointer
11
+ # attach_function :calloc, [:size_t], :pointer
12
+ # attach_function :valloc, [:size_t], :pointer
13
+ # attach_function :realloc, [:pointer, :size_t], :pointer
14
+ # attach_function :free, [:pointer], :void
15
+
16
+ # memory movers
17
+ # attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
18
+ # attach_function :bcopy, [:pointer, :pointer, :size_t], :void
19
+ end
20
+ end
21
+ end