sassc 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -3
  3. data/ext/libsass/.gitignore +3 -0
  4. data/ext/libsass/.travis.yml +1 -1
  5. data/ext/libsass/GNUmakefile.am +7 -7
  6. data/ext/libsass/Makefile +7 -4
  7. data/ext/libsass/Makefile.conf +0 -1
  8. data/ext/libsass/appveyor.yml +6 -2
  9. data/ext/libsass/docs/api-context.md +4 -4
  10. data/ext/libsass/docs/api-doc.md +29 -11
  11. data/ext/libsass/docs/api-importer-example.md +5 -5
  12. data/ext/libsass/docs/build-on-windows.md +1 -1
  13. data/ext/libsass/include/sass/base.h +10 -0
  14. data/ext/libsass/include/sass/version.h +4 -0
  15. data/ext/libsass/include/sass/version.h.in +4 -0
  16. data/ext/libsass/include/sass2scss.h +1 -1
  17. data/ext/libsass/script/ci-build-libsass +15 -3
  18. data/ext/libsass/src/ast.cpp +161 -6
  19. data/ext/libsass/src/ast.hpp +71 -44
  20. data/ext/libsass/src/ast_factory.hpp +1 -1
  21. data/ext/libsass/src/ast_fwd_decl.hpp +2 -2
  22. data/ext/libsass/src/constants.cpp +2 -4
  23. data/ext/libsass/src/constants.hpp +3 -4
  24. data/ext/libsass/src/context.cpp +16 -17
  25. data/ext/libsass/src/context.hpp +2 -2
  26. data/ext/libsass/src/cssize.cpp +19 -8
  27. data/ext/libsass/src/cssize.hpp +5 -2
  28. data/ext/libsass/src/debugger.hpp +6 -3
  29. data/ext/libsass/src/emitter.cpp +1 -1
  30. data/ext/libsass/src/environment.cpp +1 -1
  31. data/ext/libsass/src/eval.cpp +42 -14
  32. data/ext/libsass/src/eval.hpp +1 -1
  33. data/ext/libsass/src/expand.cpp +24 -8
  34. data/ext/libsass/src/expand.hpp +2 -1
  35. data/ext/libsass/src/extend.cpp +55 -15
  36. data/ext/libsass/src/extend.hpp +5 -1
  37. data/ext/libsass/src/functions.cpp +10 -5
  38. data/ext/libsass/src/inspect.cpp +25 -19
  39. data/ext/libsass/src/inspect.hpp +2 -2
  40. data/ext/libsass/src/json.cpp +20 -9
  41. data/ext/libsass/src/json.hpp +5 -5
  42. data/ext/libsass/src/lexer.cpp +4 -1
  43. data/ext/libsass/src/lexer.hpp +21 -0
  44. data/ext/libsass/src/listize.cpp +2 -1
  45. data/ext/libsass/src/operation.hpp +4 -4
  46. data/ext/libsass/src/output.cpp +1 -1
  47. data/ext/libsass/src/output.hpp +1 -1
  48. data/ext/libsass/src/parser.cpp +189 -90
  49. data/ext/libsass/src/parser.hpp +42 -2
  50. data/ext/libsass/src/prelexer.cpp +474 -7
  51. data/ext/libsass/src/prelexer.hpp +15 -2
  52. data/ext/libsass/src/remove_placeholders.cpp +5 -5
  53. data/ext/libsass/src/remove_placeholders.hpp +3 -2
  54. data/ext/libsass/src/sass.cpp +33 -3
  55. data/ext/libsass/src/sass2scss.cpp +7 -0
  56. data/ext/libsass/src/sass_context.cpp +32 -62
  57. data/ext/libsass/src/sass_functions.cpp +3 -3
  58. data/ext/libsass/src/sass_values.cpp +5 -5
  59. data/ext/libsass/src/utf8/unchecked.h +16 -16
  60. data/ext/libsass/src/util.cpp +51 -30
  61. data/ext/libsass/src/util.hpp +6 -1
  62. data/ext/libsass/win/libsass.targets +0 -2
  63. data/ext/libsass/win/libsass.vcxproj.filters +0 -6
  64. data/lib/sassc/engine.rb +4 -1
  65. data/lib/sassc/error.rb +23 -1
  66. data/lib/sassc/version.rb +1 -1
  67. data/test/error_test.rb +27 -0
  68. data/test/native_test.rb +1 -1
  69. metadata +5 -5
  70. data/ext/libsass/include/sass/interface.h +0 -105
  71. data/ext/libsass/src/sass_interface.cpp +0 -215
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4aafee4a5710a8ea851a5702e8a0cc565072af21
4
- data.tar.gz: 1971d63aab1fabbbf3354dcf3f4c722c37884e43
3
+ metadata.gz: b52db28344dd1103c3d9c82150b7670f31e040d6
4
+ data.tar.gz: 0ce1622190528f513b5460017c4033da8932fb4d
5
5
  SHA512:
6
- metadata.gz: da80b6d5c99d360c2a015b30a26758eb58823e44082532b058c159e36f0bffa2b5b0ebc95da828274874e1ed6182b9d9b2cfbff27cc22cc9d1c8b9a9c3523743
7
- data.tar.gz: 3f8022f8d73ea4ab6cced6b8bcb7c39a47ae1039c2919777d27f9bce7e7a9af763834bd05196c40fe1c5322c6ea5523d99836c062e72fa6a41604fa0d963adb7
6
+ metadata.gz: ca2d6b6f548d6c73c419dc6ba94c3d0a20fbed1af6a95862a8ff3c68fb55e583c9a51f33b5122e353d6514d9998fad8a388131a9b74b3a9d06433eacae5461e6
7
+ data.tar.gz: 06e7cb73e2e52f756aa0980c449b8f32d6f10c6be9a9e8a4e223d9f34603221e2859ae80a41eca0e9066e0d9e8cc0848ab259b0c03a0f20dd927542b50609d7a
data/README.md CHANGED
@@ -6,12 +6,36 @@ This gem combines the speed of `libsass`, the [Sass C implementation](https://gi
6
6
 
7
7
  ### libsass Version
8
8
 
9
- [3.3.3](https://github.com/sass/libsass/releases/tag/3.3.3)
9
+ [3.3.6](https://github.com/sass/libsass/releases/tag/3.3.6)
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
+ ```
10
30
 
11
31
  ## Usage
12
32
 
13
33
  This library utilizes `libsass` to allow you to compile SCSS or SASS syntax
14
- to CSS. To compile, use a `SassC::Engine`.
34
+ to CSS. To compile, use a `SassC::Engine`, e.g.:
35
+
36
+ ```ruby
37
+ SassC::Engine.new(sass, style: :compressed).render
38
+ ```
15
39
 
16
40
  **Note**: If you want to use this library with Rails/Sprockets, check out
17
41
  [sassc-rails](https://github.com/bolandrm/sassc-rails).
@@ -25,8 +49,11 @@ and [awesome contributors](https://github.com/bolandrm/sassc-ruby/graphs/contrib
25
49
 
26
50
  ## Changelog
27
51
 
52
+ - **1.10.0**
53
+ - [Improved error messages](https://github.com/sass/sassc-ruby/pull/34)
54
+ - Update to Libsass 3.3.6
28
55
  - **1.9.0**
29
- Support boolean script support
56
+ - Support boolean script support
30
57
  - **1.8.5**
31
58
  - Update to Libsass 3.3.4
32
59
  - **1.8.4**
@@ -1,5 +1,8 @@
1
1
  # Miscellaneous stuff
2
2
 
3
+ /sassc
4
+ /sass-spec
5
+
3
6
  VERSION
4
7
  .DS_Store
5
8
  .sass-cache
@@ -37,7 +37,7 @@ matrix:
37
37
  - os: osx
38
38
  compiler: gcc
39
39
  - os: osx
40
- env: AUTOTOOLS=no COVERAGE=yes BUILD=static
40
+ env: AUTOTOOLS=no BUILD=static
41
41
 
42
42
  script: ./script/ci-build-libsass
43
43
  before_install: ./script/ci-install-deps
@@ -57,9 +57,9 @@ TESTS = \
57
57
  $(SASS_SPEC_PATH)/spec/scss-tests \
58
58
  $(SASS_SPEC_PATH)/spec/types
59
59
 
60
- SASS_TEST_FLAGS =
60
+ SASS_TEST_FLAGS = -V 3.4 --impl libsass
61
61
  LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) ./script/tap-driver
62
- AM_LOG_FLAGS = -c ./tester --ignore-todo $(LOG_FLAGS)
62
+ AM_LOG_FLAGS = -c ./tester $(LOG_FLAGS)
63
63
  if USE_TAP
64
64
  AM_LOG_FLAGS += -t
65
65
  SASS_TEST_FLAGS += -t | tapout
@@ -72,16 +72,16 @@ SASS_TESTER = $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb
72
72
  SASS_TESTER += -c $(SASS_LIBSASS_PATH)/tester$(EXEEXT)
73
73
 
74
74
  test:
75
- $(SASS_TESTER) --ignore-todo $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
75
+ $(SASS_TESTER) $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
76
76
 
77
77
  test_build:
78
- $(SASS_TESTER) --ignore-todo $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
78
+ $(SASS_TESTER) $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
79
79
 
80
80
  test_full:
81
- $(SASS_TESTER) $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
81
+ $(SASS_TESTER) --run-todo $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
82
82
 
83
- test_issues:
84
- $(SASS_TESTER) $(LOG_FLAGS) $(SASS_SPEC_PATH)/spec/issues $(SASS_TEST_FLAGS)
83
+ test_probe:
84
+ $(SASS_TESTER) --probe-todo $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
85
85
 
86
86
  endif
87
87
 
@@ -300,13 +300,16 @@ version: $(SASSC_BIN)
300
300
  $(SASSC_BIN) -v
301
301
 
302
302
  test: $(SASSC_BIN)
303
- $(RUBY_BIN) $(SASS_SPEC_PATH)/sass-spec.rb -c $(SASSC_BIN) -s $(LOG_FLAGS) $(SASS_SPEC_PATH)/$(SASS_SPEC_SPEC_DIR)
303
+ $(RUBY_BIN) $(SASS_SPEC_PATH)/sass-spec.rb -V 3.4 -c $(SASSC_BIN) --impl libsass $(LOG_FLAGS) $(SASS_SPEC_PATH)/$(SASS_SPEC_SPEC_DIR)
304
304
 
305
305
  test_build: $(SASSC_BIN)
306
- $(RUBY_BIN) $(SASS_SPEC_PATH)/sass-spec.rb -c $(SASSC_BIN) -s --ignore-todo $(LOG_FLAGS) $(SASS_SPEC_PATH)/$(SASS_SPEC_SPEC_DIR)
306
+ $(RUBY_BIN) $(SASS_SPEC_PATH)/sass-spec.rb -V 3.4 -c $(SASSC_BIN) --impl libsass $(LOG_FLAGS) $(SASS_SPEC_PATH)/$(SASS_SPEC_SPEC_DIR)
307
307
 
308
- test_issues: $(SASSC_BIN)
309
- $(RUBY_BIN) $(SASS_SPEC_PATH)/sass-spec.rb -c $(SASSC_BIN) $(LOG_FLAGS) $(SASS_SPEC_PATH)/spec/issues
308
+ test_full: $(SASSC_BIN)
309
+ $(RUBY_BIN) $(SASS_SPEC_PATH)/sass-spec.rb -V 3.4 -c $(SASSC_BIN) --impl libsass --run-todo $(LOG_FLAGS) $(SASS_SPEC_PATH)/$(SASS_SPEC_SPEC_DIR)
310
+
311
+ test_probe: $(SASSC_BIN)
312
+ $(RUBY_BIN) $(SASS_SPEC_PATH)/sass-spec.rb -V 3.4 -c $(SASSC_BIN) --impl libsass --probe-todo $(LOG_FLAGS) $(SASS_SPEC_PATH)/$(SASS_SPEC_SPEC_DIR)
310
313
 
311
314
  clean-objects: lib
312
315
  -$(RM) lib/*.a lib/*.so lib/*.dll lib/*.la
@@ -33,7 +33,6 @@ SOURCES = \
33
33
  sass_values.cpp \
34
34
  sass_context.cpp \
35
35
  sass_functions.cpp \
36
- sass_interface.cpp \
37
36
  sass2scss.cpp \
38
37
  source_map.cpp \
39
38
  to_c.cpp \
@@ -63,8 +63,11 @@ test_script:
63
63
  git -C sass-spec checkout -q --force ci-spec-pr-$SPEC_PR
64
64
  }
65
65
  }
66
- ruby sass-spec/sass-spec.rb -c $env:TargetPath -s --ignore-todo sass-spec/spec
67
-
66
+ ruby sass-spec/sass-spec.rb -V 3.4 --probe-todo --impl libsass -c $env:TargetPath -s sass-spec/spec
67
+ if(-not($?)) {
68
+ echo "sass-spec tests failed"
69
+ exit 1
70
+ }
68
71
  Write-Host "Explicitly testing the case when cwd has Cyrillic characters: " -nonewline
69
72
  # See comments in gh-1774 for details.
70
73
  $env:TargetPath = Join-Path $pwd.Path $env:TargetPath
@@ -76,3 +79,4 @@ test_script:
76
79
  } else {
77
80
  echo "Success!"
78
81
  }
82
+
@@ -88,7 +88,7 @@ char* source_map_file;
88
88
  char* source_map_root;
89
89
  ```
90
90
  ```C
91
- // Custom functions that can be called from sccs code
91
+ // Custom functions that can be called from Sass code
92
92
  Sass_C_Function_List c_functions;
93
93
  ```
94
94
  ```C
@@ -168,12 +168,12 @@ struct Sass_Compiler* sass_make_data_compiler (struct Sass_Data_Context* data_ct
168
168
 
169
169
  // Execute the different compilation steps individually
170
170
  // Usefull if you only want to query the included files
171
- int sass_compiler_parse(struct Sass_Compiler* compiler);
172
- int sass_compiler_execute(struct Sass_Compiler* compiler);
171
+ int sass_compiler_parse (struct Sass_Compiler* compiler);
172
+ int sass_compiler_execute (struct Sass_Compiler* compiler);
173
173
 
174
174
  // Release all memory allocated with the compiler
175
175
  // This does _not_ include any contexts or options
176
- void sass_delete_compiler(struct Sass_Compiler* compiler);
176
+ void sass_delete_compiler (struct Sass_Compiler* compiler);
177
177
 
178
178
  // Release all memory allocated and also ourself
179
179
  void sass_delete_file_context (struct Sass_File_Context* ctx);
@@ -16,16 +16,6 @@ This will automatically load all other headers too!
16
16
  #include "sass/context.h"
17
17
  ```
18
18
 
19
- ### Deprecated usage
20
-
21
- The old API is kept in the source for backward compatibility.
22
- It's deprecated and incompatible with this documentation, use `sass/context.h`!
23
-
24
- ```C
25
- // deprecated interface
26
- #include "sass/interface.h"
27
- ```
28
-
29
19
  ## Basic C Example
30
20
 
31
21
  ```C
@@ -33,7 +23,7 @@ It's deprecated and incompatible with this documentation, use `sass/context.h`!
33
23
  #include "sass/context.h"
34
24
 
35
25
  int main() {
36
- puts(libsass_VERSION());
26
+ puts(libsass_version());
37
27
  return 0;
38
28
  }
39
29
  ```
@@ -114,6 +104,34 @@ This mirrors very well how `libsass` uses these structures.
114
104
 
115
105
  Structs can be down-casted to access `context` or `options`!
116
106
 
107
+ ## Memory handling and life-cycles
108
+
109
+ We keep memory around for as long as the main [context](api-context.md) object is not destroyed (`sass_delete_context`). LibSass will create copies of most inputs/options beside the main sass code.
110
+ You need to allocate and fill that buffer before passing it to LibSass. You may also overtake memory management from libsass for certain return values (i.e. `sass_context_take_output_string`).
111
+
112
+ ```C
113
+ // to allocate buffer to be filled
114
+ void* sass_alloc_memory(size_t size);
115
+ // to allocate a buffer from existing string
116
+ char* sass_copy_c_string(const char* str);
117
+ // to free overtaken memory when done
118
+ void sass_free_memory(void* ptr);
119
+ ```
120
+
121
+ ## Miscellaneous API functions
122
+
123
+ ```C
124
+ // Some convenient string helper function
125
+ char* sass_string_unquote (const char* str);
126
+ char* sass_string_quote (const char* str, const char quote_mark);
127
+
128
+ // Resolve a file via the given include paths in the include char* array
129
+ char* sass_resolve_file (const char* path, const char* incs[]);
130
+
131
+ // Get compiled libsass version
132
+ const char* libsass_version(void);
133
+ ```
134
+
117
135
  ## Common Pitfalls
118
136
 
119
137
  **input_path**
@@ -10,10 +10,10 @@ Sass_Import_List sass_importer(const char* path, Sass_Importer_Entry cb, struct
10
10
  // get the cookie from importer descriptor
11
11
  void* cookie = sass_importer_get_cookie(cb);
12
12
  Sass_Import_List list = sass_make_import_list(2);
13
- const char* local = "local { color: green; }";
14
- const char* remote = "remote { color: red; }";
15
- list[0] = sass_make_import_entry("/tmp/styles.scss", strdup(local), 0);
16
- list[1] = sass_make_import_entry("http://www.example.com", strdup(remote), 0);
13
+ char* local = sass_copy_c_string("local { color: green; }");
14
+ char* remote = sass_copy_c_string("remote { color: red; }");
15
+ list[0] = sass_make_import_entry("/tmp/styles.scss", local, 0);
16
+ list[1] = sass_make_import_entry("http://www.example.com", remote, 0);
17
17
  return list;
18
18
  }
19
19
 
@@ -84,7 +84,7 @@ Sass_Import_List importer(const char* path, Sass_Importer_Entry cb, struct Sass_
84
84
  Sass_Import_List list = sass_make_import_list(1);
85
85
  const char* message = "some error message";
86
86
  list[0] = sass_make_import_entry(path, 0, 0);
87
- sass_import_set_error(list[0], strdup(message), 0, 0);
87
+ sass_import_set_error(list[0], sass_copy_c_string(message), 0, 0);
88
88
  return list;
89
89
  }
90
90
 
@@ -130,7 +130,7 @@ cd libsass
130
130
  REM set PATH=%PATH%;%PROGRAMFILES%\MSBuild\12.0\Bin
131
131
  msbuild /m:4 /p:Configuration=Release win\libsass.sln
132
132
  REM running the spec test-suite manually (needs ruby and minitest gem)
133
- ruby sass-spec\sass-spec.rb -c win\bin\sassc.exe -s --ignore-todo sass-spec/spec
133
+ ruby sass-spec\sass-spec.rb -V 3.4 -c win\bin\sassc.exe -s --impl libsass sass-spec/spec
134
134
  cd ..
135
135
  ```
136
136
 
@@ -62,6 +62,13 @@ enum Sass_Output_Style {
62
62
  SASS_STYLE_TO_SASS
63
63
  };
64
64
 
65
+ // to allocate buffer to be filled
66
+ void* sass_alloc_memory(size_t size);
67
+ // to allocate a buffer from existing string
68
+ char* sass_copy_c_string(const char* str);
69
+ // to free overtaken memory when done
70
+ void sass_free_memory(void* ptr);
71
+
65
72
  // Some convenient string helper function
66
73
  ADDAPI char* ADDCALL sass_string_quote (const char* str, const char quote_mark);
67
74
  ADDAPI char* ADDCALL sass_string_unquote (const char* str);
@@ -72,6 +79,9 @@ ADDAPI char* ADDCALL sass_resolve_file (const char* path, const char* incs[]);
72
79
  // Get compiled libsass version
73
80
  ADDAPI const char* ADDCALL libsass_version(void);
74
81
 
82
+ // Get compiled libsass language
83
+ ADDAPI const char* ADDCALL libsass_language_version(void);
84
+
75
85
  #ifdef __cplusplus
76
86
  } // __cplusplus defined.
77
87
  #endif
@@ -5,4 +5,8 @@
5
5
  #define LIBSASS_VERSION "[NA]"
6
6
  #endif
7
7
 
8
+ #ifndef LIBSASS_LANGUAGE_VERSION
9
+ #define LIBSASS_LANGUAGE_VERSION "[NA]"
10
+ #endif
11
+
8
12
  #endif
@@ -5,4 +5,8 @@
5
5
  #define LIBSASS_VERSION "@PACKAGE_VERSION@"
6
6
  #endif
7
7
 
8
+ #ifndef LIBSASS_LANGUAGE_VERSION
9
+ #define LIBSASS_LANGUAGE_VERSION "3.4"
10
+ #endif
11
+
8
12
  #endif
@@ -37,7 +37,7 @@
37
37
  #ifndef SASS2SCSS_VERSION
38
38
  // Hardcode once the file is copied from
39
39
  // https://github.com/mgreter/sass2scss
40
- #define SASS2SCSS_VERSION "1.0.5"
40
+ #define SASS2SCSS_VERSION "1.0.6"
41
41
  #endif
42
42
 
43
43
  // add namespace for c++
@@ -48,6 +48,18 @@ if [ "x$PREFIX" == "x" ]; then
48
48
  fi
49
49
  fi
50
50
 
51
+ # enable address sanitation
52
+ # https://en.wikipedia.org/wiki/AddressSanitizer
53
+ if [ "x$CC" == "xclang" ]; then
54
+ if [ "x$COVERAGE" != "xyes" ]; then
55
+ if [ "$TRAVIS_OS_NAME" == "linux" ]; then
56
+ export EXTRA_CFLAGS="$EXTRA_CFLAGS -fsanitize=address"
57
+ export EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -fsanitize=address"
58
+ export EXTRA_LDFLAGS="$EXTRA_LDFLAGS -fsanitize=address"
59
+ fi
60
+ fi
61
+ fi
62
+
51
63
  echo SASS_LIBSASS_PATH: $SASS_LIBSASS_PATH
52
64
  echo TRAVIS_BUILD_DIR: $TRAVIS_BUILD_DIR
53
65
  echo SASS_SASSC_PATH: $SASS_SASSC_PATH
@@ -108,10 +120,10 @@ then
108
120
  echo "Fetching Sass Spec PR $SPEC_PR"
109
121
  git -C sass-spec fetch -u origin pull/$SPEC_PR/head:ci-spec-pr-$SPEC_PR
110
122
  git -C sass-spec checkout --force ci-spec-pr-$SPEC_PR
111
- LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_build
123
+ LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_probe
112
124
  else
113
- LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_build
125
+ LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_probe
114
126
  fi
115
127
  else
116
- LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_build
128
+ LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_probe
117
129
  fi
@@ -7,8 +7,11 @@
7
7
  #include "color_maps.hpp"
8
8
  #include <set>
9
9
  #include <iomanip>
10
- #include <algorithm>
11
10
  #include <iostream>
11
+ #include <algorithm>
12
+ #include <functional>
13
+ #include <cctype>
14
+ #include <locale>
12
15
 
13
16
  namespace Sass {
14
17
 
@@ -25,6 +28,80 @@ namespace Sass {
25
28
  dynamic_cast<Supports_Operator*>(cond);
26
29
  }
27
30
 
31
+ std::string & str_ltrim(std::string & str)
32
+ {
33
+ auto it2 = std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
34
+ str.erase( str.begin() , it2);
35
+ return str;
36
+ }
37
+
38
+ std::string & str_rtrim(std::string & str)
39
+ {
40
+ auto it1 = std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
41
+ str.erase( it1.base() , str.end() );
42
+ return str;
43
+ }
44
+
45
+ void String_Constant::rtrim()
46
+ {
47
+ value_ = str_rtrim(value_);
48
+ }
49
+ void String_Constant::ltrim()
50
+ {
51
+ value_ = str_ltrim(value_);
52
+ }
53
+ void String_Constant::trim()
54
+ {
55
+ rtrim();
56
+ ltrim();
57
+ }
58
+
59
+ void String_Schema::rtrim()
60
+ {
61
+ if (!empty()) {
62
+ if (String* str = dynamic_cast<String*>(last())) str->rtrim();
63
+ }
64
+ }
65
+ void String_Schema::ltrim()
66
+ {
67
+ if (!empty()) {
68
+ if (String* str = dynamic_cast<String*>(first())) str->ltrim();
69
+ }
70
+ }
71
+ void String_Schema::trim()
72
+ {
73
+ rtrim();
74
+ ltrim();
75
+ }
76
+
77
+ bool At_Root_Query::exclude(std::string str)
78
+ {
79
+ bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
80
+ List* l = static_cast<List*>(value());
81
+ std::string v;
82
+
83
+ if (with)
84
+ {
85
+ if (!l || l->length() == 0) return str.compare("rule") != 0;
86
+ for (size_t i = 0, L = l->length(); i < L; ++i)
87
+ {
88
+ v = unquote((*l)[i]->to_string());
89
+ if (v.compare("all") == 0 || v == str) return false;
90
+ }
91
+ return true;
92
+ }
93
+ else
94
+ {
95
+ if (!l || !l->length()) return str.compare("rule") == 0;
96
+ for (size_t i = 0, L = l->length(); i < L; ++i)
97
+ {
98
+ v = unquote((*l)[i]->to_string());
99
+ if (v.compare("all") == 0 || v == str) return true;
100
+ }
101
+ return false;
102
+ }
103
+ }
104
+
28
105
  void AST_Node::update_pstate(const ParserState& pstate)
29
106
  {
30
107
  pstate_.offset += pstate - pstate_ + pstate.offset;
@@ -60,7 +137,7 @@ namespace Sass {
60
137
  bool Compound_Selector::has_parent_ref()
61
138
  {
62
139
  for (Simple_Selector* s : *this) {
63
- if (s->has_parent_ref()) return true;
140
+ if (s && s->has_parent_ref()) return true;
64
141
  }
65
142
  return false;
66
143
  }
@@ -209,6 +286,7 @@ namespace Sass {
209
286
 
210
287
  bool Simple_Selector::operator== (const Simple_Selector& rhs) const
211
288
  {
289
+ if (const Pseudo_Selector* lp = dynamic_cast<const Pseudo_Selector*>(this)) return *lp == rhs;
212
290
  if (const Wrapped_Selector* lw = dynamic_cast<const Wrapped_Selector*>(this)) return *lw == rhs;
213
291
  if (const Attribute_Selector* la = dynamic_cast<const Attribute_Selector*>(this)) return *la == rhs;
214
292
  if (is_ns_eq(ns(), rhs.ns()))
@@ -218,6 +296,7 @@ namespace Sass {
218
296
 
219
297
  bool Simple_Selector::operator< (const Simple_Selector& rhs) const
220
298
  {
299
+ if (const Pseudo_Selector* lp = dynamic_cast<const Pseudo_Selector*>(this)) return *lp == rhs;
221
300
  if (const Wrapped_Selector* lw = dynamic_cast<const Wrapped_Selector*>(this)) return *lw < rhs;
222
301
  if (const Attribute_Selector* la = dynamic_cast<const Attribute_Selector*>(this)) return *la < rhs;
223
302
  if (is_ns_eq(ns(), rhs.ns()))
@@ -481,6 +560,49 @@ namespace Sass {
481
560
  return ns() == rhs.ns();
482
561
  }
483
562
 
563
+ bool Pseudo_Selector::operator== (const Pseudo_Selector& rhs) const
564
+ {
565
+ if (is_ns_eq(ns(), rhs.ns()) && name() == rhs.name())
566
+ {
567
+ Expression* lhs_ex = expression();
568
+ Expression* rhs_ex = rhs.expression();
569
+ if (rhs_ex && lhs_ex) return *lhs_ex == *rhs_ex;
570
+ else return lhs_ex == rhs_ex;
571
+ }
572
+ else return false;
573
+ }
574
+
575
+ bool Pseudo_Selector::operator== (const Simple_Selector& rhs) const
576
+ {
577
+ if (const Pseudo_Selector* w = dynamic_cast<const Pseudo_Selector*>(&rhs))
578
+ {
579
+ return *this == *w;
580
+ }
581
+ if (is_ns_eq(ns(), rhs.ns()))
582
+ { return name() == rhs.name(); }
583
+ return ns() == rhs.ns();
584
+ }
585
+
586
+ bool Pseudo_Selector::operator< (const Pseudo_Selector& rhs) const
587
+ {
588
+ if (is_ns_eq(ns(), rhs.ns()) && name() == rhs.name())
589
+ { return *(expression()) < *(rhs.expression()); }
590
+ if (is_ns_eq(ns(), rhs.ns()))
591
+ { return name() < rhs.name(); }
592
+ return ns() < rhs.ns();
593
+ }
594
+
595
+ bool Pseudo_Selector::operator< (const Simple_Selector& rhs) const
596
+ {
597
+ if (const Pseudo_Selector* w = dynamic_cast<const Pseudo_Selector*>(&rhs))
598
+ {
599
+ return *this < *w;
600
+ }
601
+ if (is_ns_eq(ns(), rhs.ns()))
602
+ { return name() < rhs.name(); }
603
+ return ns() < rhs.ns();
604
+ }
605
+
484
606
  bool Wrapped_Selector::operator== (const Wrapped_Selector& rhs) const
485
607
  {
486
608
  if (is_ns_eq(ns(), rhs.ns()) && name() == rhs.name())
@@ -1230,10 +1352,12 @@ namespace Sass {
1230
1352
  if ((*this)[i]->head()->is_empty_reference()) {
1231
1353
  // simply move to the next tail if we have "no" combinator
1232
1354
  if ((*this)[i]->combinator() == Complex_Selector::ANCESTOR_OF) {
1233
- if ((*this)[i]->tail() && (*this)[i]->has_line_feed()) {
1234
- (*this)[i]->tail()->has_line_feed(true);
1355
+ if ((*this)[i]->tail() != NULL) {
1356
+ if ((*this)[i]->has_line_feed()) {
1357
+ (*this)[i]->tail()->has_line_feed(true);
1358
+ }
1359
+ (*this)[i] = (*this)[i]->tail();
1235
1360
  }
1236
- (*this)[i] = (*this)[i]->tail();
1237
1361
  }
1238
1362
  // otherwise remove the first item from head
1239
1363
  else {
@@ -1246,7 +1370,15 @@ namespace Sass {
1246
1370
  bool Selector_List::has_parent_ref()
1247
1371
  {
1248
1372
  for (Complex_Selector* s : *this) {
1249
- if (s->has_parent_ref()) return true;
1373
+ if (s && s->has_parent_ref()) return true;
1374
+ }
1375
+ return false;
1376
+ }
1377
+
1378
+ bool Selector_Schema::has_parent_ref()
1379
+ {
1380
+ if (String_Schema* schema = dynamic_cast<String_Schema*>(contents())) {
1381
+ return schema->length() > 0 && dynamic_cast<Parent_Selector*>(schema->at(0)) != NULL;
1250
1382
  }
1251
1383
  return false;
1252
1384
  }
@@ -2017,6 +2149,29 @@ namespace Sass {
2017
2149
  return is_interpolant() || (right() && right()->is_right_interpolant());
2018
2150
  }
2019
2151
 
2152
+ // delay binary expressions in function arguments
2153
+ // https://github.com/sass/libsass/issues/1417
2154
+ bool Binary_Expression::can_delay(void) const
2155
+ {
2156
+ bool l_delay = false;
2157
+ bool r_delay = false;
2158
+ if (op().operand == Sass_OP::DIV) {
2159
+ if (Textual* tl = dynamic_cast<Textual*>(left())) {
2160
+ l_delay = tl->type() == Textual::NUMBER ||
2161
+ tl->type() == Textual::DIMENSION;
2162
+ } else {
2163
+ l_delay = dynamic_cast<Number*>(left()) != NULL;
2164
+ }
2165
+ if (Textual* tr = dynamic_cast<Textual*>(right())) {
2166
+ r_delay = tr->type() == Textual::NUMBER ||
2167
+ tr->type() == Textual::DIMENSION;
2168
+ } else {
2169
+ r_delay = dynamic_cast<Number*>(right()) != NULL;
2170
+ }
2171
+ }
2172
+ return l_delay && r_delay;
2173
+ }
2174
+
2020
2175
  std::string AST_Node::to_string(Sass_Inspect_Options opt) const
2021
2176
  {
2022
2177
  Sass_Output_Options out(opt);