Commit fe572eb1 by xzyfer Committed by Michael Mifsud
parent 639173e4
{
"name": "node-sass",
"version": "4.7.2",
"libsass": "3.5.0.beta.2",
"libsass": "3.5.0",
"description": "Wrapper around libsass",
"license": "MIT",
"bugs": "https://github.com/sass/node-sass/issues",
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -5,18 +5,18 @@
The following is a set of guidelines for contributing to LibSass, which is hosted in the [Sass Organization](https://github.com/sass) on GitHub.
These are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request.
LibSass is a library that implements a [sass language] [8] compiler. As such it does not directly interface with end users (frontend developers).
LibSass is a library that implements a [sass language][8] compiler. As such it does not directly interface with end users (frontend developers).
For direct contributions to the LibSass code base you will need to have at least a rough idea of C++, we will not lie about that.
But there are other ways to contribute to the progress of LibSass. All contributions are done via github pull requests.
You can also contribute to the LibSass [documentation] [9] or provide additional [spec tests] [10] (and we will gladly point you in the
You can also contribute to the LibSass [documentation][9] or provide additional [spec tests][10] (and we will gladly point you in the
direction for corners that lack test coverage). Foremost we rely on good and concise bug reports for issues the spec tests do not yet catch.
## Precheck: My Sass isn't compiling
- [ ] Check if you can reproduce the issue via [SourceMap Inspector] [5] (updated regularly).
- [ ] Validate official ruby sass compiler via [SassMeister] [6] produces your expected result.
- [ ] Search for similar issue in [LibSass] [1] and [node-sass] [2] (include closed tickets)
- [ ] Optionally test your code directly with [sass] [7] or [sassc] [3] ([installer] [4])
- [ ] Check if you can reproduce the issue via [SourceMap Inspector][5] (updated regularly).
- [ ] Validate official ruby sass compiler via [SassMeister][6] produces your expected result.
- [ ] Search for similar issue in [LibSass][1] and [node-sass][2] (include closed tickets)
- [ ] Optionally test your code directly with [sass][7] or [sassc][3] ([installer][4])
## Precheck: My build/install fails
- [ ] Problems with building or installing libsass should be directed to implementors first!
......@@ -47,7 +47,7 @@ direction for corners that lack test coverage). Foremost we rely on good and con
## What makes a code test case
Important is that someone else can get the test case up and running to reproduce it locally. For this
we urge you to verify that your sample yields the expected result by testing it via [SassMeister] [6]
we urge you to verify that your sample yields the expected result by testing it via [SassMeister][6]
or directly via ruby sass or node-sass (or any other libsass implementor) before submitting your bug
report. Once you verified all of the above, you may use the template below to file your bug report.
......
### Title: Be as meaningful as possible in 60 chars if possible
[todo]: # (Title: Be as meaningful as possible)
[todo]: # (Title: Try to use 60 or less chars)
[todo]: # (This is only a template!)
[todo]: # (remove unneeded bits)
[todo]: # (use github preview!)
## input.scss
[todo]: # (always test and report with scss syntax)
[todo]: # (use sass only when results differ from scss)
input.scss
```scss
test {
content: bar
}
```
[libsass 3.5.5] [1]
## Actual results
[todo]: # (update version info!)
[libsass 3.X.y][1]
```css
test {
content: bar; }
```
ruby sass 3.4.21
## Expected result
[todo]: # (update version info!)
ruby sass 3.X.y
```css
test {
content: bar; }
```
[todo]: # (update version info!)
[todo]: # (example for node-sass!)
version info:
```cmd
$ node-sass --version
node-sass 3.3.3 (Wrapper) [JavaScript]
libsass 3.2.5 (Sass Compiler) [C/C++]
node-sass 3.X.y (Wrapper) [JavaScript]
libsass 3.X.y (Sass Compiler) [C/C++]
```
[todo]: # (Go to http://libsass.ocbnet.ch/srcmap)
[todo]: # (Enter your SCSS code and hit compile)
[todo]: # (Click `bookmark` and replace the url)
[todo]: # (link is used in actual results above)
[1]: http://libsass.ocbnet.ch/srcmap/#dGVzdCB7CiAgY29udGVudDogYmFyOyB9Cg==
......@@ -12,6 +12,8 @@ VERSION
.cproject
.project
.settings/
*.db
*.aps
# Configuration stuff
......@@ -68,6 +70,7 @@ bin/*
.libs/
win/bin
*.user
win/*.db
# Final results
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -69,7 +69,7 @@ else
endif
SASS_TESTER = $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb
SASS_TESTER += -c $(SASS_LIBSASS_PATH)/tester$(EXEEXT)
SASS_TESTER += -c $(top_srcdir)/tester$(EXEEXT)
test:
$(SASS_TESTER) $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -299,7 +299,7 @@ install-shared: $(DESTDIR)$(PREFIX)/lib/libsass.so \
install-headers
$(SASSC_BIN): $(BUILD)
$(MAKE) -C $(SASS_SASSC_PATH)
$(MAKE) -C $(SASS_SASSC_PATH) build-$(BUILD)-dev
sassc: $(SASSC_BIN)
$(SASSC_BIN) -v
......
File mode changed from 100755 to 100644
LibSass
=======
by Aaron Leung ([@akhleung]), Hampton Catlin ([@hcatlin]), Marcel Greter ([@mgreter]) and Michael Mifsud ([@xzyfer])
[![Unix CI](https://travis-ci.org/sass/libsass.svg?branch=master)](https://travis-ci.org/sass/libsass)
[![Windows CI](https://ci.appveyor.com/api/projects/status/github/sass/libsass?svg=true)](https://ci.appveyor.com/project/sass/libsass/branch/master)
[![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)
[![Coverage Status](https://img.shields.io/coveralls/sass/libsass.svg)](https://coveralls.io/r/sass/libsass?branch=feature%2Ftest-travis-ci-3)
[![Join us](https://libsass-slack.herokuapp.com/badge.svg)](https://libsass-slack.herokuapp.com/)
https://github.com/sass/libsass
LibSass is just a library, but if you want to RUN LibSass,
then go to https://github.com/sass/sassc or
https://github.com/sass/sassc-ruby or
[find your local implementer](docs/implementations.md).
LibSass requires GCC 4.6+ or Clang/LLVM. If your OS is older, this version may not compile.
On Windows, you need MinGW with GCC 4.6+ or VS 2013 Update 4+. It is also possible to build LibSass with Clang/LLVM on Windows.
LibSass - Sass compiler written in C++
======================================
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")
[![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")
[![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")
[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
implementations are only bindings into other programming languages. But most also
ship with a command line interface (CLI) you can use directly. There is also
[SassC](https://github.com/sass/sassc), which is the official lightweight
CLI tool built by the same people as LibSass.
### Excerpt of "sanctioned" implementations:
- https://github.com/sass/node-sass (Node.js)
- https://github.com/sass/perl-libsass (Perl)
- https://github.com/sass/libsass-python (Python)
- https://github.com/wellington/go-libsass (Go)
- https://github.com/sass/sassc-ruby (Ruby)
- https://github.com/sass/libsass-net (C#)
- https://github.com/medialize/sass.js (JS)
- https://github.com/bit3/jsass (Java)
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
-----
LibSass is a C/C++ port of the Sass CSS precompiler. The original version was written in Ruby, but this version is meant for efficiency and portability.
This library strives to be light, simple, and easy to build and integrate with a variety of platforms and languages.
LibSass is a C++ port of the original Ruby Sass CSS compiler with a [C API](docs/api-doc.md).
We coded LibSass with portability and efficiency in mind. You can expect LibSass to be a lot
faster than Ruby Sass and on par or faster than the best alternative CSS compilers around.
Developing
----------
As you may have noticed, the LibSass repo itself has
no executables and no tests. Oh noes! How can you develop???
Well, luckily, [SassC](http://github.com/sass/sassc) is the official binary wrapper for
LibSass and is *always* kept in sync. SassC is used by continous integration systems in
LibSass repository. When developing LibSass, it is best to actually
checkout SassC and develop in that directory with the SassC spec
and tests there.
We even run Travis tests for SassC!
As noted above, the LibSass repository does not contain any binaries or other way to execute
LibSass. Therefore, you need an implementer to develop LibSass. Easiest is to start with
the official [SassC](http://github.com/sass/sassc) CLI wrapper. It is *guaranteed* to compile
with the latest code in LibSass master, since it is also used in the CI process. There is no
limitation here, as you may use any other LibSass implementer to test your LibSass branch!
Tests
Testing
-------
Since LibSass is a pure library, tests are run through the [SassSpec](https://github.com/sass/sass-spec) project using the [SassC](http://github.com/sass/sassc) driver.
Since LibSass is a pure library, tests are run through the [Sass-Spec](https://github.com/sass/sass-spec)
project using the [SassC](http://github.com/sass/sassc) CLI wrapper. To run the tests against LibSass while
developing, you can run `./script/spec`. This will clone SassC and Sass-Spec under the project folder and
then run the Sass-Spec test suite. You may want to update the clones to ensure you have the latest version.
Note that the scripts in the `./script` folder are mainly intended for our CI needs.
To run tests against LibSass while developing, you can run `./script/spec`. This will clone SassC and Sass-Spec under the project folder and then run the Sass-Spec test suite. You may want to update the clones to ensure you have the latest version.
Building
--------
### DEBUG builds
To build LibSass you need GCC 4.6+ or Clang/LLVM. If your OS is older, you may need to upgrade
them first (or install clang as an alternative). On Windows, you need MinGW with GCC 4.6+ or VS 2013
Update 4+. It is also possible to build LibSass with Clang/LLVM on Windows with various build chains
and/or command line interpreters.
Set the environment variable `DEBUG` to `1` to enable debug builds that can be debugged
with `gdb`, `lldb` and others. E.g.: use `$ DEBUG=1 ./script/spec` to run the tests with
a debug build.
See the [build docs for further instructions](docs/build.md)!
Library Usage
Compatibility
-------------
While LibSass is a library primarily written in C++, it provides a simple
C interface which should be used by most implementers. LibSass does not do
much on its own without an implementer. This can be a command line tool, like
[sassc](https://github.com/sass/sassc) or a [binding](docs/implementations.md)
to your favorite programing language.
If you want to build or interface with LibSass, we recommend to check out the
documentation pages about [building LibSass](docs/build.md) and
the [C-API documentation](docs/api-doc.md).
Current LibSass 3.4 should be compatible with Sass 3.4. Please refer to the [sass compatibility
page](http://sass-compatibility.github.io/) for a more detailed comparison. But note that there
are still a few incomplete edges which we are aware of. Otherwise LibSass has reached a good level
of stability, thanks to our ever growing [Sass-Spec test suite](https://github.com/sass/sass-spec).
About Sass
----------
Sass is a CSS pre-processor language to add on exciting, new,
awesome features to CSS. Sass was the first language of its kind
and by far the most mature and up to date codebase.
Sass is a CSS pre-processor language to add on exciting, new, awesome features to CSS. Sass was
the first language of its kind and by far the most mature and up to date codebase.
Sass was originally concieved of by the co-creator of this library,
Hampton Catlin ([@hcatlin]). Most of the language has been the result of years
of work by Natalie Weizenbaum ([@nex3]) and Chris Eppstein ([@chriseppstein]).
Sass was originally conceived of by the co-creator of this library, Hampton Catlin ([@hcatlin]).
Most of the language has been the result of years of work by Natalie Weizenbaum ([@nex3]) and
Chris Eppstein ([@chriseppstein]).
For more information about Sass itself, please visit http://sass-lang.com
Initial development of libsass by Aaron Leung and Hampton Catlin was supported by [Moovweb](http://www.moovweb.com).
Initial development of LibSass by Aaron Leung and Hampton Catlin was supported by [Moovweb](http://www.moovweb.com).
Licensing
---------
Our MIT license is designed to be as simple, and liberal as possible.
sass2scss was originally written by [Marcel Greter][@mgreter]
and he happily agreed to have it merged into the project.
Our [MIT license](LICENSE) is designed to be as simple and liberal as possible.
[@hcatlin]: https://github.com/hcatlin
[@akhleung]: https://github.com/akhleung
......
File mode changed from 100755 to 100644
......@@ -7,8 +7,13 @@ environment:
matrix:
- Compiler: msvc
Config: Release
Platform: Win32
- Compiler: msvc
Config: Debug
Platform: Win32
- Compiler: msvc
Config: Release
Platform: Win64
- Compiler: mingw
Build: static
- Compiler: mingw
......@@ -38,7 +43,7 @@ build_script:
if ($env:Compiler -eq "mingw") {
mingw32-make -j4 sassc
} else {
msbuild /m:4 /p:Configuration=$env:Config sassc\win\sassc.sln
msbuild /m:4 /p:"Configuration=$env:Config;Platform=$env:Platform" sassc\win\sassc.sln
}
# print the branding art
......@@ -84,4 +89,3 @@ test_script:
} else {
echo "Success!"
}
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -187,7 +187,7 @@ should be on par with the latest LibSass interface version. Some of them may not
have all features implemented!
1. [Perl Example](https://github.com/sass/perl-libsass/blob/master/lib/CSS/Sass.xs)
2. [Go Example](http://godoc.org/github.com/wellington/go-libsass#example-Context-Compile)
2. [Go Example](https://godoc.org/github.com/wellington/go-libsass#example-Compiler--Stdin)
3. [Node Example](https://github.com/sass/node-sass/blob/master/src/binding.cpp)
## ABI forward compatibility
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
`Sass_Values` are used to pass values and their types between the implementer
and LibSass. Sass knows various different value types (including nested arrays
and hash-maps). If you implement a binding to another programming language, you
have to find a way to [marshal] [1] (convert) `Sass_Values` between the target
have to find a way to [marshal][1] (convert) `Sass_Values` between the target
language and C. `Sass_Values` are currently only used by custom functions, but
it should also be possible to use them without a compiler context.
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -3,14 +3,14 @@ Both should be considered experimental (MinGW was better tested)!
## Building via MingGW (makefiles)
First grab the latest [MinGW for windows] [1] installer. Once it is installed, you can click on continue or open the Installation Manager via `bin\mingw-get.exe`.
First grab the latest [MinGW for windows][1] installer. Once it is installed, you can click on continue or open the Installation Manager via `bin\mingw-get.exe`.
You need to have the following components installed:
![Visualization of components installed in the interface](https://cloud.githubusercontent.com/assets/282293/5525466/947bf396-89e6-11e4-841d-4aa916f14de1.png)
Next we need to install [git for windows] [2]. You probably want to check the option to add it to the global path, but you do not need to install the unix tools.
Next we need to install [git for windows][2]. You probably want to check the option to add it to the global path, but you do not need to install the unix tools.
If you want to run the spec test-suite you also need [ruby] [3] and a few gems available. Grab the [latest installer] [3] and make sure to add it the global path. Then install the missing gems:
If you want to run the spec test-suite you also need [ruby][3] and a few gems available. Grab the [latest installer][3] and make sure to add it the global path. Then install the missing gems:
```bash
gem install minitest
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
## Building LibSass with MingGW (makefiles)
First grab the latest [MinGW for windows] [1] installer. Once it is installed, you can click on continue or open the Installation Manager via `bin\mingw-get.exe`.
First grab the latest [MinGW for windows][1] installer. Once it is installed, you can click on continue or open the Installation Manager via `bin\mingw-get.exe`.
You need to have the following components installed:
![](https://cloud.githubusercontent.com/assets/282293/5525466/947bf396-89e6-11e4-841d-4aa916f14de1.png)
Next we need to install [git for windows] [2]. You probably want to check the option to add it to the global path, but you do not need to install the unix tools.
Next we need to install [git for windows][2]. You probably want to check the option to add it to the global path, but you do not need to install the unix tools.
If you want to run the spec test-suite you also need [ruby] [3] and a few gems available. Grab the [latest installer] [3] and make sure to add it the global path. Then install the missing gems:
If you want to run the spec test-suite you also need [ruby][3] and a few gems available. Grab the [latest installer][3] and make sure to add it the global path. Then install the missing gems:
```bash
gem install minitest
......
File mode changed from 100755 to 100644
`libsass` is only a library and does not do much on its own. You need an implementation that you can use from the [command line] [6]. Or some [[bindings|Implementations]] to use it within your favorite programming language. You should be able to get [`sassc`] [6] running by following the instructions in this guide.
`libsass` is only a library and does not do much on its own. You need an implementation that you can use from the [command line][6]. Or some [bindings|Implementations][9] to use it within your favorite programming language. You should be able to get [`sassc`][6] running by following the instructions in this guide.
Before starting, see [setup dev environment](setup-environment.md).
......@@ -11,27 +11,27 @@ We try to keep the code as OS independent and standard compliant as possible. Re
Linux is the main target for `libsass` and we support two ways to build `libsass` here. The old plain makefiles should still work on most systems (including MinGW), while the autotools build is preferred if you want to create a [system library] (experimental).
- [Building with makefiles] [1]
- [Building with autotools] [2]
- [Building with makefiles][1]
- [Building with autotools][2]
### Building on Windows (experimental)
Windows build support was added very recently and should be considered experimental. Credits go to @darrenkopp and @am11 for their work on getting `libsass` and `sassc` to compile with visual studio!
- [Building with MinGW] [3]
- [Building with Visual Studio] [11]
- [Building with MinGW][3]
- [Building with Visual Studio][11]
### Building on Max OS X (untested)
Works the same as on linux, but you can also install LibSass via `homebrew`.
- [Building on Mac OS X] [10]
- [Building on Mac OS X][10]
### Building a system library (experimental)
Since `libsass` is a library, it makes sense to install it as a shared library on your system. On linux this means creating a `.so` library via autotools. This should work pretty well already, but we are not yet committed to keep the ABI 100% stable. This should be the case once we increase the version number for the library to 1.0.0 or higher. On Windows you should be able get a `dll` by creating a shared build with MinGW. There is currently no target in the MSVC project files to do this.
- [Building shared system library] [4]
- [Building shared system library][4]
Compiling with clang instead of gcc
--
......@@ -46,7 +46,7 @@ export CXX=/usr/bin/clang++
Running the spec test-suite
--
We constantly and automatically test `libsass` against the official [spec test-suite] [5]. To do this we need to have a test-runner (which is written in ruby) and a command-line tool ([`sassc`] [6]) to run the tests. Therefore we need to additionally compile `sassc`. To do this, the build files of all three projects need to work together. This may not have the same quality for all build flavors. You definitely need to have ruby (2.1?) installed (version 1.9 seems to cause problems at least on windows). You also need some gems installed:
We constantly and automatically test `libsass` against the official [spec test-suite][5]. To do this we need to have a test-runner (which is written in ruby) and a command-line tool ([`sassc`][6]) to run the tests. Therefore we need to additionally compile `sassc`. To do this, the build files of all three projects need to work together. This may not have the same quality for all build flavors. You definitely need to have ruby (2.1?) installed (version 1.9 seems to cause problems at least on windows). You also need some gems installed:
```bash
ruby -v
......@@ -67,7 +67,7 @@ export LIBSASS_VERSION="x.y.z."
Continuous Integration
--
We use two CI services to automatically test all commits against the latest [spec test-suite] [5].
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)
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -37,7 +37,7 @@
#ifndef SASS2SCSS_VERSION
// Hardcode once the file is copied from
// https://github.com/mgreter/sass2scss
#define SASS2SCSS_VERSION "1.1.0"
#define SASS2SCSS_VERSION "1.1.1"
#endif
// add namespace for c++
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -18,18 +18,18 @@ BEGIN
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "CompanyName", "Libsass Organization"
VALUE "CompanyName", "Sass Open Source Foundation"
VALUE "FileDescription", "A C/C++ implementation of a Sass compiler"
VALUE "FileVersion", "0.9.0.0"
VALUE "FileVersion", "1.0.0.0"
VALUE "InternalName", "libsass"
VALUE "LegalCopyright", "©2014 libsass.org"
VALUE "LegalCopyright", "\251 2017 libsass.org"
VALUE "OriginalFilename", "libsass.dll"
VALUE "ProductName", "Libsass Library"
VALUE "ProductVersion", "0.9.0.0"
VALUE "ProductName", "LibSass Library"
VALUE "ProductVersion", "1.0.0.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END
\ No newline at end of file
END
......@@ -114,7 +114,7 @@ then
then
echo "Travis rate limit on github exceeded"
echo "Retrying via 'special purpose proxy'"
JSON=$(curl -L -sS http://libsass.ocbnet.ch/libsass-spec-pr.psgi/$TRAVIS_PULL_REQUEST)
JSON=$(curl -L -sS https://github-api-reverse-proxy.herokuapp.com/repos/sass/libsass/pulls/$TRAVIS_PULL_REQUEST)
fi
RE_SPEC_PR="sass\/sass-spec(#|\/pull\/)([0-9]+)"
......
......@@ -3,4 +3,4 @@
gem install minitest
gem install minitap
pip install --user 'requests[security]'
pip2 install --user 'requests[security]'
#!/bin/bash
if [ "x$COVERAGE" == "xyes" ]; then
pip install --user gcovr
pip install --user cpp-coveralls
pip2 install --user gcovr
pip2 install --user cpp-coveralls
else
echo "no dependencies to install"
fi
......@@ -15,9 +15,6 @@ if [ "x$AUTOTOOLS" == "xyes" ]; then
sudo apt-get -qq install automake
fi
# https://github.com/sass/libsass/pull/2183
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
brew uninstall libtool
brew install libtool
fi
fi
exit 0
#! /bin/sh
#!/usr/bin/env sh
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
......
File mode changed from 100755 to 100644
......@@ -19,12 +19,21 @@ class LocalOption {
this->orig = var;
*(this->var) = orig;
}
void reset()
{
*(this->var) = this->orig;
}
~LocalOption() {
*(this->var) = this->orig;
}
};
#define LOCAL_FLAG(name,opt) LocalOption<bool> flag_##name(name, opt)
#define LOCAL_COUNT(name,opt) LocalOption<size_t> cnt_##name(name, opt)
#define NESTING_GUARD(name) \
LocalOption<size_t> cnt_##name(name, name + 1); \
if (name > MAX_NESTING) throw Exception::NestingLimitError(pstate); \
#define ATTACH_OPERATIONS()\
virtual void perform(Operation<void>* op) { (*op)(this); }\
......
File mode changed from 100755 to 100644
......@@ -132,6 +132,9 @@ namespace Sass {
class Map;
typedef Map* Map_Ptr;
typedef Map const* Map_Ptr_Const;
class Function;
typedef Function* Function_Ptr;
typedef Function const* Function_Ptr_Const;
class Mixin_Call;
typedef Mixin_Call* Mixin_Call_Ptr;
......@@ -158,9 +161,6 @@ namespace Sass {
class Variable;
typedef Variable* Variable_Ptr;
typedef Variable const* Variable_Ptr_Const;
class Textual;
typedef Textual* Textual_Ptr;
typedef Textual const* Textual_Ptr_Const;
class Number;
typedef Number* Number_Ptr;
typedef Number const* Number_Ptr_Const;
......@@ -314,6 +314,7 @@ namespace Sass {
IMPL_MEM_OBJ(Expression);
IMPL_MEM_OBJ(List);
IMPL_MEM_OBJ(Map);
IMPL_MEM_OBJ(Function);
IMPL_MEM_OBJ(Binary_Expression);
IMPL_MEM_OBJ(Unary_Expression);
IMPL_MEM_OBJ(Function_Call);
......@@ -321,7 +322,6 @@ namespace Sass {
IMPL_MEM_OBJ(Custom_Warning);
IMPL_MEM_OBJ(Custom_Error);
IMPL_MEM_OBJ(Variable);
IMPL_MEM_OBJ(Textual);
IMPL_MEM_OBJ(Number);
IMPL_MEM_OBJ(Color);
IMPL_MEM_OBJ(Boolean);
......@@ -376,6 +376,11 @@ namespace Sass {
struct CompareNodes {
template <class T>
bool operator() (const T& lhs, const T& rhs) const {
// code around sass logic issue. 1px == 1 is true
// but both items are still different keys in maps
if (dynamic_cast<Number*>(lhs.ptr()))
if (dynamic_cast<Number*>(rhs.ptr()))
return lhs->hash() == rhs->hash();
return !lhs.isNull() && !rhs.isNull() && *lhs == *rhs;
}
};
......@@ -410,8 +415,12 @@ namespace Sass {
typedef std::deque<Complex_Selector_Obj> ComplexSelectorDeque;
typedef std::set<Simple_Selector_Obj, OrderNodes> SimpleSelectorSet;
typedef std::set<Complex_Selector_Obj, OrderNodes> ComplexSelectorSet;
typedef std::set<Compound_Selector_Obj, OrderNodes> CompoundSelectorSet;
typedef std::unordered_set<Simple_Selector_Obj, HashNodes, CompareNodes> SimpleSelectorDict;
// only to switch implementations for testing
#define environment_map std::map
// ###########################################################################
// explicit type conversion functions
// ###########################################################################
......
File mode changed from 100755 to 100644
......@@ -24,7 +24,9 @@ namespace base64
encoder(int buffersize_in = BUFFERSIZE)
: _buffersize(buffersize_in)
{}
{
base64_init_encodestate(&_state);
}
int encode(char value_in)
{
......
......@@ -60,13 +60,13 @@ namespace Sass {
size_t depth()
{
size_t d = 0;
size_t d = std::string::npos;
Backtrace* p = parent;
while (p) {
++d;
p = p->parent;
}
return d-1;
return d;
}
};
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -14,6 +14,8 @@ namespace Sass {
std::string callee(type + " " + name);
std::map<std::string, Parameter_Obj> param_map;
List_Obj varargs = SASS_MEMORY_NEW(List, as->pstate());
varargs->is_arglist(true); // enable keyword size handling
for (size_t i = 0, L = as->length(); i < L; ++i) {
if (auto str = Cast<String_Quoted>((*as)[i]->value())) {
......@@ -95,13 +97,17 @@ namespace Sass {
env->local_frame()[p->name()] = arglist;
Map_Obj argmap = Cast<Map>(a->value());
for (auto key : argmap->keys()) {
std::string name = unquote(Cast<String_Constant>(key)->value());
arglist->append(SASS_MEMORY_NEW(Argument,
key->pstate(),
argmap->at(key),
"$" + name,
false,
false));
if (String_Constant_Obj str = Cast<String_Constant>(key)) {
std::string param = unquote(str->value());
arglist->append(SASS_MEMORY_NEW(Argument,
key->pstate(),
argmap->at(key),
"$" + param,
false,
false));
} else {
throw Exception::InvalidVarKwdType(key->pstate(), key->inspect(), a);
}
}
} else {
......@@ -131,8 +137,8 @@ namespace Sass {
if (List_Obj rest = Cast<List>(a->value())) {
arglist->separator(rest->separator());
for (size_t i = 0, L = rest->size(); i < L; ++i) {
Expression_Obj obj = rest->at(i);
for (size_t i = 0, L = rest->length(); i < L; ++i) {
Expression_Obj obj = rest->value_at_index(i);
arglist->append(SASS_MEMORY_NEW(Argument,
obj->pstate(),
obj,
......@@ -167,8 +173,15 @@ namespace Sass {
else if (a->is_rest_argument()) {
// normal param and rest arg
List_Obj arglist = Cast<List>(a->value());
if (!arglist) {
if (Expression_Obj arg = Cast<Expression>(a->value())) {
arglist = SASS_MEMORY_NEW(List, a->pstate(), 1);
arglist->append(arg);
}
}
// empty rest arg - treat all args as default values
if (!arglist->length()) {
if (!arglist || !arglist->length()) {
break;
} else {
if (arglist->length() > LP - ip && !ps->has_rest_parameter()) {
......@@ -205,14 +218,16 @@ namespace Sass {
Map_Obj argmap = Cast<Map>(a->value());
for (auto key : argmap->keys()) {
std::string name = "$" + unquote(Cast<String_Constant>(key)->value());
String_Constant_Ptr val = Cast<String_Constant>(key);
if (val == NULL) throw Exception::InvalidVarKwdType(key->pstate(), key->inspect(), a);
std::string param = "$" + unquote(val->value());
if (!param_map.count(name)) {
if (!param_map.count(param)) {
std::stringstream msg;
msg << callee << " has no parameter named " << name;
msg << callee << " has no parameter named " << param;
error(msg.str(), a->pstate());
}
env->local_frame()[name] = argmap->at(key);
env->local_frame()[param] = argmap->at(key);
}
++ia;
continue;
......@@ -234,15 +249,21 @@ namespace Sass {
else {
// named arg -- bind it to the appropriately named param
if (!param_map.count(a->name())) {
std::stringstream msg;
msg << callee << " has no parameter named " << a->name();
error(msg.str(), a->pstate());
if (ps->has_rest_parameter()) {
varargs->append(a);
} else {
std::stringstream msg;
msg << callee << " has no parameter named " << a->name();
error(msg.str(), a->pstate());
}
}
if (param_map[a->name()]->is_rest_parameter()) {
std::stringstream msg;
msg << "argument " << a->name() << " of " << callee
<< "cannot be used as named argument";
error(msg.str(), a->pstate());
if (param_map[a->name()]) {
if (param_map[a->name()]->is_rest_parameter()) {
std::stringstream msg;
msg << "argument " << a->name() << " of " << callee
<< "cannot be used as named argument";
error(msg.str(), a->pstate());
}
}
if (env->has_local(a->name())) {
std::stringstream msg;
......@@ -265,11 +286,7 @@ namespace Sass {
// cerr << "********" << endl;
if (!env->has_local(leftover->name())) {
if (leftover->is_rest_parameter()) {
env->local_frame()[leftover->name()] = SASS_MEMORY_NEW(List,
leftover->pstate(),
0,
SASS_COMMA,
true);
env->local_frame()[leftover->name()] = varargs;
}
else if (leftover->default_value()) {
Expression_Ptr dv = leftover->default_value()->perform(eval);
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -46,6 +46,9 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
result = (fragment & 0x0fc) >> 2;
*codechar++ = base64_encode_value(result);
result = (fragment & 0x003) << 4;
#ifndef _MSC_VER
__attribute__ ((fallthrough));
#endif
case step_B:
if (plainchar == plaintextend)
{
......@@ -57,6 +60,9 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
result |= (fragment & 0x0f0) >> 4;
*codechar++ = base64_encode_value(result);
result = (fragment & 0x00f) << 2;
#ifndef _MSC_VER
__attribute__ ((fallthrough));
#endif
case step_C:
if (plainchar == plaintextend)
{
......
......@@ -40,7 +40,13 @@ namespace Sass {
}
At_Root_Block_Ptr ar = Cast<At_Root_Block>(parent);
Statement_Ptr ret = this->visit_children(ar->block());
Block_Ptr ret = ar->block();
if (ret != NULL) {
for (auto n : ret->elements()) {
n->perform(this);
}
}
this->parent = old_parent;
this->parents = old_parents;
......@@ -97,6 +103,19 @@ namespace Sass {
return n;
}
Statement_Ptr CheckNesting::operator()(If_Ptr i)
{
this->visit_children(i);
if (Block_Ptr b = Cast<Block>(i->alternative())) {
for (auto n : i->alternative()->elements()) {
n->perform(this);
}
}
return i;
}
Statement_Ptr CheckNesting::fallback_impl(Statement_Ptr s)
{
Block_Ptr b1 = Cast<Block>(s);
......
......@@ -22,6 +22,7 @@ namespace Sass {
Statement_Ptr operator()(Block_Ptr);
Statement_Ptr operator()(Definition_Ptr);
Statement_Ptr operator()(If_Ptr);
template <typename U>
Statement_Ptr fallback(U x) {
......
......@@ -607,16 +607,20 @@ namespace Sass {
Color_Ptr_Const name_to_color(const char* key)
{
auto p = names_to_colors.find(key);
if (p != names_to_colors.end()) {
return p->second;
}
return 0;
return name_to_color(std::string(key));
}
Color_Ptr_Const name_to_color(const std::string& key)
{
return name_to_color(key.c_str());
// case insensitive lookup. See #2462
std::string lower{key};
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
auto p = names_to_colors.find(lower.c_str());
if (p != names_to_colors.end()) {
return p->second;
}
return 0;
}
const char* color_to_name(const int key)
......
File mode changed from 100755 to 100644
......@@ -79,11 +79,12 @@ namespace Sass {
extern const char supports_kwd[] = "@supports";
extern const char keyframes_kwd[] = "keyframes";
extern const char only_kwd[] = "only";
extern const char rgb_kwd[] = "rgb(";
extern const char rgb_fn_kwd[] = "rgb(";
extern const char url_fn_kwd[] = "url(";
extern const char url_kwd[] = "url";
// extern const char url_prefix_kwd[] = "url-prefix(";
// extern const char url_prefix_fn_kwd[] = "url-prefix(";
extern const char important_kwd[] = "important";
extern const char pseudo_not_kwd[] = ":not(";
extern const char pseudo_not_fn_kwd[] = ":not(";
extern const char even_kwd[] = "even";
extern const char odd_kwd[] = "odd";
extern const char progid_kwd[] = "progid";
......
......@@ -79,11 +79,12 @@ namespace Sass {
extern const char supports_kwd[];
extern const char keyframes_kwd[];
extern const char only_kwd[];
extern const char rgb_kwd[];
extern const char rgb_fn_kwd[];
extern const char url_fn_kwd[];
extern const char url_kwd[];
// extern const char url_prefix_kwd[];
// extern const char url_prefix_fn_kwd[];
extern const char important_kwd[];
extern const char pseudo_not_kwd[];
extern const char pseudo_not_fn_kwd[];
extern const char even_kwd[];
extern const char odd_kwd[];
extern const char progid_kwd[];
......
......@@ -67,11 +67,14 @@ namespace Sass {
plugins(),
emitter(c_options),
ast_gc(),
strings(),
resources(),
sheets(),
subset_map(),
import_stack(),
callee_stack(),
c_compiler(NULL),
c_headers (std::vector<Sass_Importer_Entry>()),
c_importers (std::vector<Sass_Importer_Entry>()),
......@@ -130,7 +133,7 @@ namespace Sass {
Context::~Context()
{
// resources were allocated by strdup or malloc
// resources were allocated by malloc
for (size_t i = 0; i < resources.size(); ++i) {
free(resources[i].contents);
free(resources[i].srcmap);
......@@ -416,12 +419,12 @@ namespace Sass {
// need one correct import
bool has_import = false;
// process all custom importers (or custom headers)
for (Sass_Importer_Entry& importer : importers) {
for (Sass_Importer_Entry& importer_ent : importers) {
// int priority = sass_importer_get_priority(importer);
Sass_Importer_Fn fn = sass_importer_get_function(importer);
Sass_Importer_Fn fn = sass_importer_get_function(importer_ent);
// skip importer if it returns NULL
if (Sass_Import_List includes =
fn(load_path.c_str(), importer, c_compiler)
fn(load_path.c_str(), importer_ent, c_compiler)
) {
// get c pointer copy to iterate over
Sass_Import_List it_includes = includes;
......@@ -436,15 +439,15 @@ namespace Sass {
// create the importer struct
Importer importer(uniq_path, ctx_path);
// query data from the current include
Sass_Import_Entry include = *it_includes;
char* source = sass_import_take_source(include);
char* srcmap = sass_import_take_srcmap(include);
size_t line = sass_import_get_error_line(include);
size_t column = sass_import_get_error_column(include);
const char *abs_path = sass_import_get_abs_path(include);
Sass_Import_Entry include_ent = *it_includes;
char* source = sass_import_take_source(include_ent);
char* srcmap = sass_import_take_srcmap(include_ent);
size_t line = sass_import_get_error_line(include_ent);
size_t column = sass_import_get_error_column(include_ent);
const char *abs_path = sass_import_get_abs_path(include_ent);
// handle error message passed back from custom importer
// it may (or may not) override the line and column info
if (const char* err_message = sass_import_get_error_message(include)) {
if (const char* err_message = sass_import_get_error_message(include_ent)) {
if (source || srcmap) register_resource({ importer, uniq_path }, { source, srcmap }, &pstate);
if (line == std::string::npos && column == std::string::npos) error(err_message, pstate);
else error(err_message, ParserState(ctx_path, source, Position(line, column)));
......@@ -661,7 +664,8 @@ namespace Sass {
// should we extend something?
if (!subset_map.empty()) {
// create crtp visitor object
Extend extend(*this, subset_map);
Extend extend(subset_map);
extend.setEval(expand.eval);
// extend tree nodes
extend(root);
}
......@@ -696,10 +700,8 @@ namespace Sass {
char* Context::render_srcmap()
{
if (source_map_file == "") return 0;
char* result = 0;
std::string map = emitter.render_srcmap(*this);
result = sass_copy_c_string(map.c_str());
return result;
return sass_copy_c_string(map.c_str());
}
......@@ -831,6 +833,8 @@ namespace Sass {
register_function(ctx, mixin_exists_sig, mixin_exists, env);
register_function(ctx, feature_exists_sig, feature_exists, env);
register_function(ctx, call_sig, call, env);
register_function(ctx, content_exists_sig, content_exists, env);
register_function(ctx, get_function_sig, get_function, env);
// Boolean Functions
register_function(ctx, not_sig, sass_not, env);
register_function(ctx, if_sig, sass_if, env);
......
......@@ -43,6 +43,9 @@ namespace Sass {
Plugins plugins;
Output emitter;
// generic ast node garbage container
// used to avoid possible circular refs
std::vector<AST_Node_Obj> ast_gc;
// resources add under our control
// these are guaranteed to be freed
std::vector<char*> strings;
......
......@@ -23,12 +23,12 @@ namespace Sass {
Block_Ptr Cssize::operator()(Block_Ptr b)
{
Block_Ptr bb = SASS_MEMORY_NEW(Block, b->pstate(), b->length(), b->is_root());
Block_Obj bb = SASS_MEMORY_NEW(Block, b->pstate(), b->length(), b->is_root());
// bb->tabs(b->tabs());
block_stack.push_back(bb);
append_block(b, bb);
block_stack.pop_back();
return bb;
return bb.detach();
}
Statement_Ptr Cssize::operator()(Trace_Ptr t)
......@@ -54,7 +54,8 @@ namespace Sass {
d->pstate(),
property,
d->value(),
d->is_important());
d->is_important(),
d->is_custom_property());
dd->is_indented(d->is_indented());
dd->tabs(d->tabs());
......@@ -174,9 +175,9 @@ namespace Sass {
if (props->length())
{
Block_Obj bb = SASS_MEMORY_NEW(Block, rr->block()->pstate());
bb->concat(props);
rr->block(bb);
Block_Obj pb = SASS_MEMORY_NEW(Block, rr->block()->pstate());
pb->concat(props);
rr->block(pb);
for (size_t i = 0, L = rules->length(); i < L; i++)
{
......@@ -259,7 +260,7 @@ namespace Sass {
tmp |= m->exclude_node(s);
}
if (!tmp)
if (!tmp && m->block())
{
Block_Ptr bb = operator()(m->block());
for (size_t i = 0, L = bb->length(); i < L; ++i) {
......@@ -302,14 +303,17 @@ namespace Sass {
Statement_Ptr Cssize::bubble(At_Root_Block_Ptr m)
{
if (!m || !m->block()) return NULL;
Block_Ptr bb = SASS_MEMORY_NEW(Block, this->parent()->pstate());
Has_Block_Obj new_rule = Cast<Has_Block>(SASS_MEMORY_COPY(this->parent()));
new_rule->block(bb);
new_rule->tabs(this->parent()->tabs());
new_rule->block()->concat(m->block());
Block_Ptr wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate());
wrapper_block->append(new_rule);
if (new_rule) {
new_rule->block(bb);
new_rule->tabs(this->parent()->tabs());
new_rule->block()->concat(m->block());
wrapper_block->append(new_rule);
}
At_Root_Block_Ptr mm = SASS_MEMORY_NEW(At_Root_Block,
m->pstate(),
wrapper_block,
......@@ -442,7 +446,7 @@ namespace Sass {
for (size_t j = 0, K = slice->length(); j < K; ++j)
{
Statement_Ptr ss = NULL;
Statement_Ptr ss;
Statement_Obj stm = slice->at(j);
// this has to go now here (too bad)
Bubble_Obj node = Cast<Bubble>(stm);
......@@ -476,8 +480,6 @@ namespace Sass {
ss->tabs(ss->tabs() + node->tabs());
ss->group_end(node->group_end());
if (!ss) continue;
Block_Obj bb = SASS_MEMORY_NEW(Block,
children->pstate(),
children->length(),
......@@ -584,10 +586,11 @@ namespace Sass {
}
Media_Query_Ptr mm = SASS_MEMORY_NEW(Media_Query,
mq1->pstate(), 0,
mq1->length() + mq2->length(), mod == "not", mod == "only"
);
mq1->pstate(),
0,
mq1->length() + mq2->length(),
mod == "not",
mod == "only");
if (!type.empty()) {
mm->media_type(SASS_MEMORY_NEW(String_Quoted, mq1->pstate(), type));
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -103,7 +103,7 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
std::cerr << (selector->has_line_break() ? " [line-break]": " -");
std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
std::cerr << std::endl;
debug_ast(selector->schema(), "#{} ");
debug_ast(selector->schema(), ind + "#{} ");
for(const Complex_Selector_Obj& i : selector->elements()) { debug_ast(i, ind + " ", env); }
......@@ -415,6 +415,7 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
Declaration_Ptr block = Cast<Declaration>(node);
std::cerr << ind << "Declaration " << block;
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [is_custom_property: " << block->is_custom_property() << "] ";
std::cerr << " " << block->tabs() << std::endl;
debug_ast(block->property(), ind + " prop: ", env);
debug_ast(block->value(), ind + " value: ", env);
......@@ -488,18 +489,6 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
std::cerr << (block->is_invisible() ? " [INVISIBLE]" : "");
std::cerr << " [indent: " << block->tabs() << "]" << std::endl;
for(const Statement_Obj& i : block->elements()) { debug_ast(i, ind + " ", env); }
} else if (Cast<Textual>(node)) {
Textual_Ptr expression = Cast<Textual>(node);
std::cerr << ind << "Textual " << expression;
std::cerr << " (" << pstate_source_position(node) << ")";
if (expression->type() == Textual::NUMBER) std::cerr << " [NUMBER]";
else if (expression->type() == Textual::PERCENTAGE) std::cerr << " [PERCENTAGE]";
else if (expression->type() == Textual::DIMENSION) std::cerr << " [DIMENSION]";
else if (expression->type() == Textual::HEX) std::cerr << " [HEX]";
std::cerr << " [" << expression->value() << "]";
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
if (expression->is_delayed()) std::cerr << " [delayed]";
std::cerr << std::endl;
} else if (Cast<Variable>(node)) {
Variable_Ptr expression = Cast<Variable>(node);
std::cerr << ind << "Variable " << expression;
......@@ -524,8 +513,17 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
std::cerr << " [" << expression->name() << "]";
if (expression->is_delayed()) std::cerr << " [delayed]";
if (expression->is_interpolant()) std::cerr << " [interpolant]";
if (expression->is_css()) std::cerr << " [css]";
std::cerr << std::endl;
debug_ast(expression->arguments(), ind + " args: ", env);
debug_ast(expression->func(), ind + " func: ", env);
} else if (Cast<Function>(node)) {
Function_Ptr expression = Cast<Function>(node);
std::cerr << ind << "Function " << expression;
std::cerr << " (" << pstate_source_position(node) << ")";
if (expression->is_css()) std::cerr << " [css]";
std::cerr << std::endl;
debug_ast(expression->definition(), ind + " definition: ", env);
} else if (Cast<Arguments>(node)) {
Arguments_Ptr expression = Cast<Arguments>(node);
std::cerr << ind << "Arguments " << expression;
......@@ -698,6 +696,8 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
case Expression::Concrete_Type::C_ERROR: std::cerr << " [C_ERROR]"; break;
case Expression::Concrete_Type::FUNCTION: std::cerr << " [FUNCTION]"; break;
case Expression::Concrete_Type::NUM_TYPES: std::cerr << " [NUM_TYPES]"; break;
case Expression::Concrete_Type::VARIABLE: std::cerr << " [VARIABLE]"; break;
case Expression::Concrete_Type::FUNCTION_VAL: std::cerr << " [FUNCTION_VAL]"; break;
}
std::cerr << std::endl;
} else if (Cast<Has_Block>(node)) {
......
......@@ -14,7 +14,9 @@ namespace Sass {
scheduled_space(0),
scheduled_linefeed(0),
scheduled_delimiter(false),
scheduled_crutch(0),
scheduled_mapping(0),
in_custom_property(false),
in_comment(false),
in_wrapped(false),
in_media_block(false),
......@@ -101,10 +103,30 @@ namespace Sass {
// prepend some text or token to the buffer
void Emitter::prepend_string(const std::string& text)
{
wbuf.smap.prepend(Offset(text));
// do not adjust mappings for utf8 bom
// seems they are not counted in any UA
if (text.compare("\xEF\xBB\xBF") != 0) {
wbuf.smap.prepend(Offset(text));
}
wbuf.buffer = text + wbuf.buffer;
}
char Emitter::last_char()
{
return wbuf.buffer.back();
}
// append a single char to the buffer
void Emitter::append_char(const char chr)
{
// write space/lf
flush_schedules();
// add to buffer
wbuf.buffer += chr;
// account for data in source-maps
wbuf.smap.append(Offset(chr));
}
// append some text or token to the buffer
void Emitter::append_string(const std::string& text)
{
......@@ -145,9 +167,9 @@ namespace Sass {
add_open_mapping(node);
// hotfix for browser issues
// this is pretty ugly indeed
if (scheduled_mapping) {
add_open_mapping(scheduled_mapping);
scheduled_mapping = 0;
if (scheduled_crutch) {
add_open_mapping(scheduled_crutch);
scheduled_crutch = 0;
}
append_string(text);
add_close_mapping(node);
......@@ -193,7 +215,7 @@ namespace Sass {
{
scheduled_space = 0;
append_string(":");
append_optional_space();
if (!in_custom_property) append_optional_space();
}
void Emitter::append_mandatory_space()
......@@ -206,7 +228,9 @@ namespace Sass {
if ((output_style() != COMPRESSED) && buffer().size()) {
unsigned char lst = buffer().at(buffer().length() - 1);
if (!isspace(lst) || scheduled_delimiter) {
append_mandatory_space();
if (last_char() != '(') {
append_mandatory_space();
}
}
}
}
......
......@@ -37,9 +37,12 @@ namespace Sass {
size_t scheduled_space;
size_t scheduled_linefeed;
bool scheduled_delimiter;
AST_Node_Ptr scheduled_crutch;
AST_Node_Ptr scheduled_mapping;
public:
// output strings different in custom css properties
bool in_custom_property;
// output strings different in comments
bool in_comment;
// selector list does not get linefeeds
......@@ -66,11 +69,15 @@ namespace Sass {
void prepend_output(const OutputBuffer& out);
// append some text or token to the buffer
void append_string(const std::string& text);
// append a single character to buffer
void append_char(const char chr);
// append some white-space only text
void append_wspace(const std::string& text);
// append some text or token to the buffer
// this adds source-mappings for node start and end
void append_token(const std::string& text, const AST_Node_Ptr node);
// query last appended character
char last_char();
public: // syntax sugar
void append_indentation();
......
......@@ -6,17 +6,17 @@ namespace Sass {
template <typename T>
Environment<T>::Environment(bool is_shadow)
: local_frame_(std::map<std::string, T>()),
: local_frame_(environment_map<std::string, T>()),
parent_(0), is_shadow_(false)
{ }
template <typename T>
Environment<T>::Environment(Environment<T>* env, bool is_shadow)
: local_frame_(std::map<std::string, T>()),
: local_frame_(environment_map<std::string, T>()),
parent_(env), is_shadow_(is_shadow)
{ }
template <typename T>
Environment<T>::Environment(Environment<T>& env, bool is_shadow)
: local_frame_(std::map<std::string, T>()),
: local_frame_(environment_map<std::string, T>()),
parent_(&env), is_shadow_(is_shadow)
{ }
......@@ -45,7 +45,7 @@ namespace Sass {
}
template <typename T>
std::map<std::string, T>& Environment<T>::local_frame() {
environment_map<std::string, T>& Environment<T>::local_frame() {
return local_frame_;
}
......@@ -53,12 +53,25 @@ namespace Sass {
bool Environment<T>::has_local(const std::string& key) const
{ return local_frame_.find(key) != local_frame_.end(); }
template <typename T> EnvResult
Environment<T>::find_local(const std::string& key)
{
auto end = local_frame_.end();
auto it = local_frame_.find(key);
return EnvResult(it, it != end);
}
template <typename T>
T& Environment<T>::get_local(const std::string& key)
{ return local_frame_[key]; }
template <typename T>
void Environment<T>::set_local(const std::string& key, T val)
void Environment<T>::set_local(const std::string& key, const T& val)
{
local_frame_[key] = val;
}
template <typename T>
void Environment<T>::set_local(const std::string& key, T&& val)
{
local_frame_[key] = val;
}
......@@ -86,7 +99,12 @@ namespace Sass {
{ return (*global_env())[key]; }
template <typename T>
void Environment<T>::set_global(const std::string& key, T val)
void Environment<T>::set_global(const std::string& key, const T& val)
{
global_env()->local_frame_[key] = val;
}
template <typename T>
void Environment<T>::set_global(const std::string& key, T&& val)
{
global_env()->local_frame_[key] = val;
}
......@@ -126,12 +144,31 @@ namespace Sass {
// either update already existing lexical value
// or if flag is set, we create one if no lexical found
template <typename T>
void Environment<T>::set_lexical(const std::string& key, T val)
void Environment<T>::set_lexical(const std::string& key, const T& val)
{
auto cur = this; bool shadow = false;
while (cur->is_lexical() || shadow) {
if (cur->has_local(key)) {
cur->set_local(key, val);
Environment<T>* cur = this;
bool shadow = false;
while ((cur && cur->is_lexical()) || shadow) {
EnvResult rv(cur->find_local(key));
if (rv.found) {
rv.it->second = val;
return;
}
shadow = cur->is_shadow();
cur = cur->parent_;
}
set_local(key, val);
}
// this one moves the value
template <typename T>
void Environment<T>::set_lexical(const std::string& key, T&& val)
{
Environment<T>* cur = this;
bool shadow = false;
while ((cur && cur->is_lexical()) || shadow) {
EnvResult rv(cur->find_local(key));
if (rv.found) {
rv.it->second = val;
return;
}
shadow = cur->is_shadow();
......@@ -155,6 +192,20 @@ namespace Sass {
return false;
}
// look on the full stack for key
// include all scopes available
template <typename T> EnvResult
Environment<T>::find(const std::string& key)
{
auto cur = this;
while (true) {
EnvResult rv(cur->find_local(key));
if (rv.found) return rv;
cur = cur->parent_;
if (!cur) return rv;
}
};
// use array access for getter and setter functions
template <typename T>
T& Environment<T>::operator[](const std::string& key)
......@@ -168,7 +219,7 @@ namespace Sass {
}
return get_local(key);
}
/*
#ifdef DEBUG
template <typename T>
size_t Environment<T>::print(std::string prefix)
......@@ -176,7 +227,7 @@ namespace Sass {
size_t indent = 0;
if (parent_) indent = parent_->print(prefix) + 1;
std::cerr << prefix << std::string(indent, ' ') << "== " << this << std::endl;
for (typename std::map<std::string, T>::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) {
for (typename environment_map<std::string, T>::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) {
if (!ends_with(i->first, "[f]") && !ends_with(i->first, "[f]4") && !ends_with(i->first, "[f]2")) {
std::cerr << prefix << std::string(indent, ' ') << i->first << " " << i->second;
if (Value_Ptr val = Cast<Value>(i->second))
......@@ -187,7 +238,7 @@ namespace Sass {
return indent ;
}
#endif
*/
// compile implementation for AST_Node
template class Environment<AST_Node_Obj>;
......
......@@ -2,17 +2,26 @@
#define SASS_ENVIRONMENT_H
#include <string>
#include <map>
#include "ast_fwd_decl.hpp"
#include "ast_def_macros.hpp"
namespace Sass {
typedef environment_map<std::string, AST_Node_Obj>::iterator EnvIter;
class EnvResult {
public:
EnvIter it;
bool found;
public:
EnvResult(EnvIter it, bool found)
: it(it), found(found) {}
};
template <typename T>
class Environment {
// TODO: test with map
std::map<std::string, T> local_frame_;
environment_map<std::string, T> local_frame_;
ADD_PROPERTY(Environment*, parent)
ADD_PROPERTY(bool, is_shadow)
......@@ -37,14 +46,17 @@ namespace Sass {
// scope operates on the current frame
std::map<std::string, T>& local_frame();
environment_map<std::string, T>& local_frame();
bool has_local(const std::string& key) const;
EnvResult find_local(const std::string& key);
T& get_local(const std::string& key);
// set variable on the current frame
void set_local(const std::string& key, T val);
void set_local(const std::string& key, const T& val);
void set_local(const std::string& key, T&& val);
void del_local(const std::string& key);
......@@ -60,7 +72,8 @@ namespace Sass {
T& get_global(const std::string& key);
// set a variable on the global frame
void set_global(const std::string& key, T val);
void set_global(const std::string& key, const T& val);
void set_global(const std::string& key, T&& val);
void del_global(const std::string& key);
......@@ -72,12 +85,17 @@ namespace Sass {
// see if we have a lexical we could update
// either update already existing lexical value
// or we create a new one on the current frame
void set_lexical(const std::string& key, T val);
void set_lexical(const std::string& key, T&& val);
void set_lexical(const std::string& key, const T& val);
// look on the full stack for key
// include all scopes available
bool has(const std::string& key) const;
// look on the full stack for key
// include all scopes available
EnvResult find(const std::string& key);
// use array access for getter and setter functions
T& operator[](const std::string& key);
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment