From 6cb8239f184a023f6cd2df9a2abaa32bd9d580f6 Mon Sep 17 00:00:00 2001 From: Carson Date: Wed, 11 Jan 2023 17:30:04 -0600 Subject: [PATCH] Upgrade libsass from 3.6.4 to 3.6.5 Closes #122 by way of https://github.com/sass/libsass/pull/3129 --- scripts/apply_libsass_patches.R | 11 +- .../patches/002-remove-libsass-tests.patch | 474 --------------- scripts/update_libsass.R | 2 +- .../.github/workflows/build-and-test.yml | 218 +++++++ src/libsass/.travis.yml | 70 --- src/libsass/Makefile | 5 +- src/libsass/Makefile.conf | 87 ++- src/libsass/Readme.md | 15 +- src/libsass/docs/build.md | 8 +- src/libsass/docs/implementations.md | 1 + src/libsass/script/ci-build-libsass | 6 +- src/libsass/script/ci-install-compiler | 10 +- src/libsass/src/ast.hpp | 6 +- src/libsass/src/ast_helpers.hpp | 26 +- src/libsass/src/ast_sel_unify.cpp | 2 +- src/libsass/src/ast_selectors.cpp | 33 +- src/libsass/src/ast_selectors.hpp | 17 +- src/libsass/src/ast_values.cpp | 4 +- src/libsass/src/error_handling.cpp | 6 + src/libsass/src/error_handling.hpp | 9 + src/libsass/src/extender.cpp | 74 ++- src/libsass/src/fn_numbers.cpp | 23 +- src/libsass/src/fn_selectors.cpp | 2 +- src/libsass/src/inspect.cpp | 11 +- src/libsass/src/lexer.cpp | 2 +- src/libsass/src/operators.cpp | 2 +- src/libsass/src/parser.cpp | 2 +- src/libsass/src/position.cpp | 16 +- src/libsass/src/sass_context.cpp | 1 + src/libsass/utils/README.md | 6 + .../utils/build-skeletons/libsass.targets | 8 + .../build-skeletons/libsass.vcxproj.filters | 20 + src/libsass/utils/update-builds.pl | 88 +++ src/libsass/win/libsass.targets | 126 ++-- src/libsass/win/libsass.vcxproj.filters | 563 +++++++++--------- 35 files changed, 984 insertions(+), 970 deletions(-) delete mode 100644 scripts/patches/002-remove-libsass-tests.patch create mode 100644 src/libsass/.github/workflows/build-and-test.yml delete mode 100644 src/libsass/.travis.yml create mode 100644 src/libsass/utils/README.md create mode 100644 src/libsass/utils/build-skeletons/libsass.targets create mode 100644 src/libsass/utils/build-skeletons/libsass.vcxproj.filters create mode 100644 src/libsass/utils/update-builds.pl diff --git a/scripts/apply_libsass_patches.R b/scripts/apply_libsass_patches.R index 3cd821ec..47cfe356 100644 --- a/scripts/apply_libsass_patches.R +++ b/scripts/apply_libsass_patches.R @@ -4,12 +4,19 @@ library(rprojroot) -patch_dir <- rprojroot::find_package_root_file("scripts/patches") +# Remove libsass test files (the entire `test` directory) since they contain unicode +# directory paths, and R CMD check provides a warning. +unlink( + find_package_root_file("src/libsass/test"), + recursive = TRUE +) + +patch_dir <- find_package_root_file("scripts/patches") for (patch in list.files(patch_dir, full.names = TRUE)) { tryCatch({ message(sprintf("Applying %s", basename(patch))) - system(sprintf("git apply '%s'", patch)) + system(sprintf("git apply --reject --whitespace=fix '%s'", patch)) }, error = function(e) { quit(save = "no", status = 1) diff --git a/scripts/patches/002-remove-libsass-tests.patch b/scripts/patches/002-remove-libsass-tests.patch deleted file mode 100644 index 3094d2c6..00000000 --- a/scripts/patches/002-remove-libsass-tests.patch +++ /dev/null @@ -1,474 +0,0 @@ -Remove libsass test files (the entire `test` directory) since they contain unicode -directory paths, and R CMD check provides a warning. - -diff --git a/src/libsass/test/Makefile b/src/libsass/test/Makefile -deleted file mode 100644 -index 0f9aa30..0000000 ---- a/src/libsass/test/Makefile -+++ /dev/null -@@ -1,24 +0,0 @@ --CXX ?= c++ --CXXFLAGS := -I ../include/ -std=c++11 -fsanitize=address -g -O1 -fno-omit-frame-pointer -- --test: test_shared_ptr test_util_string -- --test_shared_ptr: build/test_shared_ptr -- @ASAN_OPTIONS="symbolize=1" build/test_shared_ptr -- --test_util_string: build/test_util_string -- @ASAN_OPTIONS="symbolize=1" build/test_util_string -- --build: -- @mkdir build -- --build/test_shared_ptr: test_shared_ptr.cpp ../src/memory/shared_ptr.cpp | build -- $(CXX) $(CXXFLAGS) ../src/memory/allocator.cpp ../src/memory/shared_ptr.cpp -o build/test_shared_ptr test_shared_ptr.cpp -- --build/test_util_string: test_util_string.cpp ../src/util_string.cpp | build -- $(CXX) $(CXXFLAGS) ../src/memory/allocator.cpp ../src/util_string.cpp -o build/test_util_string test_util_string.cpp -- --clean: | build -- rm -rf build -- --.PHONY: test test_shared_ptr test_util_string clean -diff --git "a/src/libsass/test/e2e/unicode-pwd/S\303\241ss-U\305\242F8/input.scss" "b/src/libsass/test/e2e/unicode-pwd/S\303\241ss-U\305\242F8/input.scss" -deleted file mode 100644 -index 2d4b287..0000000 ---- "a/src/libsass/test/e2e/unicode-pwd/S\303\241ss-U\305\242F8/input.scss" -+++ /dev/null -@@ -1,3 +0,0 @@ --span.utf8-in-path { -- margin: auto; --} -diff --git "a/src/libsass/test/e2e/unicode-pwd/S\303\241ss-U\305\242F8/output.css" "b/src/libsass/test/e2e/unicode-pwd/S\303\241ss-U\305\242F8/output.css" -deleted file mode 100644 -index 2d4b287..0000000 ---- "a/src/libsass/test/e2e/unicode-pwd/S\303\241ss-U\305\242F8/output.css" -+++ /dev/null -@@ -1,3 +0,0 @@ --span.utf8-in-path { -- margin: auto; --} -diff --git a/src/libsass/test/go.mod b/src/libsass/test/go.mod -deleted file mode 100644 -index e69de29..0000000 -diff --git a/src/libsass/test/test_shared_ptr.cpp b/src/libsass/test/test_shared_ptr.cpp -deleted file mode 100644 -index 7355c1a..0000000 ---- a/src/libsass/test/test_shared_ptr.cpp -+++ /dev/null -@@ -1,191 +0,0 @@ --#include "../src/memory/allocator.hpp" --#include "../src/memory/shared_ptr.hpp" -- --#include --#include --#include --#include -- --#define ASSERT(cond) \ -- if (!(cond)) { \ -- std::cerr << "Assertion failed: " #cond " at " __FILE__ << ":" << __LINE__ << std::endl; \ -- return false; \ -- } \ -- --class TestObj : public Sass::SharedObj { -- public: -- TestObj(bool *destroyed) : destroyed_(destroyed) {} -- ~TestObj() { *destroyed_ = true; } -- Sass::sass::string to_string() const { -- Sass::sass::ostream result; -- result << "refcount=" << refcount << " destroyed=" << *destroyed_; -- return result.str(); -- } -- private: -- bool *destroyed_; --}; -- --using SharedTestObj = Sass::SharedImpl; -- --bool TestOneSharedPtr() { -- bool destroyed = false; -- { -- SharedTestObj a = SASS_MEMORY_NEW(TestObj, &destroyed); -- } -- ASSERT(destroyed); -- return true; --} -- --bool TestTwoSharedPtrs() { -- bool destroyed = false; -- { -- SharedTestObj a = SASS_MEMORY_NEW(TestObj, &destroyed); -- { -- SharedTestObj b = a; -- } -- ASSERT(!destroyed); -- } -- ASSERT(destroyed); -- return true; --} -- --bool TestSelfAssignment() { -- bool destroyed = false; -- { -- SharedTestObj a = SASS_MEMORY_NEW(TestObj, &destroyed); -- a = a; -- ASSERT(!destroyed); -- } -- ASSERT(destroyed); -- return true; --} -- --bool TestPointerAssignment() { -- bool destroyed = false; -- std::unique_ptr ptr(new TestObj(&destroyed)); -- { -- SharedTestObj a = ptr.get(); -- } -- ASSERT(destroyed); -- ptr.release(); -- return true; --} -- --bool TestOneSharedPtrDetach() { -- bool destroyed = false; -- std::unique_ptr ptr(new TestObj(&destroyed)); -- { -- SharedTestObj a = ptr.get(); -- a.detach(); -- } -- ASSERT(!destroyed); -- return true; --} -- --bool TestTwoSharedPtrsDetach() { -- bool destroyed = false; -- std::unique_ptr ptr(new TestObj(&destroyed)); -- { -- SharedTestObj a = ptr.get(); -- { -- SharedTestObj b = a; -- b.detach(); -- } -- ASSERT(!destroyed); -- a.detach(); -- } -- ASSERT(!destroyed); -- return true; --} -- --bool TestSelfAssignDetach() { -- bool destroyed = false; -- std::unique_ptr ptr(new TestObj(&destroyed)); -- { -- SharedTestObj a = ptr.get(); -- a = a.detach(); -- ASSERT(!destroyed); -- } -- ASSERT(destroyed); -- ptr.release(); -- return true; --} -- --bool TestDetachedPtrIsNotDestroyedUntilAssignment() { -- bool destroyed = false; -- std::unique_ptr ptr(new TestObj(&destroyed)); -- { -- SharedTestObj a = ptr.get(); -- SharedTestObj b = a; -- ASSERT(a.detach() == ptr.get()); -- ASSERT(!destroyed); -- } -- ASSERT(!destroyed); -- { -- SharedTestObj c = ptr.get(); -- ASSERT(!destroyed); -- } -- ASSERT(destroyed); -- ptr.release(); -- return true; --} -- --bool TestDetachNull() { -- SharedTestObj a; -- ASSERT(a.detach() == nullptr); -- return true; --} -- --class EmptyTestObj : public Sass::SharedObj { -- public: -- Sass::sass::string to_string() const { return ""; } --}; -- --bool TestComparisonWithSharedPtr() { -- Sass::SharedImpl a = new EmptyTestObj(); -- ASSERT(a == a); -- Sass::SharedImpl b = a; -- ASSERT(a == b); -- Sass::SharedImpl c = new EmptyTestObj(); -- ASSERT(a != c); -- Sass::SharedImpl nullobj; -- ASSERT(a != nullobj); -- ASSERT(nullobj == nullobj); -- return true; --} -- --bool TestComparisonWithNullptr() { -- Sass::SharedImpl a = new EmptyTestObj(); -- ASSERT(a != nullptr); -- Sass::SharedImpl nullobj; -- ASSERT(nullobj == nullptr); -- return true; --} -- --#define TEST(fn) \ -- if (fn()) { \ -- passed.push_back(#fn); \ -- } else { \ -- failed.push_back(#fn); \ -- std::cerr << "Failed: " #fn << std::endl; \ -- } \ -- --int main(int argc, char **argv) { -- std::vector passed; -- std::vector failed; -- TEST(TestOneSharedPtr); -- TEST(TestTwoSharedPtrs); -- TEST(TestSelfAssignment); -- TEST(TestPointerAssignment); -- TEST(TestOneSharedPtrDetach); -- TEST(TestTwoSharedPtrsDetach); -- TEST(TestSelfAssignDetach); -- TEST(TestDetachedPtrIsNotDestroyedUntilAssignment); -- TEST(TestDetachNull); -- TEST(TestComparisonWithSharedPtr); -- TEST(TestComparisonWithNullptr); -- std::cerr << argv[0] << ": Passed: " << passed.size() -- << ", failed: " << failed.size() -- << "." << std::endl; -- return failed.size(); --} -diff --git a/src/libsass/test/test_util_string.cpp b/src/libsass/test/test_util_string.cpp -deleted file mode 100644 -index a44e6e1..0000000 ---- a/src/libsass/test/test_util_string.cpp -+++ /dev/null -@@ -1,217 +0,0 @@ --#include "../src/util_string.hpp" -- --#include --#include --#include --#include -- --namespace { -- --Sass::sass::string escape_string(const Sass::sass::string& str) { -- Sass::sass::string out; -- out.reserve(str.size()); -- for (char c : str) { -- switch (c) { -- case '\n': -- out.append("\\n"); -- break; -- case '\r': -- out.append("\\r"); -- break; -- case '\f': -- out.append("\\f"); -- break; -- default: -- out += c; -- } -- } -- return out; --} -- --#define ASSERT_TRUE(cond) \ -- if (!cond) { \ -- std::cerr << \ -- "Expected condition to be true at " << __FILE__ << ":" << __LINE__ << \ -- std::endl; \ -- return false; \ -- } \ -- --#define ASSERT_FALSE(cond) \ -- ASSERT_TRUE(!(cond)) \ -- --#define ASSERT_STR_EQ(a, b) \ -- if (a != b) { \ -- std::cerr << \ -- "Expected LHS == RHS at " << __FILE__ << ":" << __LINE__ << \ -- "\n LHS: [" << escape_string(a) << "]" \ -- "\n RHS: [" << escape_string(b) << "]" << \ -- std::endl; \ -- return false; \ -- } \ -- --bool TestNormalizeNewlinesNoNewline() { -- Sass::sass::string input = "a"; -- Sass::sass::string normalized = Sass::Util::normalize_newlines(input); -- ASSERT_STR_EQ(input, normalized); -- return true; --} -- --bool TestNormalizeNewlinesLF() { -- Sass::sass::string input = "a\nb"; -- Sass::sass::string normalized = Sass::Util::normalize_newlines(input); -- ASSERT_STR_EQ(input, normalized); -- return true; --} -- --bool TestNormalizeNewlinesCR() { -- Sass::sass::string normalized = Sass::Util::normalize_newlines("a\rb"); -- ASSERT_STR_EQ("a\nb", normalized); -- return true; --} -- --bool TestNormalizeNewlinesCRLF() { -- Sass::sass::string normalized = Sass::Util::normalize_newlines("a\r\nb\r\n"); -- ASSERT_STR_EQ("a\nb\n", normalized); -- return true; --} -- --bool TestNormalizeNewlinesFF() { -- Sass::sass::string normalized = Sass::Util::normalize_newlines("a\fb\f"); -- ASSERT_STR_EQ("a\nb\n", normalized); -- return true; --} -- --bool TestNormalizeNewlinesMixed() { -- Sass::sass::string normalized = Sass::Util::normalize_newlines("a\fb\nc\rd\r\ne\ff"); -- ASSERT_STR_EQ("a\nb\nc\nd\ne\nf", normalized); -- return true; --} -- --bool TestNormalizeUnderscores() { -- Sass::sass::string normalized = Sass::Util::normalize_underscores("a_b_c"); -- ASSERT_STR_EQ("a-b-c", normalized); -- return true; --} -- --bool TestNormalizeDecimalsLeadingZero() { -- Sass::sass::string normalized = Sass::Util::normalize_decimals("0.5"); -- ASSERT_STR_EQ("0.5", normalized); -- return true; --} -- --bool TestNormalizeDecimalsNoLeadingZero() { -- Sass::sass::string normalized = Sass::Util::normalize_decimals(".5"); -- ASSERT_STR_EQ("0.5", normalized); -- return true; --} -- --bool testEqualsLiteral() { -- ASSERT_TRUE(Sass::Util::equalsLiteral("moz", "moz")); -- ASSERT_TRUE(Sass::Util::equalsLiteral(":moz", ":moz")); -- ASSERT_FALSE(Sass::Util::equalsLiteral("moz", ":moz")); -- ASSERT_FALSE(Sass::Util::equalsLiteral(":moz", "moz")); -- ASSERT_TRUE(Sass::Util::equalsLiteral("moz-foo", "MOZ-foo")); -- ASSERT_FALSE(Sass::Util::equalsLiteral("moz-foo", "moz_foo")); -- ASSERT_TRUE(Sass::Util::equalsLiteral("moz-foo", "MOZ-FOOS")); -- ASSERT_FALSE(Sass::Util::equalsLiteral("moz-foos", "moz-foo")); -- ASSERT_FALSE(Sass::Util::equalsLiteral("-moz-foo", "moz-foo")); -- return true; -- --} -- --bool TestUnvendor() { -- // Generated by using dart sass -- ASSERT_STR_EQ("moz", Sass::Util::unvendor("moz")); -- ASSERT_STR_EQ(":moz", Sass::Util::unvendor(":moz")); -- ASSERT_STR_EQ("-moz", Sass::Util::unvendor("-moz")); -- ASSERT_STR_EQ("--moz", Sass::Util::unvendor("--moz")); -- ASSERT_STR_EQ("moz-bar", Sass::Util::unvendor("moz-bar")); -- ASSERT_STR_EQ("bar", Sass::Util::unvendor("-moz-bar")); -- ASSERT_STR_EQ("bar-", Sass::Util::unvendor("-moz-bar-")); -- ASSERT_STR_EQ("--moz-bar", Sass::Util::unvendor("--moz-bar")); -- ASSERT_STR_EQ("-bar", Sass::Util::unvendor("-moz--bar")); -- ASSERT_STR_EQ("any", Sass::Util::unvendor("-s-any")); -- ASSERT_STR_EQ("any-more", Sass::Util::unvendor("-s-any-more")); -- ASSERT_STR_EQ("any--more", Sass::Util::unvendor("-s-any--more")); -- ASSERT_STR_EQ("--s-any--more", Sass::Util::unvendor("--s-any--more")); -- ASSERT_STR_EQ("s-any--more", Sass::Util::unvendor("s-any--more")); -- ASSERT_STR_EQ("_s_any_more", Sass::Util::unvendor("_s_any_more")); -- ASSERT_STR_EQ("more", Sass::Util::unvendor("-s_any-more")); -- ASSERT_STR_EQ("any_more", Sass::Util::unvendor("-s-any_more")); -- ASSERT_STR_EQ("_s_any_more", Sass::Util::unvendor("_s_any_more")); -- return true; --} -- --bool Test_ascii_str_to_lower() { -- Sass::sass::string str = "A B"; -- Sass::Util::ascii_str_tolower(&str); -- ASSERT_STR_EQ("a b", str); -- return true; --} -- --bool Test_ascii_str_to_upper() { -- Sass::sass::string str = "a b"; -- Sass::Util::ascii_str_toupper(&str); -- ASSERT_STR_EQ("A B", str); -- return true; --} -- --bool Test_ascii_isalpha() { -- ASSERT_TRUE(Sass::Util::ascii_isalpha('a')); -- ASSERT_FALSE(Sass::Util::ascii_isalpha('3')); -- return true; --} -- --bool Test_ascii_isxdigit() { -- ASSERT_TRUE(Sass::Util::ascii_isxdigit('a')); -- ASSERT_TRUE(Sass::Util::ascii_isxdigit('F')); -- ASSERT_TRUE(Sass::Util::ascii_isxdigit('3')); -- ASSERT_FALSE(Sass::Util::ascii_isxdigit('G')); -- return true; --} -- --bool Test_ascii_isspace() { -- ASSERT_TRUE(Sass::Util::ascii_isspace(' ')); -- ASSERT_TRUE(Sass::Util::ascii_isspace('\t')); -- ASSERT_TRUE(Sass::Util::ascii_isspace('\v')); -- ASSERT_TRUE(Sass::Util::ascii_isspace('\f')); -- ASSERT_TRUE(Sass::Util::ascii_isspace('\r')); -- ASSERT_TRUE(Sass::Util::ascii_isspace('\n')); -- ASSERT_FALSE(Sass::Util::ascii_isspace('G')); -- return true; --} -- --} // namespace -- --#define TEST(fn) \ -- if (fn()) { \ -- passed.push_back(#fn); \ -- } else { \ -- failed.push_back(#fn); \ -- std::cerr << "Failed: " #fn << std::endl; \ -- } \ -- --int main(int argc, char **argv) { -- std::vector passed; -- std::vector failed; -- TEST(TestNormalizeNewlinesNoNewline); -- TEST(TestNormalizeNewlinesLF); -- TEST(TestNormalizeNewlinesCR); -- TEST(TestNormalizeNewlinesCRLF); -- TEST(TestNormalizeNewlinesFF); -- TEST(TestNormalizeNewlinesMixed); -- TEST(TestNormalizeUnderscores); -- TEST(TestNormalizeDecimalsLeadingZero); -- TEST(TestNormalizeDecimalsNoLeadingZero); -- TEST(testEqualsLiteral); -- TEST(TestUnvendor); -- TEST(Test_ascii_str_to_lower); -- TEST(Test_ascii_str_to_upper); -- TEST(Test_ascii_isalpha); -- TEST(Test_ascii_isxdigit); -- TEST(Test_ascii_isspace); -- std::cerr << argv[0] << ": Passed: " << passed.size() -- << ", failed: " << failed.size() -- << "." << std::endl; -- return failed.size(); --} diff --git a/scripts/update_libsass.R b/scripts/update_libsass.R index c1268ba9..99f36c3e 100644 --- a/scripts/update_libsass.R +++ b/scripts/update_libsass.R @@ -9,7 +9,7 @@ ROOT <- rprojroot::find_package_root_file() setwd(ROOT) - LIBSASS_VERSION <- "3.6.4" + LIBSASS_VERSION <- "3.6.5" url <- sprintf( "https://github.com/sass/libsass/archive/%s.tar.gz", diff --git a/src/libsass/.github/workflows/build-and-test.yml b/src/libsass/.github/workflows/build-and-test.yml new file mode 100644 index 00000000..86975970 --- /dev/null +++ b/src/libsass/.github/workflows/build-and-test.yml @@ -0,0 +1,218 @@ +name: GitHub CI + +on: + push: + branches: + - master + - develop + pull_request: + branches: + - master + - develop + +jobs: + + linux-and-mac: + # if: ${{ false }} + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.os }} BUILD=${{ matrix.config.build }} CC=${{ matrix.config.cc }} CXX=${{ matrix.config.cxx }} AUTOTOOLS=${{ matrix.config.autotools }} + + strategy: + fail-fast: false + matrix: + config: + #- {os: ubuntu-16.04, build: 'static', cc: 'gcc-4.4', cxx: 'g++-4.4', autotools: 'no', cppstd: 'gnu++0x'} + #- {os: ubuntu-16.04, build: 'static', cc: 'gcc-4.6', cxx: 'g++-4.6', autotools: 'no', cppstd: 'gnu++0x'} + - {os: ubuntu-16.04, build: 'static', cc: 'gcc-4.7', cxx: 'g++-4.7', autotools: 'no', cppstd: 'gnu++11'} + - {os: ubuntu-16.04, build: 'static', cc: 'gcc-4.8', cxx: 'g++-4.8', autotools: 'no', cppstd: 'c++11'} + - {os: ubuntu-16.04, build: 'static', cc: 'gcc-5', cxx: 'g++-5', autotools: 'no', cppstd: 'c++11'} + - {os: ubuntu-16.04, build: 'static', cc: 'gcc-6', cxx: 'g++-6', autotools: 'no', cppstd: 'c++11'} + - {os: ubuntu-latest, build: 'static', cc: 'gcc-7', cxx: 'g++-7', autotools: 'no', cppstd: 'c++11'} + - {os: ubuntu-latest, build: 'shared', cc: 'gcc', cxx: 'g++', autotools: 'yes', cppstd: 'c++11'} + - {os: ubuntu-latest, build: 'static', cc: 'gcc', cxx: 'g++', autotools: 'yes', cppstd: 'c++11'} + - {os: ubuntu-latest, build: 'shared', cc: 'gcc', cxx: 'g++', autotools: 'no', cppstd: 'c++11'} + - {os: ubuntu-latest, build: 'static', cc: 'gcc', cxx: 'g++', autotools: 'no', cppstd: 'c++11'} + - {os: ubuntu-latest, build: 'shared', cc: 'clang', cxx: 'clang++', autotools: 'yes', cppstd: 'c++11'} + - {os: ubuntu-latest, build: 'static', cc: 'clang', cxx: 'clang++', autotools: 'yes', cppstd: 'c++11'} + - {os: ubuntu-latest, build: 'shared', cc: 'clang', cxx: 'clang++', autotools: 'no', cppstd: 'c++11'} + - {os: ubuntu-latest, build: 'static', cc: 'clang', cxx: 'clang++', autotools: 'no', cppstd: 'c++11'} + - {os: macOS-latest, build: 'shared', cc: 'clang', cxx: 'clang++', autotools: 'yes', cppstd: 'c++11'} + - {os: macOS-latest, build: 'static', cc: 'clang', cxx: 'clang++', autotools: 'yes', cppstd: 'c++11'} + - {os: macOS-latest, build: 'shared', cc: 'clang', cxx: 'clang++', autotools: 'no', cppstd: 'c++11'} + - {os: macOS-latest, build: 'static', cc: 'clang', cxx: 'clang++', autotools: 'no', cppstd: 'c++11'} + + env: + ASAN_OPTIONS: detect_odr_violation=0 + AUTOTOOLS: ${{ matrix.config.autotools }} + COVERAGE: no + BUILD: ${{ matrix.config.build }} + CXX: ${{ matrix.config.cxx }} + CC: ${{ matrix.config.cc }} + + steps: + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1 + if: matrix.config.os == 'ubuntu-16.04' + with: + ruby-version: 2.6 + - name: Install ruby hrx module + if: matrix.config.os == 'ubuntu-16.04' + run: sudo /opt/hostedtoolcache/Ruby/2.6.7/x64/bin/gem install hrx + - name: Install ruby minitest module + if: matrix.config.os == 'ubuntu-16.04' + run: sudo /opt/hostedtoolcache/Ruby/2.6.7/x64/bin/gem install minitest + - name: Install automake if needed (MacOS) + if: runner.os == 'macOS' + run: brew install automake + - name: Install gcc 7 if needed + if: matrix.config.cc == 'gcc-7' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt update + sudo apt install g++-7 -y + - name: Install gcc 6 if needed + if: matrix.config.cc == 'gcc-6' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt update + sudo apt install g++-6 -y + - name: Install gcc 5 if needed + if: matrix.config.cc == 'gcc-5' + run: | + sudo add-apt-repository universe + sudo add-apt-repository multiverse + sudo apt update + sudo apt install g++-5 -y + - name: Install gcc 4.8 if needed + if: matrix.config.cc == 'gcc-4.8' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt update + sudo apt install g++-4.8 -y + - name: Install gcc 4.7 if needed + if: matrix.config.cc == 'gcc-4.7' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt update + sudo apt install g++-4.7 -y + - name: Install gcc 4.6 if needed + if: matrix.config.cc == 'gcc-4.6' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt update + sudo apt install g++-4.6 -y + - name: Install gcc 4.5 if needed + if: matrix.config.cc == 'gcc-4.5' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt update + sudo apt install g++-4.5 -y + - name: Install gcc 4.4 if needed + if: matrix.config.cc == 'gcc-4.4' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt update + sudo apt install g++-4.4 -y + - name: ./script/ci-install-deps + env: + MAKE_OPTS: LIBSASS_CPPSTD=${{ matrix.config.cppstd }} + run: ./script/ci-install-deps + - name: ./script/ci-install-compiler + env: + MAKE_OPTS: LIBSASS_CPPSTD=${{ matrix.config.cppstd }} + run: ./script/ci-install-compiler + - name: ./script/ci-build-libsass + env: + MAKE_OPTS: LIBSASS_CPPSTD=${{ matrix.config.cppstd }} + run: ./script/ci-build-libsass + + + windows-msvc: + runs-on: windows-latest + name: Windows MSVC build + + strategy: + fail-fast: false + matrix: + config: + - {build: Release, platform: Win64} + - {build: Debug, platform: Win64} + - {build: Release, platform: Win32} + - {build: Debug, platform: Win32} + + steps: + - name: Change git config to preserve line-endings + run: | + git config --system core.autocrlf false + git config --system core.eol lf + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + bundler-cache: true + - name: Install ruby hrx module + run: gem install hrx + - name: Install ruby minitest module + run: gem install minitest + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + - name: Clone and checkout sassc repository + run: git clone https://github.com/sass/sassc.git + - name: Clone and checkout sass-spec repository + run: git clone https://github.com/sass/sass-spec.git + - name: Compile libsass ${{ matrix.config.build }} build for ${{ matrix.config.platform }} + run: msbuild /m:4 /p:"Configuration=${{ matrix.config.build }};Platform=${{ matrix.config.platform }}" sassc\win\sassc.sln + - name: Execute spec test runner + run: ruby sass-spec/sass-spec.rb --probe-todo --impl libsass -c sassc/bin/sassc.exe -s sass-spec/spec + + windows-mingw: + runs-on: windows-latest + name: Windows MinGW build + + strategy: + fail-fast: false + matrix: + config: + - {build: shared, platform: x64} + - {build: static, platform: x64} + - {build: shared, platform: x86} + - {build: static, platform: x86} + + steps: + - name: Change git config to preserve line-endings + run: | + git config --system core.autocrlf false + git config --system core.eol lf + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + bundler-cache: true + - name: Set up MinGW + uses: egor-tensin/setup-mingw@v2 + with: + platform: ${{ matrix.config.platform }} + - name: Install ruby hrx module + run: gem install hrx + - name: Install ruby minitest module + run: gem install minitest + - name: Clone and checkout sassc repository + run: git clone https://github.com/sass/sassc.git + - name: Clone and checkout sass-spec repository + run: git clone https://github.com/sass/sass-spec.git + - name: Add libsass library path to be found + if: matrix.config.build == 'shared' + run: echo "/d/a/libsass/libsass/lib" >> $GITHUB_PATH + - name: Compile libsass ${{ matrix.config.build }} build for ${{ matrix.config.platform }} + run: make ${{ matrix.config.build }} BUILD=${{ matrix.config.build }} + - name: Copy library over to pass call test + if: matrix.config.build == 'shared' + run: copy /a/libsass/libsass/lib/libsass.dll sassc/bin/ + - name: Compile sassc ${{ matrix.config.build }} build for ${{ matrix.config.platform }} + run: make sassc BUILD=${{ matrix.config.build }} + - name: Execute spec test runner + run: ruby sass-spec/sass-spec.rb --probe-todo --impl libsass -c sassc/bin/sassc.exe -s sass-spec/spec + + +#- name: Install LLVM and Clang +# uses: KyleMayes/install-llvm-action@v1.2.2 diff --git a/src/libsass/.travis.yml b/src/libsass/.travis.yml deleted file mode 100644 index d2a0ca0f..00000000 --- a/src/libsass/.travis.yml +++ /dev/null @@ -1,70 +0,0 @@ -language: cpp - -# ASan needs ptrace support which currently requires `sudo: required`. -# See https://github.com/travis-ci/travis-ci/issues/9033. -sudo: required - -# don't create redundant code coverage reports -# - AUTOTOOLS=yes COVERAGE=yes BUILD=static -# - AUTOTOOLS=no COVERAGE=yes BUILD=shared -# - AUTOTOOLS=no COVERAGE=no BUILD=static - -# further speed up day by day travis-ci builds -# re-enable this if you change the makefiles -# this will still catch all coding errors! -# - AUTOTOOLS=yes COVERAGE=no BUILD=static - -# currently there are various issues when -# built with coverage, clang and autotools -# - AUTOTOOLS=yes COVERAGE=yes BUILD=shared - -matrix: - include : - - os: linux - compiler: gcc - env: AUTOTOOLS=no COVERAGE=yes BUILD=static - - os: linux - compiler: g++-5 - env: AUTOTOOLS=yes COVERAGE=no BUILD=shared - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-5 - - os: linux - compiler: g++-8 - env: AUTOTOOLS=yes COVERAGE=no BUILD=shared - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-8 - - os: linux - compiler: clang - # This build runs with ASan and we set `detect_odr_violation=0` - # to work around https://bugs.llvm.org/show_bug.cgi?id=37545. - env: AUTOTOOLS=no COVERAGE=no BUILD=static ASAN_OPTIONS=detect_odr_violation=0 - - os: linux - compiler: clang - env: AUTOTOOLS=yes COVERAGE=no BUILD=shared - - os: osx - compiler: clang - env: AUTOTOOLS=no COVERAGE=no BUILD=shared - - os: osx - compiler: clang - env: AUTOTOOLS=no COVERAGE=no BUILD=static - - os: osx - compiler: clang - env: AUTOTOOLS=yes COVERAGE=no BUILD=shared - -script: - - ./script/ci-build-libsass - - ./script/ci-build-plugin math - - ./script/ci-build-plugin glob - - ./script/ci-build-plugin digest - - ./script/ci-build-plugin tests -before_install: ./script/ci-install-deps -install: ./script/ci-install-compiler -after_success: ./script/ci-report-coverage diff --git a/src/libsass/Makefile b/src/libsass/Makefile index 2ad16502..6f81feb1 100644 --- a/src/libsass/Makefile +++ b/src/libsass/Makefile @@ -57,8 +57,9 @@ ifdef LIBSASS_VERSION CXXFLAGS += -DLIBSASS_VERSION="\"$(LIBSASS_VERSION)\"" endif -CXXFLAGS += -std=c++11 -LDFLAGS += -std=c++11 +LIBSASS_CPPSTD ?= c++11 +CXXFLAGS += -std=$(LIBSASS_CPPSTD) +LDFLAGS += -std=$(LIBSASS_CPPSTD) ifeq (Windows,$(UNAME)) ifneq ($(BUILD),shared) diff --git a/src/libsass/Makefile.conf b/src/libsass/Makefile.conf index 49298703..679e36cc 100644 --- a/src/libsass/Makefile.conf +++ b/src/libsass/Makefile.conf @@ -5,6 +5,90 @@ # heavy RAM usage peaks. Other than that the order is arbitrary. +INCFILES = \ + sass.h \ + sass2scss.h \ + sass/base.h \ + sass/context.h \ + sass/functions.h \ + sass/values.h \ + sass/version.h + +HPPFILES = \ + ast.hpp \ + ast2c.hpp \ + ast_def_macros.hpp \ + ast_fwd_decl.hpp \ + ast_helpers.hpp \ + ast_selectors.hpp \ + ast_supports.hpp \ + ast_values.hpp \ + backtrace.hpp \ + base64vlq.hpp \ + bind.hpp \ + c2ast.hpp \ + check_nesting.hpp \ + color_maps.hpp \ + constants.hpp \ + context.hpp \ + cssize.hpp \ + dart_helpers.hpp \ + debug.hpp \ + debugger.hpp \ + emitter.hpp \ + environment.hpp \ + error_handling.hpp \ + eval.hpp \ + expand.hpp \ + extender.hpp \ + extension.hpp \ + file.hpp \ + fn_colors.hpp \ + fn_lists.hpp \ + fn_maps.hpp \ + fn_miscs.hpp \ + fn_numbers.hpp \ + fn_selectors.hpp \ + fn_strings.hpp \ + fn_utils.hpp \ + inspect.hpp \ + json.hpp \ + kwd_arg_macros.hpp \ + lexer.hpp \ + listize.hpp \ + mapping.hpp \ + memory.hpp \ + MurmurHash2.hpp \ + operation.hpp \ + operators.hpp \ + ordered_map.hpp \ + output.hpp \ + parser.hpp \ + permutate.hpp \ + plugins.hpp \ + position.hpp \ + prelexer.hpp \ + remove_placeholders.hpp \ + sass.hpp \ + sass_context.hpp \ + sass_functions.hpp \ + sass_values.hpp \ + settings.hpp \ + source.hpp \ + source_data.hpp \ + source_map.hpp \ + stylesheet.hpp \ + to_value.hpp \ + units.hpp \ + utf8_string.hpp \ + util.hpp \ + util_string.hpp \ + values.hpp \ + memory/allocator.hpp \ + memory/config.hpp \ + memory/memory_pool.hpp \ + memory/shared_ptr.hpp + SOURCES = \ ast.cpp \ ast_values.cpp \ @@ -71,4 +155,5 @@ SOURCES = \ utf8_string.cpp \ base64vlq.cpp -CSOURCES = cencode.c +CSOURCES = \ + cencode.c diff --git a/src/libsass/Readme.md b/src/libsass/Readme.md index b18f78e0..2d1a1d46 100644 --- a/src/libsass/Readme.md +++ b/src/libsass/Readme.md @@ -1,17 +1,22 @@ LibSass - Sass compiler written in C++ ====================================== -Currently maintained by Marcel Greter ([@mgreter]) and Michael Mifsud ([@xzyfer]) +Currently maintained by Marcel Greter ([@mgreter]) and Michael Mifsud ([@xzyfer]) Originally created by Aaron Leung ([@akhleung]) and Hampton Catlin ([@hcatlin]) -[![Unix CI](https://travis-ci.org/sass/libsass.svg?branch=master)](https://travis-ci.org/sass/libsass "Travis CI") +[![GitHub CI](https://github.com/sass/libsass/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/sass/libsass/actions/workflows/build-and-test.yml "GitHub CI") [![Windows CI](https://ci.appveyor.com/api/projects/status/github/sass/libsass?svg=true)](https://ci.appveyor.com/project/sass/libsass/branch/master "Appveyor CI") -[![Coverage Status](https://img.shields.io/coveralls/sass/libsass.svg)](https://coveralls.io/r/sass/libsass?branch=feature%2Ftest-travis-ci-3 "Code coverage of spec tests") +[![Coverage Status](https://img.shields.io/coveralls/sass/libsass.svg)](https://coveralls.io/r/sass/libsass?branch=master "Code coverage of spec tests") [![Percentage of issues still open](http://isitmaintained.com/badge/open/sass/libsass.svg)](http://isitmaintained.com/project/sass/libsass "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/sass/libsass.svg)](http://isitmaintained.com/project/sass/libsass "Average time to resolve an issue") [![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=283068)](https://www.bountysource.com/trackers/283068-libsass?utm_source=283068&utm_medium=shield&utm_campaign=TRACKER_BADGE "Bountysource") [![Join us](https://libsass-slack.herokuapp.com/badge.svg)](https://libsass-slack.herokuapp.com/ "Slack communication channels") +**Warning:** [LibSass is deprecated](https://sass-lang.com/blog/libsass-is-deprecated). +While it will continue to receive maintenance releases indefinitely, there are no +plans to add additional features or compatibility with any new CSS or Sass features. +Projects that still use it should move onto +[Dart Sass](https://sass-lang.com/dart-sass). [LibSass](https://github.com/sass/libsass "LibSass GitHub Project") is just a library! If you want to use LibSass to compile Sass, you need an implementer. Some @@ -30,8 +35,10 @@ CLI tool built by the same people as LibSass. - https://github.com/sass/libsass-net (C#) - https://github.com/medialize/sass.js (JS) - https://github.com/bit3/jsass (Java) +- https://github.com/scottdavis/sass.ex (Elixir) +- https://github.com/Youimmi/sass_compiler (Elixir) -This list does not say anything about the quality of either the listed or not listed [implementations](docs/implementations.md)! +This list does not say anything about the quality of either the listed or not listed [implementations](docs/implementations.md)! The authors of the listed projects above are just known to work regularly together with LibSass developers. About diff --git a/src/libsass/docs/build.md b/src/libsass/docs/build.md index c656d883..531480aa 100644 --- a/src/libsass/docs/build.md +++ b/src/libsass/docs/build.md @@ -69,10 +69,10 @@ Continuous Integration We use two CI services to automatically test all commits against the latest [spec test-suite][5]. -- [LibSass on Travis-CI (linux)][7] -[![Build Status](https://travis-ci.org/sass/libsass.png?branch=master)](https://travis-ci.org/sass/libsass) +- [LibSass on GitHub Actions (linux)][7] +[![Build Status](https://github.com/sass/libsass/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/sass/libsass/actions/workflows/build-and-test.yml) - [LibSass on AppVeyor (windows)][8] -[![Build status](https://ci.appveyor.com/api/projects/status/github/sass/libsass?svg=true)](https://ci.appveyor.com/project/mgreter/libsass-513/branch/master) +[![Build status](https://ci.appveyor.com/api/projects/status/github/sass/libsass?svg=true)](https://ci.appveyor.com/project/sass/libsass/branch/master) Why not using CMake? -- @@ -90,7 +90,7 @@ Miscellaneous [4]: build-shared-library.md [5]: https://github.com/sass/sass-spec [6]: https://github.com/sass/sassc -[7]: https://github.com/sass/libsass/blob/master/.travis.yml +[7]: https://github.com/sass/libsass/blob/master/.github/workflows [8]: https://github.com/sass/libsass/blob/master/appveyor.yml [9]: implementations.md [10]: build-on-darwin.md diff --git a/src/libsass/docs/implementations.md b/src/libsass/docs/implementations.md index 942e2de0..95febc14 100644 --- a/src/libsass/docs/implementations.md +++ b/src/libsass/docs/implementations.md @@ -8,6 +8,7 @@ There are several implementations of `libsass` for a variety of languages. Here ### Elixir * [sass.ex](https://github.com/scottdavis/sass.ex) +* [sass_compiler](https://github.com/Youimmi/sass_compiler) ### Go * [go-libsass](https://github.com/wellington/go-libsass) diff --git a/src/libsass/script/ci-build-libsass b/src/libsass/script/ci-build-libsass index d4ade4eb..84f25e00 100755 --- a/src/libsass/script/ci-build-libsass +++ b/src/libsass/script/ci-build-libsass @@ -4,6 +4,8 @@ set -e script/bootstrap +echo Building LibSass $MAKE_OPTS + # export this path right here (was in script/spec before) export SASS_LIBSASS_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../ && pwd )" @@ -90,8 +92,8 @@ else make $MAKE_OPTS clean # Run C++ unit tests - make -C test clean - make -C test test + make $MAKE_OPTS -C test clean + make $MAKE_OPTS -C test test fi diff --git a/src/libsass/script/ci-install-compiler b/src/libsass/script/ci-install-compiler index 30505a54..bccc75ae 100755 --- a/src/libsass/script/ci-install-compiler +++ b/src/libsass/script/ci-install-compiler @@ -1,8 +1,8 @@ #!/bin/bash -gem install minitest -gem install minitap -gem install rspec -gem install hrx +sudo gem install minitest +sudo gem install minitap +sudo gem install rspec +sudo gem install hrx -pip2 install --user 'requests[security]' +# sudo pip2 install --user 'requests[security]' diff --git a/src/libsass/src/ast.hpp b/src/libsass/src/ast.hpp index c3b1e3ba..e7dcaf65 100644 --- a/src/libsass/src/ast.hpp +++ b/src/libsass/src/ast.hpp @@ -358,7 +358,7 @@ namespace Sass { class Hashed { private: std::unordered_map< - K, T, ObjHash, ObjEquality + K, T, ObjHash, ObjHashEquality > elements_; sass::vector _keys; @@ -396,7 +396,7 @@ namespace Sass { bool has_duplicate_key() const { return duplicate_key_ != nullptr; } K get_duplicate_key() const { return duplicate_key_; } const std::unordered_map< - K, T, ObjHash, ObjEquality + K, T, ObjHash, ObjHashEquality >& elements() { return elements_; } Hashed& operator<<(std::pair p) { @@ -432,7 +432,7 @@ namespace Sass { return *this; } const std::unordered_map< - K, T, ObjHash, ObjEquality + K, T, ObjHash, ObjHashEquality >& pairs() const { return elements_; } const sass::vector& keys() const { return _keys; } diff --git a/src/libsass/src/ast_helpers.hpp b/src/libsass/src/ast_helpers.hpp index b4c4522d..da8f85fe 100644 --- a/src/libsass/src/ast_helpers.hpp +++ b/src/libsass/src/ast_helpers.hpp @@ -61,7 +61,7 @@ namespace Sass { // Implement compare and hashing operations for AST Nodes // ########################################################################### - // TODO: get rid of funtions and use ObjEquality + // TODO: get rid of functions and use ObjEquality template // Hash the raw pointer instead of object @@ -149,6 +149,30 @@ namespace Sass { } }; + // ########################################################################### + // Special compare function only for hashes. + // We need to make sure to not have objects equal that + // have different hashes. This is currently an issue, + // since `1px` is equal to `1` but have different hashes. + // This goes away once we remove unitless equality. + // ########################################################################### + + template + // Compare the objects and its hashes + bool ObjHashEqualityFn(const T& lhs, const T& rhs) { + if (lhs == nullptr) return rhs == nullptr; + else if (rhs == nullptr) return false; + else return lhs->hash() == rhs->hash(); + } + struct ObjHashEquality { + template + // Compare the objects and its contents and hashes + bool operator() (const T& lhs, const T& rhs) const { + return ObjEqualityFn(lhs, rhs) && + ObjHashEqualityFn(lhs, rhs); + } + }; + // ########################################################################### // Implement ordering operations for AST Nodes // ########################################################################### diff --git a/src/libsass/src/ast_sel_unify.cpp b/src/libsass/src/ast_sel_unify.cpp index c6a2b397..31e151e7 100644 --- a/src/libsass/src/ast_sel_unify.cpp +++ b/src/libsass/src/ast_sel_unify.cpp @@ -20,7 +20,7 @@ namespace Sass { SASS_ASSERT(!complexes.empty(), "Can't unify empty list"); if (complexes.size() == 1) return complexes; - CompoundSelectorObj unifiedBase = SASS_MEMORY_NEW(CompoundSelector, SourceSpan("[phony]")); + CompoundSelectorObj unifiedBase = SASS_MEMORY_NEW(CompoundSelector, SourceSpan("[unify]")); for (auto complex : complexes) { SelectorComponentObj base = complex.back(); if (CompoundSelector * comp = base->getCompound()) { diff --git a/src/libsass/src/ast_selectors.cpp b/src/libsass/src/ast_selectors.cpp index 64c9a491..c1428429 100644 --- a/src/libsass/src/ast_selectors.cpp +++ b/src/libsass/src/ast_selectors.cpp @@ -433,6 +433,16 @@ namespace Sass { return false; } + bool ComplexSelector::isInvalidCss() const + { + for (size_t i = 0; i < length(); i += 1) { + if (CompoundSelectorObj compound = get(i)->getCompound()) { + if (compound->isInvalidCss()) return true; + } + } + return false; + } + SelectorListObj ComplexSelector::wrapInList() { SelectorListObj selector = @@ -525,15 +535,13 @@ namespace Sass { CompoundSelector::CompoundSelector(SourceSpan pstate, bool postLineBreak) : SelectorComponent(pstate, postLineBreak), Vectorized(), - hasRealParent_(false), - extended_(false) + hasRealParent_(false) { } CompoundSelector::CompoundSelector(const CompoundSelector* ptr) : SelectorComponent(ptr), Vectorized(*ptr), - hasRealParent_(ptr->hasRealParent()), - extended_(ptr->extended()) + hasRealParent_(ptr->hasRealParent()) { } size_t CompoundSelector::hash() const @@ -950,6 +958,23 @@ namespace Sass { std::sort(begin(), end(), cmpSimpleSelectors); } + bool CompoundSelector::isInvalidCss() const + { + size_t current = 0, next = 0; + for (const SimpleSelector* sel : elements()) { + next = sel->getSortOrder(); + // Must only have one type selector + if (current == 1 && next == 1) { + return true; + } + if (next < current) { + return true; + } + current = next; + } + return false; + } + /* better return sass::vector? only - is empty container anyway? */ SelectorList* ComplexSelector::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent) { diff --git a/src/libsass/src/ast_selectors.hpp b/src/libsass/src/ast_selectors.hpp index 6c793d7b..bdc25b44 100644 --- a/src/libsass/src/ast_selectors.hpp +++ b/src/libsass/src/ast_selectors.hpp @@ -182,7 +182,7 @@ namespace Sass { class ClassSelector final : public SimpleSelector { public: ClassSelector(SourceSpan pstate, sass::string n); - int getSortOrder() const override final { return 3; } + int getSortOrder() const override final { return 2; } virtual unsigned long specificity() const override; bool operator==(const SimpleSelector& rhs) const final override; ATTACH_CMP_OPERATIONS(ClassSelector) @@ -216,7 +216,7 @@ namespace Sass { ADD_PROPERTY(char, modifier); public: AttributeSelector(SourceSpan pstate, sass::string n, sass::string m, String_Obj v, char o = 0); - int getSortOrder() const override final { return 4; } + int getSortOrder() const override final { return 2; } size_t hash() const override; virtual unsigned long specificity() const override; bool operator==(const SimpleSelector& rhs) const final override; @@ -237,7 +237,7 @@ namespace Sass { ADD_PROPERTY(bool, isClass) public: PseudoSelector(SourceSpan pstate, sass::string n, bool element = false); - int getSortOrder() const override final { return 5; } + int getSortOrder() const override final { return 3; } virtual bool is_pseudo_element() const override; size_t hash() const override; @@ -273,16 +273,17 @@ namespace Sass { // Between each item there is an implicit ancestor of combinator //////////////////////////////////////////////////////////////////////////// class ComplexSelector final : public Selector, public Vectorized { - ADD_PROPERTY(bool, chroots) + ADD_PROPERTY(bool, chroots); // line break before list separator - ADD_PROPERTY(bool, hasPreLineFeed) + ADD_PROPERTY(bool, hasPreLineFeed); public: ComplexSelector(SourceSpan pstate); // Returns true if the first components - // is a compound selector and fullfills + // is a compound selector and fulfills // a few other criteria. bool isInvisible() const; + bool isInvalidCss() const; size_t hash() const override; void cloneChildren() override; @@ -413,12 +414,11 @@ namespace Sass { //////////////////////////////////////////////////////////////////////////// class CompoundSelector final : public SelectorComponent, public Vectorized { ADD_PROPERTY(bool, hasRealParent) - ADD_PROPERTY(bool, extended) public: CompoundSelector(SourceSpan pstate, bool postLineBreak = false); // Returns true if this compound selector - // fullfills various criteria. + // fulfills various criteria. bool isInvisible() const; bool empty() const override { @@ -454,6 +454,7 @@ namespace Sass { bool operator==(const SimpleSelector& rhs) const; void sortChildren(); + bool isInvalidCss() const; ATTACH_CMP_OPERATIONS(CompoundSelector) ATTACH_AST_OPERATIONS(CompoundSelector) diff --git a/src/libsass/src/ast_values.cpp b/src/libsass/src/ast_values.cpp index 4fc3516c..fccb0967 100644 --- a/src/libsass/src/ast_values.cpp +++ b/src/libsass/src/ast_values.cpp @@ -481,9 +481,9 @@ namespace Sass { { if (hash_ == 0) { hash_ = std::hash()(value_); - for (const auto numerator : numerators) + for (const auto& numerator : numerators) hash_combine(hash_, std::hash()(numerator)); - for (const auto denominator : denominators) + for (const auto& denominator : denominators) hash_combine(hash_, std::hash()(denominator)); } return hash_; diff --git a/src/libsass/src/error_handling.cpp b/src/libsass/src/error_handling.cpp index d96fe529..8fc840e6 100644 --- a/src/libsass/src/error_handling.cpp +++ b/src/libsass/src/error_handling.cpp @@ -84,6 +84,12 @@ namespace Sass { msg = "stack level too deep"; } + EndlessExtendError::EndlessExtendError(Backtraces traces, const AST_Node& node) + : Base(node.pstate(), def_msg, traces), node(node) + { + msg = "Extend is creating an absurdly big selector, aborting!"; + } + IncompatibleUnits::IncompatibleUnits(const Units& lhs, const Units& rhs) { msg = "Incompatible units: '" + rhs.unit() + "' and '" + lhs.unit() + "'."; diff --git a/src/libsass/src/error_handling.hpp b/src/libsass/src/error_handling.hpp index a7e8efc8..8fd5fdab 100644 --- a/src/libsass/src/error_handling.hpp +++ b/src/libsass/src/error_handling.hpp @@ -134,6 +134,15 @@ namespace Sass { virtual ~StackError() throw() {}; }; + class EndlessExtendError : public Base { + protected: + const AST_Node& node; + public: + EndlessExtendError(Backtraces traces, const AST_Node& node); + virtual const char* errtype() const { return "EndlessExtendError"; } + virtual ~EndlessExtendError() throw() {}; + }; + /* common virtual base class (has no pstate or trace) */ class OperationError : public std::runtime_error { protected: diff --git a/src/libsass/src/extender.cpp b/src/libsass/src/extender.cpp index 8b0fd127..95eece17 100644 --- a/src/libsass/src/extender.cpp +++ b/src/libsass/src/extender.cpp @@ -228,8 +228,8 @@ namespace Sass { // EO registerSelector // ########################################################################## - // Returns an extension that combines [left] and [right]. Throws - // a [SassException] if [left] and [right] have incompatible + // Returns an extension that combines [left] and [right]. Throws + // a [SassException] if [left] and [right] have incompatible // media contexts. Throws an [ArgumentError] if [left] // and [right] don't have the same extender and target. // ########################################################################## @@ -281,7 +281,7 @@ namespace Sass { // ########################################################################## // Adds an extension to this extender. The [extender] is the selector for the // style rule in which the extension is defined, and [target] is the selector - // passed to `@extend`. The [extend] provides the extend span and indicates + // passed to `@extend`. The [extend] provides the extend span and indicates // whether the extension is optional. The [mediaContext] defines the media query // context in which the extension is defined. It can only extend selectors // within the same context. A `null` context indicates no media queries. @@ -353,7 +353,7 @@ namespace Sass { ExtSelExtMap newExtensionsByTarget; newExtensionsByTarget.insert(std::make_pair(target, newExtensions)); - // ToDo: do we really need to fetch again (see top off fn) + // ToDo: do we really need to fetch again (see top off fn) auto existingExtensions = extensionsByExtender.find(target); if (existingExtensions != extensionsByExtender.end()) { if (hasExistingExtensions && !existingExtensions->second.empty()) { @@ -373,7 +373,7 @@ namespace Sass { } // EO addExtension - + // ########################################################################## // Extend [extensions] using [newExtensions]. // ########################################################################## @@ -446,7 +446,7 @@ namespace Sass { bool first = false, containsExtension = ObjEqualityFn(selectors.front(), extension.extender); for (const ComplexSelectorObj& complex : selectors) { - // If the output contains the original complex + // If the output contains the original complex // selector, there's no need to recreate it. if (containsExtension && first) { first = false; @@ -614,7 +614,7 @@ namespace Sass { // ToDo: either change weave or paths to work with the same data? sass::vector> paths = permutate(extendedNotExpanded); - + for (const sass::vector& path : paths) { // Unpack the inner complex selector to component list sass::vector> _paths; @@ -626,7 +626,7 @@ namespace Sass { for (sass::vector& components : weaved) { - ComplexSelectorObj cplx = SASS_MEMORY_NEW(ComplexSelector, "[phony]"); + ComplexSelectorObj cplx = SASS_MEMORY_NEW(ComplexSelector, complex->pstate()); cplx->hasPreLineFeed(complex->hasPreLineFeed()); for (auto& pp : path) { if (pp->hasPreLineFeed()) { @@ -643,7 +643,18 @@ namespace Sass { } first = false; - result.push_back(cplx); + auto it = result.begin(); + while (it != result.end()) { + if (ObjEqualityFn(*it, cplx)) break; + it += 1; + } + if (it == result.end()) { + result.push_back(cplx); + } + + if (result.size() > 500) { + throw Exception::EndlessExtendError(traces, complex); + } } @@ -755,6 +766,20 @@ namespace Sass { sass::vector exts = options[0]; for (size_t n = 0; n < exts.size(); n += 1) { exts[n].assertCompatibleMediaContext(mediaQueryContext, traces); + // To fix invalid css we need to re-order some + // Therefore we need to make copies for them + if (exts[n].extender->isInvalidCss()) { + exts[n].extender = SASS_MEMORY_COPY(exts[n].extender); + for (SelectorComponentObj& component : exts[n].extender->elements()) { + if (CompoundSelector* compound = component->getCompound()) { + if (compound->isInvalidCss()) { + CompoundSelector* copy = SASS_MEMORY_COPY(compound); + copy->sortChildren(); + component = copy; + } + } + } + } result.push_back(exts[n].extender); } return result; @@ -824,7 +849,7 @@ namespace Sass { } if (!originals.empty()) { CompoundSelectorObj merged = - SASS_MEMORY_NEW(CompoundSelector, "[phony]"); + SASS_MEMORY_NEW(CompoundSelector, "[compound]"); merged->concat(originals); toUnify.insert(toUnify.begin(), { merged }); } @@ -844,10 +869,23 @@ namespace Sass { } for (sass::vector& components : complexes) { - auto sel = SASS_MEMORY_NEW(ComplexSelector, "[ext]"); + auto sel = SASS_MEMORY_NEW(ComplexSelector, "[unified]"); sel->hasPreLineFeed(lineBreak); sel->elements(components); + + /* This seems to do too much in regard of previous behavior + for (SelectorComponentObj& component : sel->elements()) { + if (CompoundSelector* compound = component->getCompound()) { + if (compound->isInvalidCss()) { + CompoundSelector* copy = SASS_MEMORY_COPY(compound); + copy->sortChildren(); + component = copy; + } + } + }*/ + unifiedPaths.push_back(sel); + } } @@ -950,7 +988,7 @@ namespace Sass { if (innerPseudo->normalized() != "matches") return {}; return innerPseudo->selector()->elements(); } - else if (name == "matches" && name == "any" && name == "current" && name == "nth-child" && name == "nth-last-child") { + else if (name == "matches" || name == "any" || name == "current" || name == "nth-child" || name == "nth-last-child") { // As above, we could theoretically support :not within :matches, but // doing so would require this method and its callers to handle much // more complex cases that likely aren't worth the pain. @@ -958,7 +996,7 @@ namespace Sass { if (!ObjEquality()(innerPseudo->argument(), pseudo->argument())) return {}; return innerPseudo->selector()->elements(); } - else if (name == "has" && name == "host" && name == "host-context" && name == "slotted") { + else if (name == "has" || name == "host" || name == "host-context" || name == "slotted") { // We can't expand nested selectors here, because each layer adds an // additional layer of semantics. For example, `:has(:has(img))` // doesn't match `
` but `:has(img)` does. @@ -1004,7 +1042,7 @@ namespace Sass { } } } - + sass::vector expanded = expand( complexes, extendPseudoComplex, pseudo, mediaQueryContext); @@ -1023,8 +1061,8 @@ namespace Sass { } } - SelectorListObj list = SASS_MEMORY_NEW(SelectorList, "[phony]"); - list->concat(complexes); + SelectorListObj list = SASS_MEMORY_NEW(SelectorList, "[pseudo]"); + list->concat(expanded); return { pseudo->withSelector(list) }; } @@ -1061,7 +1099,7 @@ namespace Sass { { // Avoid truly horrific quadratic behavior. - // TODO(nweiz): I think there may be a way to get perfect trimming + // TODO(nweiz): I think there may be a way to get perfect trimming // without going quadratic by building some sort of trie-like // data structure that can be used to look up superselectors. // TODO(mgreter): Check how this performs in C++ (up the limit) @@ -1103,7 +1141,7 @@ namespace Sass { maxSpecificity = std::max(maxSpecificity, maxSourceSpecificity(compound)); } } - + // Look in [result] rather than [selectors] for selectors after [i]. This // ensures we aren't comparing against a selector that's already been trimmed, diff --git a/src/libsass/src/fn_numbers.cpp b/src/libsass/src/fn_numbers.cpp index 01ac6049..73d78b03 100644 --- a/src/libsass/src/fn_numbers.cpp +++ b/src/libsass/src/fn_numbers.cpp @@ -5,10 +5,12 @@ #include #include #include +#include #include #include #include #include +#include #include "ast.hpp" #include "units.hpp" @@ -41,8 +43,25 @@ namespace Sass { #else uint64_t GetSeed() { - std::random_device rd; - return rd(); + // Init universe entropy + uint64_t rnd = 42; + // Try to get random number from system + try { + std::random_device rd; + rnd = rd(); + } + // On certain system this can throw since either + // underlying hardware or software can be buggy. + // https://github.com/sass/libsass/issues/3151 + catch (std::exception&) { + } + // Don't trust anyone to be random, so we + // add a little entropy of our own. + rnd ^= std::time(NULL) ^ std::clock() ^ + std::hash() + (std::this_thread::get_id()); + // Return entropy + return rnd; } #endif diff --git a/src/libsass/src/fn_selectors.cpp b/src/libsass/src/fn_selectors.cpp index 7494451e..3a7f88b2 100644 --- a/src/libsass/src/fn_selectors.cpp +++ b/src/libsass/src/fn_selectors.cpp @@ -96,7 +96,7 @@ namespace Sass { for (auto& complex : sel->elements()) { if (complex->empty()) { - complex->append(SASS_MEMORY_NEW(CompoundSelector, "[phony]")); + complex->append(SASS_MEMORY_NEW(CompoundSelector, "[append]")); } if (CompoundSelector* comp = Cast(complex->first())) { comp->hasRealParent(true); diff --git a/src/libsass/src/inspect.cpp b/src/libsass/src/inspect.cpp index bad73849..4d079bed 100644 --- a/src/libsass/src/inspect.cpp +++ b/src/libsass/src/inspect.cpp @@ -439,7 +439,7 @@ namespace Sass { if (list->is_bracketed()) { append_string(lbracket(list)); } - // probably ruby sass eqivalent of element_needs_parens + // probably ruby sass equivalent of element_needs_parens else if (output_style() == TO_SASS && list->length() == 1 && !list->from_selector() && @@ -489,7 +489,7 @@ namespace Sass { } append_string(rbracket(list)); } - // probably ruby sass eqivalent of element_needs_parens + // probably ruby sass equivalent of element_needs_parens else if (output_style() == TO_SASS && list->length() == 1 && !list->from_selector() && @@ -1017,7 +1017,7 @@ namespace Sass { bool was_comma_array = in_comma_array; - // probably ruby sass eqivalent of element_needs_parens + // probably ruby sass equivalent of element_needs_parens if (output_style() == TO_SASS && g->length() == 1 && (!Cast((*g)[0]) && !Cast((*g)[0]))) { @@ -1045,7 +1045,7 @@ namespace Sass { } in_comma_array = was_comma_array; - // probably ruby sass eqivalent of element_needs_parens + // probably ruby sass equivalent of element_needs_parens if (output_style() == TO_SASS && g->length() == 1 && (!Cast((*g)[0]) && !Cast((*g)[0]))) { @@ -1081,7 +1081,7 @@ namespace Sass { void Inspect::operator()(SelectorComponent* sel) { // You should probably never call this method directly - // But in case anyone does, we will do the upcasting + // But in case anyone does, we will do the up-casting if (auto comp = Cast(sel)) operator()(comp); if (auto comb = Cast(sel)) operator()(comb); } @@ -1091,7 +1091,6 @@ namespace Sass { if (sel->hasRealParent()) { append_string("&"); } - sel->sortChildren(); for (auto& item : sel->elements()) { item->perform(this); } diff --git a/src/libsass/src/lexer.cpp b/src/libsass/src/lexer.cpp index e8c3ba4b..b83c7394 100644 --- a/src/libsass/src/lexer.cpp +++ b/src/libsass/src/lexer.cpp @@ -39,7 +39,7 @@ namespace Sass { { unsigned int cmp = unsigned(chr); return (cmp > 41 && cmp < 127) || - cmp == ':' || cmp == '/'; + cmp == ':' || cmp == '/' || cmp == '|'; } // check if char is within a reduced ascii range diff --git a/src/libsass/src/operators.cpp b/src/libsass/src/operators.cpp index f163f3dc..a76bce3c 100644 --- a/src/libsass/src/operators.cpp +++ b/src/libsass/src/operators.cpp @@ -247,7 +247,7 @@ namespace Sass { { double rval = rhs.value(); - if ((op == Sass_OP::DIV || op == Sass_OP::DIV) && rval == 0) { + if ((op == Sass_OP::DIV || op == Sass_OP::MOD) && rval == 0) { // comparison of Fixnum with Float failed? throw Exception::ZeroDivisionError(lhs, rhs); } diff --git a/src/libsass/src/parser.cpp b/src/libsass/src/parser.cpp index a6420b84..201a536e 100644 --- a/src/libsass/src/parser.cpp +++ b/src/libsass/src/parser.cpp @@ -524,7 +524,7 @@ namespace Sass { // update for end position ruleset->update_pstate(pstate); ruleset->block()->update_pstate(pstate); - // need this info for sanity checks + // need this info for coherence checks ruleset->is_root(is_root); // return AST Node return ruleset; diff --git a/src/libsass/src/position.cpp b/src/libsass/src/position.cpp index 33efdf90..99018533 100644 --- a/src/libsass/src/position.cpp +++ b/src/libsass/src/position.cpp @@ -33,7 +33,7 @@ namespace Sass { { Offset offset(0, 0); if (end == 0) { - end += strlen(beg); + end = beg + strlen(beg); } offset.add(beg, end); return offset; @@ -54,17 +54,15 @@ namespace Sass { // https://stackoverflow.com/a/9356203/1550314 // https://en.wikipedia.org/wiki/UTF-8#Description unsigned char chr = *begin; - // skip over 10xxxxxx - // is 1st bit not set - if ((chr & 128) == 0) { + // Ignore all `10xxxxxx` chars + // '0xxxxxxx' are ASCII chars + // '11xxxxxx' are utf8 starts + // 64 => initial utf8 byte + // 128 => regular ASCII char + if ((chr & 192) != 128) { // regular ASCII char column += 1; } - // is 2nd bit not set - else if ((chr & 64) == 0) { - // first utf8 byte - column += 1; - } } ++ begin; } diff --git a/src/libsass/src/sass_context.cpp b/src/libsass/src/sass_context.cpp index 44a0f14d..44cee57b 100644 --- a/src/libsass/src/sass_context.cpp +++ b/src/libsass/src/sass_context.cpp @@ -77,6 +77,7 @@ namespace Sass { // now create the code trace (ToDo: maybe have util functions?) if (e.pstate.position.line != sass::string::npos && e.pstate.position.column != sass::string::npos && + e.pstate.getRawData() != nullptr && e.pstate.source != nullptr) { Offset offset(e.pstate.position); size_t lines = offset.line; diff --git a/src/libsass/utils/README.md b/src/libsass/utils/README.md new file mode 100644 index 00000000..b0819549 --- /dev/null +++ b/src/libsass/utils/README.md @@ -0,0 +1,6 @@ +This directory contains some utilities that are not essential for LibSass. + +# perl update-builds.pl + +This will update 3rd party build files from `Makefile.conf`, which +is the master index file for all required sources and headers. diff --git a/src/libsass/utils/build-skeletons/libsass.targets b/src/libsass/utils/build-skeletons/libsass.targets new file mode 100644 index 00000000..77bcf669 --- /dev/null +++ b/src/libsass/utils/build-skeletons/libsass.targets @@ -0,0 +1,8 @@ + + {{includes}} + {{headers}} + {{sources}} + + + + diff --git a/src/libsass/utils/build-skeletons/libsass.vcxproj.filters b/src/libsass/utils/build-skeletons/libsass.vcxproj.filters new file mode 100644 index 00000000..78cace5d --- /dev/null +++ b/src/libsass/utils/build-skeletons/libsass.vcxproj.filters @@ -0,0 +1,20 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;in;inl;inc;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {{includes}} + {{headers}} + {{sources}} + diff --git a/src/libsass/utils/update-builds.pl b/src/libsass/utils/update-builds.pl new file mode 100644 index 00000000..72cb4120 --- /dev/null +++ b/src/libsass/utils/update-builds.pl @@ -0,0 +1,88 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +# Installed via `cpan install File::Slurp` +# Alternative `cpanm install File::Slurp` +use File::Slurp qw(read_file write_file); + +my $tmpl_msvc_head = < +EOTMPL + +my $tmpl_msvc_inc = < +EOTMPL + +my $tmpl_msvc_src = < +EOTMPL + +my $tmpl_msvc_filter_head = < + Library Includes + +EOTMPL + +my $tmpl_msvc_filter_inc = < + LibSass Headers + +EOTMPL + +my $tmpl_msvc_filter_src = < + LibSass Sources + +EOTMPL + +# parse source files directly from libsass makefile +open(my $fh, "<", "../Makefile.conf") or + die "../Makefile.conf not found"; +my $srcfiles = join "", <$fh>; close $fh; + +my (@INCFILES, @HPPFILES, @SOURCES, @CSOURCES); +# parse variable out (this is hopefully tolerant enough) +if ($srcfiles =~ /^\s*INCFILES\s*=\s*((?:.*(?:\\\r?\n))*.*)/m) { + @INCFILES = grep { $_ } split /(?:\s|\\\r?\n)+/, $1; +} else { die "Did not find c++ INCFILES in libsass/Makefile.conf"; } +if ($srcfiles =~ /^\s*HPPFILES\s*=\s*((?:.*(?:\\\r?\n))*.*)/m) { + @HPPFILES = grep { $_ } split /(?:\s|\\\r?\n)+/, $1; +} else { die "Did not find c++ HPPFILES in libsass/Makefile.conf"; } +if ($srcfiles =~ /^\s*SOURCES\s*=\s*((?:.*(?:\\\r?\n))*.*)/m) { + @SOURCES = grep { $_ } split /(?:\s|\\\r?\n)+/, $1; +} else { die "Did not find c++ SOURCES in libsass/Makefile.conf"; } +if ($srcfiles =~ /^\s*CSOURCES\s*=\s*((?:.*(?:\\\r?\n))*.*)/m) { + @CSOURCES = grep { $_ } split /(?:\s|\\\r?\n)+/, $1; +} else { die "Did not find c++ CSOURCES in libsass/Makefile.conf"; } + +sub renderTemplate($@) { + my $str = "\n"; + my $tmpl = shift; + foreach my $inc (@_) { + $str .= sprintf($tmpl, $inc); + } + $str .= " "; + return $str; +} + +@INCFILES = map { s/\//\\/gr } @INCFILES; +@HPPFILES = map { s/\//\\/gr } @HPPFILES; +@SOURCES = map { s/\//\\/gr } @SOURCES; +@CSOURCES = map { s/\//\\/gr } @CSOURCES; + +my $targets = read_file("build-skeletons/libsass.targets"); +$targets =~s /\{\{includes\}\}/renderTemplate($tmpl_msvc_inc, @INCFILES)/eg; +$targets =~s /\{\{headers\}\}/renderTemplate($tmpl_msvc_head, @HPPFILES)/eg; +$targets =~s /\{\{sources\}\}/renderTemplate($tmpl_msvc_src, @SOURCES, @CSOURCES)/eg; +warn "Generating ../win/libsass.targets\n"; +write_file("../win/libsass.targets", $targets); + +my $filters = read_file("build-skeletons/libsass.vcxproj.filters"); +$filters =~s /\{\{includes\}\}/renderTemplate($tmpl_msvc_filter_inc, @INCFILES)/eg; +$filters =~s /\{\{headers\}\}/renderTemplate($tmpl_msvc_filter_head, @HPPFILES)/eg; +$filters =~s /\{\{sources\}\}/renderTemplate($tmpl_msvc_filter_src, @SOURCES, @CSOURCES)/eg; +warn "Generating ../win/libsass.vcxproj.filters\n"; +write_file("../win/libsass.vcxproj.filters", $filters); + diff --git a/src/libsass/win/libsass.targets b/src/libsass/win/libsass.targets index 6aa17d12..a60a27e5 100644 --- a/src/libsass/win/libsass.targets +++ b/src/libsass/win/libsass.targets @@ -1,5 +1,5 @@ - + @@ -7,32 +7,28 @@ - - - - - - - - - - - + + + + + - + + + @@ -41,26 +37,29 @@ - - - - + + + - + + + + + + - + - @@ -68,51 +67,33 @@ + + + - - - - - - + + + + - + - - - - - - - - - - - - - - - - - - - - + @@ -121,34 +102,55 @@ - + + + + + + + - - - - - + + + + + - - + + + + + + + + + + + + + - - - + + - + + + + - - - + + + + + diff --git a/src/libsass/win/libsass.vcxproj.filters b/src/libsass/win/libsass.vcxproj.filters index 8396b451..2d6248c9 100644 --- a/src/libsass/win/libsass.vcxproj.filters +++ b/src/libsass/win/libsass.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -7,459 +7,452 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd + h;hh;hpp;hxx;hm;in;inl;inc;xsd {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - {bb9c270d-e9f5-49bf-afda-771a1a4bb5b7} - h;hh;hpp;hxx;hm;in;inl;inc;xsd - - Include Headers + LibSass Headers - Include Headers + LibSass Headers - Include Headers + LibSass Headers - Include Headers + LibSass Headers - Include Headers + LibSass Headers - Include Headers + LibSass Headers - Include Headers + LibSass Headers - - Include Headers + + + + Library Includes - - Sources + + Library Includes - - Sources + + Library Includes - - Sources + + Library Includes - - - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - - Headers + + Library Includes - Sources + LibSass Sources - Sources - - - Sources + LibSass Sources - Sources + LibSass Sources - Sources + LibSass Sources - Sources + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Source Files + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - Sources + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources + + + LibSass Sources + + + LibSass Sources + + + LibSass Sources + + + LibSass Sources - Sources + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - Sources + LibSass Sources - Sources + LibSass Sources + + + LibSass Sources - Sources + LibSass Sources - Sources - - - Sources + LibSass Sources - Sources + LibSass Sources - - Sources + + LibSass Sources + + + LibSass Sources - Sources + LibSass Sources - Sources + LibSass Sources - Sources - - - Sources - - - Sources - - - Sources - - - Sources - - - Sources + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources - - Sources + + LibSass Sources