sassc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +24 -0
  8. data/Rakefile +21 -0
  9. data/ext/libsass/.editorconfig +15 -0
  10. data/ext/libsass/.gitattributes +2 -0
  11. data/ext/libsass/.gitignore +61 -0
  12. data/ext/libsass/.travis.yml +38 -0
  13. data/ext/libsass/COPYING +25 -0
  14. data/ext/libsass/INSTALL +1 -0
  15. data/ext/libsass/LICENSE +25 -0
  16. data/ext/libsass/Makefile +223 -0
  17. data/ext/libsass/Makefile.am +145 -0
  18. data/ext/libsass/Readme.md +93 -0
  19. data/ext/libsass/appveyor.yml +76 -0
  20. data/ext/libsass/ast.cpp +581 -0
  21. data/ext/libsass/ast.hpp +1949 -0
  22. data/ext/libsass/ast_def_macros.hpp +16 -0
  23. data/ext/libsass/ast_factory.hpp +87 -0
  24. data/ext/libsass/ast_fwd_decl.hpp +72 -0
  25. data/ext/libsass/b64/cencode.h +32 -0
  26. data/ext/libsass/b64/encode.h +77 -0
  27. data/ext/libsass/backtrace.hpp +81 -0
  28. data/ext/libsass/base64vlq.cpp +43 -0
  29. data/ext/libsass/base64vlq.hpp +28 -0
  30. data/ext/libsass/bind.cpp +187 -0
  31. data/ext/libsass/bind.hpp +18 -0
  32. data/ext/libsass/cencode.c +102 -0
  33. data/ext/libsass/color_names.hpp +324 -0
  34. data/ext/libsass/configure.ac +130 -0
  35. data/ext/libsass/constants.cpp +144 -0
  36. data/ext/libsass/constants.hpp +145 -0
  37. data/ext/libsass/context.cpp +507 -0
  38. data/ext/libsass/context.hpp +150 -0
  39. data/ext/libsass/contextualize.cpp +157 -0
  40. data/ext/libsass/contextualize.hpp +65 -0
  41. data/ext/libsass/copy_c_str.cpp +13 -0
  42. data/ext/libsass/copy_c_str.hpp +5 -0
  43. data/ext/libsass/debug.hpp +39 -0
  44. data/ext/libsass/environment.hpp +75 -0
  45. data/ext/libsass/error_handling.cpp +28 -0
  46. data/ext/libsass/error_handling.hpp +28 -0
  47. data/ext/libsass/eval.cpp +1149 -0
  48. data/ext/libsass/eval.hpp +80 -0
  49. data/ext/libsass/expand.cpp +430 -0
  50. data/ext/libsass/expand.hpp +77 -0
  51. data/ext/libsass/extconf.rb +6 -0
  52. data/ext/libsass/extend.cpp +1962 -0
  53. data/ext/libsass/extend.hpp +50 -0
  54. data/ext/libsass/file.cpp +291 -0
  55. data/ext/libsass/file.hpp +18 -0
  56. data/ext/libsass/functions.cpp +1565 -0
  57. data/ext/libsass/functions.hpp +187 -0
  58. data/ext/libsass/inspect.cpp +727 -0
  59. data/ext/libsass/inspect.hpp +108 -0
  60. data/ext/libsass/json.cpp +1411 -0
  61. data/ext/libsass/json.hpp +117 -0
  62. data/ext/libsass/kwd_arg_macros.hpp +23 -0
  63. data/ext/libsass/m4/.gitkeep +0 -0
  64. data/ext/libsass/mapping.hpp +17 -0
  65. data/ext/libsass/memory_manager.hpp +54 -0
  66. data/ext/libsass/node.cpp +251 -0
  67. data/ext/libsass/node.hpp +122 -0
  68. data/ext/libsass/operation.hpp +153 -0
  69. data/ext/libsass/output_compressed.cpp +401 -0
  70. data/ext/libsass/output_compressed.hpp +95 -0
  71. data/ext/libsass/output_nested.cpp +364 -0
  72. data/ext/libsass/output_nested.hpp +108 -0
  73. data/ext/libsass/parser.cpp +2016 -0
  74. data/ext/libsass/parser.hpp +264 -0
  75. data/ext/libsass/paths.hpp +69 -0
  76. data/ext/libsass/position.hpp +22 -0
  77. data/ext/libsass/posix/getopt.c +562 -0
  78. data/ext/libsass/posix/getopt.h +95 -0
  79. data/ext/libsass/prelexer.cpp +688 -0
  80. data/ext/libsass/prelexer.hpp +513 -0
  81. data/ext/libsass/remove_placeholders.cpp +59 -0
  82. data/ext/libsass/remove_placeholders.hpp +43 -0
  83. data/ext/libsass/res/resource.rc +35 -0
  84. data/ext/libsass/sass.cpp +33 -0
  85. data/ext/libsass/sass.h +60 -0
  86. data/ext/libsass/sass2scss.cpp +834 -0
  87. data/ext/libsass/sass2scss.h +110 -0
  88. data/ext/libsass/sass_context.cpp +709 -0
  89. data/ext/libsass/sass_context.h +120 -0
  90. data/ext/libsass/sass_functions.cpp +137 -0
  91. data/ext/libsass/sass_functions.h +90 -0
  92. data/ext/libsass/sass_interface.cpp +277 -0
  93. data/ext/libsass/sass_interface.h +97 -0
  94. data/ext/libsass/sass_util.cpp +136 -0
  95. data/ext/libsass/sass_util.hpp +259 -0
  96. data/ext/libsass/sass_values.cpp +337 -0
  97. data/ext/libsass/sass_values.h +124 -0
  98. data/ext/libsass/script/bootstrap +10 -0
  99. data/ext/libsass/script/branding +10 -0
  100. data/ext/libsass/script/ci-build-libsass +72 -0
  101. data/ext/libsass/script/ci-install-compiler +4 -0
  102. data/ext/libsass/script/ci-install-deps +19 -0
  103. data/ext/libsass/script/ci-report-coverage +25 -0
  104. data/ext/libsass/script/coveralls-debug +32 -0
  105. data/ext/libsass/script/spec +5 -0
  106. data/ext/libsass/script/tap-driver +652 -0
  107. data/ext/libsass/script/tap-runner +1 -0
  108. data/ext/libsass/source_map.cpp +133 -0
  109. data/ext/libsass/source_map.hpp +46 -0
  110. data/ext/libsass/subset_map.hpp +145 -0
  111. data/ext/libsass/support/libsass.pc.in +11 -0
  112. data/ext/libsass/test-driver +127 -0
  113. data/ext/libsass/test/test_node.cpp +98 -0
  114. data/ext/libsass/test/test_paths.cpp +29 -0
  115. data/ext/libsass/test/test_selector_difference.cpp +28 -0
  116. data/ext/libsass/test/test_specificity.cpp +28 -0
  117. data/ext/libsass/test/test_subset_map.cpp +472 -0
  118. data/ext/libsass/test/test_superselector.cpp +71 -0
  119. data/ext/libsass/test/test_unification.cpp +33 -0
  120. data/ext/libsass/to_c.cpp +61 -0
  121. data/ext/libsass/to_c.hpp +44 -0
  122. data/ext/libsass/to_string.cpp +29 -0
  123. data/ext/libsass/to_string.hpp +32 -0
  124. data/ext/libsass/token.hpp +32 -0
  125. data/ext/libsass/units.cpp +54 -0
  126. data/ext/libsass/units.hpp +10 -0
  127. data/ext/libsass/utf8.h +34 -0
  128. data/ext/libsass/utf8/checked.h +327 -0
  129. data/ext/libsass/utf8/core.h +329 -0
  130. data/ext/libsass/utf8/unchecked.h +228 -0
  131. data/ext/libsass/utf8_string.cpp +102 -0
  132. data/ext/libsass/utf8_string.hpp +36 -0
  133. data/ext/libsass/util.cpp +189 -0
  134. data/ext/libsass/util.hpp +26 -0
  135. data/ext/libsass/win/libsass.filters +291 -0
  136. data/ext/libsass/win/libsass.sln +28 -0
  137. data/ext/libsass/win/libsass.vcxproj +255 -0
  138. data/lib/sassc.rb +6 -0
  139. data/lib/sassc/engine.rb +13 -0
  140. data/lib/sassc/native.rb +44 -0
  141. data/lib/sassc/native/native_context_api.rb +140 -0
  142. data/lib/sassc/native/native_functions_api.rb +41 -0
  143. data/lib/sassc/native/sass_input_style.rb +11 -0
  144. data/lib/sassc/native/sass_output_style.rb +10 -0
  145. data/lib/sassc/native/sass_value.rb +95 -0
  146. data/lib/sassc/native/string_list.rb +8 -0
  147. data/lib/sassc/version.rb +3 -0
  148. data/sassc.gemspec +43 -0
  149. data/test/smoke_test.rb +171 -0
  150. data/test/test_helper.rb +4 -0
  151. metadata +281 -0
@@ -0,0 +1,145 @@
1
+ ACLOCAL_AMFLAGS = -I m4
2
+
3
+ AM_LDFLAGS = -lstdc++ -lm
4
+ AM_CFLAGS = -Wall -fPIC
5
+ AM_CXXFLAGS = -Wall -fPIC
6
+ AM_CFLAGS += -DLIBSASS_VERSION="\"$(LIBSASS_VERSION)\""
7
+ AM_CXXFLAGS += -DLIBSASS_VERSION="\"$(LIBSASS_VERSION)\""
8
+
9
+ AM_CXXFLAGS += -std=c++0x
10
+
11
+ if ENABLE_COVERAGE
12
+ AM_CFLAGS += -O0 --coverage
13
+ AM_CXXFLAGS += -O0 --coverage
14
+ AM_LDFLAGS += -O0 --coverage -lgcov
15
+ else
16
+ AM_CFLAGS += -O2
17
+ AM_CXXFLAGS += -O2
18
+ AM_LDFLAGS += -O2
19
+ endif
20
+
21
+ VERSION = $(LIBSASS_VERSION)
22
+
23
+ EXTRA_DIST = \
24
+ COPYING \
25
+ INSTALL \
26
+ LICENSE \
27
+ Readme.md
28
+
29
+ pkgconfigdir = $(libdir)/pkgconfig
30
+ pkgconfig_DATA = support/libsass.pc
31
+
32
+ lib_LTLIBRARIES = libsass.la
33
+
34
+ libsass_la_SOURCES = \
35
+ ast_fwd_decl.hpp ast_def_macros.hpp \
36
+ kwd_arg_macros.hpp memory_manager.hpp \
37
+ position.hpp operation.hpp \
38
+ subset_map.hpp mapping.hpp \
39
+ color_names.hpp backtrace.hpp \
40
+ cencode.c b64/cencode.h b64/encode.h \
41
+ token.hpp environment.hpp \
42
+ paths.hpp debug.hpp \
43
+ utf8.h utf8/core.h \
44
+ utf8/checked.h utf8/unchecked.h \
45
+ ast.cpp ast.hpp \
46
+ base64vlq.cpp base64vlq.hpp \
47
+ bind.cpp bind.hpp \
48
+ constants.cpp constants.hpp \
49
+ context.cpp context.hpp \
50
+ contextualize.cpp contextualize.hpp \
51
+ copy_c_str.cpp copy_c_str.hpp \
52
+ error_handling.cpp error_handling.hpp \
53
+ eval.cpp eval.hpp \
54
+ expand.cpp expand.hpp \
55
+ extend.cpp extend.hpp \
56
+ file.cpp file.hpp \
57
+ functions.cpp functions.hpp \
58
+ inspect.cpp inspect.hpp \
59
+ node.cpp node.hpp \
60
+ json.cpp json.hpp \
61
+ output_compressed.cpp output_compressed.hpp \
62
+ output_nested.cpp output_nested.hpp \
63
+ parser.cpp parser.hpp \
64
+ prelexer.cpp prelexer.hpp \
65
+ remove_placeholders.cpp remove_placeholders.hpp \
66
+ sass.cpp sass.h \
67
+ sass_util.cpp sass_util.hpp \
68
+ sass_values.cpp sass_values.h \
69
+ sass_context.cpp sass_context.h \
70
+ sass_functions.cpp sass_functions.h \
71
+ sass_interface.cpp sass_interface.h \
72
+ sass2scss.cpp sass2scss.h \
73
+ source_map.cpp source_map.hpp \
74
+ to_c.cpp to_c.hpp \
75
+ to_string.cpp to_string.hpp \
76
+ units.cpp units.hpp \
77
+ utf8_string.cpp utf8_string.hpp \
78
+ util.cpp util.hpp
79
+
80
+ libsass_la_CFLAGS = $(AM_CFLAGS)
81
+ libsass_la_CXXFLAGS = $(AM_CXXFLAGS)
82
+ libsass_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 0:9:0
83
+
84
+ include_HEADERS = sass2scss.h sass_context.h sass_functions.h sass_values.h sass.h
85
+
86
+ if ENABLE_TESTS
87
+
88
+ noinst_PROGRAMS = sassc_bin
89
+
90
+ sassc_bin_SOURCES = $(SASS_SASSC_PATH)/sassc.c
91
+ sassc_bin_LDADD = libsass.la
92
+ sassc_bin_CFLAGS = $(AM_CFLAGS)
93
+ sassc_bin_CXXFLAGS = $(AM_CXXFLAGS)
94
+ sassc_bin_LDFLAGS = $(AM_LDFLAGS) -no-install
95
+
96
+ if ENABLE_COVERAGE
97
+ nodist_EXTRA_sassc_bin_SOURCES = non-existent-file-to-force-CXX-linking.cxx
98
+ nodist_EXTRA_libsass_la_SOURCES = non-existent-file-to-force-CXX-linking.cxx
99
+ endif
100
+
101
+ SASS_SASSC_PATH ?= sassc
102
+ SASS_SPEC_PATH ?= sass-spec
103
+ SASSC_BIN = $(SASS_SASSC_PATH)/bin/sassc
104
+
105
+ TESTS = \
106
+ $(SASS_SPEC_PATH)/spec/basic \
107
+ $(SASS_SPEC_PATH)/spec/css \
108
+ $(SASS_SPEC_PATH)/spec/extend-tests \
109
+ $(SASS_SPEC_PATH)/spec/extends \
110
+ $(SASS_SPEC_PATH)/spec/libsass \
111
+ $(SASS_SPEC_PATH)/spec/libsass-closed-issues \
112
+ $(SASS_SPEC_PATH)/spec/maps \
113
+ $(SASS_SPEC_PATH)/spec/misc \
114
+ $(SASS_SPEC_PATH)/spec/regressions \
115
+ $(SASS_SPEC_PATH)/spec/scss \
116
+ $(SASS_SPEC_PATH)/spec/scss-tests \
117
+ $(SASS_SPEC_PATH)/spec/types
118
+
119
+ SASS_TEST_FLAGS =
120
+ LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) ./script/tap-driver
121
+ AM_LOG_FLAGS = -c ./sassc_bin --ignore-todo $(LOG_FLAGS)
122
+ if USE_TAP
123
+ AM_LOG_FLAGS += -t
124
+ SASS_TEST_FLAGS += -t | tapout
125
+ LOG_COMPILER = ./script/tap-runner $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb
126
+ else
127
+ LOG_COMPILER = $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb
128
+ endif
129
+
130
+ $(SASSC_BIN): libsass.la
131
+ cd $(SASS_SASSC_PATH) && $(MAKE)
132
+
133
+ test: $(SASSC_BIN)
134
+ $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb -c $(SASSC_BIN) --ignore-todo $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
135
+
136
+ test_build: $(SASSC_BIN)
137
+ $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb -c $(SASSC_BIN) --ignore-todo $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
138
+
139
+ test_full: $(SASSC_BIN)
140
+ $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb -c $(SASSC_BIN) $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
141
+
142
+ test_issues: $(SASSC_BIN)
143
+ $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb -c $(SASSC_BIN) $(LOG_FLAGS) $(SASS_SPEC_PATH)/spec/issues $(SASS_TEST_FLAGS)
144
+
145
+ endif
@@ -0,0 +1,93 @@
1
+ Libsass
2
+ =======
3
+
4
+ by Aaron Leung ([@akhleung]) and Hampton Catlin ([@hcatlin])
5
+
6
+ [![Linux CI](https://travis-ci.org/sass/libsass.png?branch=master)](https://travis-ci.org/sass/libsass)
7
+ [![Windows CI](https://ci.appveyor.com/api/projects/status/github/sass/libsass?svg=true)](https://ci.appveyor.com/project/sass/libsass/branch/master)
8
+ [![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)
9
+ [![Coverage Status](https://img.shields.io/coveralls/sass/libsass.svg)](https://coveralls.io/r/sass/libsass?branch=feature%2Ftest-travis-ci-3)
10
+
11
+ https://github.com/sass/libsass
12
+
13
+ Libsass is just a library, but if you want to RUN libsass,
14
+ then go to https://github.com/sass/sassc or
15
+ https://github.com/sass/ruby-libsass or
16
+ [find your local implementer](https://github.com/sass/libsass/wiki/Implementations).
17
+
18
+ LibSass requires GCC 4.5+ or Clang/LLVM. If your OS is older, this version may not compile.
19
+
20
+ About
21
+ -----
22
+
23
+ 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.
24
+
25
+ This library strives to be light, simple, and easy to build and integrate with a variety of platforms and languages.
26
+
27
+ Developing
28
+ ----------
29
+
30
+ As you may have noticed, the libsass repo itself has
31
+ no executables and no tests. Oh noes! How can you develop???
32
+
33
+ Well, luckily, SassC is the official binary wrapper for
34
+ libsass and is *always* kept in sync. SassC uses a git submodule
35
+ to include libsass. When developing libsass, its best to actually
36
+ check out SassC and develop in that directory with the SassC spec
37
+ and tests there.
38
+
39
+ We even run Travis tests for SassC!
40
+
41
+ Tests
42
+ -------
43
+
44
+ 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.
45
+
46
+ 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.
47
+
48
+ Library Usage
49
+ -------------
50
+
51
+ While libsass is a library primarily written in C++, it provides a simple
52
+ C interface which should be used by most implementers. Libsass does not do
53
+ much on its own without an implementer. This can be a command line tool, like
54
+ [sassc](https://github.com/sass/sassc) or a [binding](https://github.com/sass/libsass/wiki/Implementations)
55
+ to your favorite programing language.
56
+
57
+ If you want to build or interface with libsass, we recommend to check out the
58
+ wiki pages about [building libsass](https://github.com/sass/libsass/wiki/Building-Libsass) and
59
+ the [C-API documentation](https://github.com/sass/libsass/wiki/API-Documentation).
60
+
61
+ About Sass
62
+ ----------
63
+
64
+ Sass is a CSS pre-processor language to add on exciting, new,
65
+ awesome features to CSS. Sass was the first language of its kind
66
+ and by far the most mature and up to date codebase.
67
+
68
+ Sass was originally created by the co-creator of this library,
69
+ Hampton Catlin ([@hcatlin]). The extension and continuing evolution
70
+ of the language has all been the result of years of work by Natalie
71
+ Weizenbaum ([@nex3]) and Chris Eppstein ([@chriseppstein]).
72
+
73
+ For more information about Sass itself, please visit http://sass-lang.com
74
+
75
+ Contribution Agreement
76
+ ----------------------
77
+
78
+ Any contribution to the project are seen as copyright assigned to Hampton Catlin, a
79
+ human on the planet earth. Your contribution warrants that you have the right to
80
+ assign copyright on your work. The intention here is to ensure that the project
81
+ remains totally free (liberal, like).
82
+
83
+ Our MIT license is designed to be as simple, and liberal as possible.
84
+
85
+ [@hcatlin]: https://github.com/hcatlin
86
+ [@akhleung]: https://github.com/akhleung
87
+ [@chriseppstein]: https://github.com/chriseppstein
88
+ [@nex3]: https://github.com/nex3
89
+
90
+ sass2scss was originally written by Marcel Greter [@mgreter]
91
+ and he happily agreed to have it merged into the project.
92
+
93
+ [sass_interface.h]: sass_interface.h
@@ -0,0 +1,76 @@
1
+ environment:
2
+ CTEST_OUTPUT_ON_FAILURE: 1
3
+ matrix:
4
+ - Compiler: mingw
5
+ Build: static
6
+ ruby_version: "21-x64"
7
+ - Compiler: mingw
8
+ Build: shared
9
+ ruby_version: "21-x64"
10
+ - Compiler: msvc
11
+ Config: Release
12
+ ruby_version: "21-x64"
13
+ - Compiler: msvc
14
+ Config: Debug
15
+ ruby_version: "21-x64"
16
+
17
+ cache:
18
+ - x86_64-4.9.2-release-win32-seh-rt_v3-rev0.7z
19
+ - C:\Ruby21-x64\lib\ruby\gems\2.1.0
20
+ - C:\Ruby21-x64\bin
21
+
22
+ install:
23
+ - git clone https://github.com/sass/sassc.git
24
+ - git clone https://github.com/sass/sass-spec.git
25
+ - set PATH=C:\Ruby%ruby_version%\bin;%PATH%
26
+ - set SASS_LIBSASS_PATH=..
27
+ - gem install minitest
28
+ - ps: |
29
+ if ($env:Compiler -eq "mingw") {
30
+ if (-Not (Test-Path "x86_64-4.9.2-release-win32-seh-rt_v3-rev0.7z")) {
31
+ # Install MinGW.
32
+ $url = "http://sourceforge.net/projects/mingw-w64/files/"
33
+ $url += "Toolchains%20targetting%20Win64/Personal%20Builds/"
34
+ $url += "mingw-builds/4.9.2/threads-win32/seh/"
35
+ $url += "x86_64-4.9.2-release-win32-seh-rt_v3-rev0.7z/download"
36
+ Invoke-WebRequest -UserAgent wget -Uri $url -OutFile x86_64-4.9.2-release-win32-seh-rt_v3-rev0.7z
37
+ }
38
+ &7z x -oC:\ x86_64-4.9.2-release-win32-seh-rt_v3-rev0.7z > $null
39
+ }
40
+ - set PATH=C:\mingw64\bin;%PATH%
41
+ - set CC=gcc
42
+
43
+ build_script:
44
+ - ps: |
45
+ if ($env:Compiler -eq "mingw") {
46
+ mingw32-make -j4 sassc
47
+ } else {
48
+ msbuild /m:4 /p:Configuration=$env:Config win\libsass.sln
49
+ }
50
+ - ps: |
51
+ if ($env:Compiler -eq "mingw") {
52
+ sassc\bin\sassc.exe -v
53
+ ruby -v
54
+ } else {
55
+ if ($env:Config -eq "Debug") {
56
+ win\bin\Debug\sassc.exe -v
57
+ ruby -v
58
+ } else {
59
+ win\bin\sassc.exe -v
60
+ ruby -v
61
+ }
62
+ }
63
+
64
+ test_script:
65
+ - ps: |
66
+ if ($env:Compiler -eq "mingw") {
67
+ ruby sass-spec\sass-spec.rb -c sassc\bin\sassc.exe -s --ignore-todo sass-spec/spec
68
+ } else {
69
+ if ($env:Config -eq "Debug") {
70
+ echo test runner in debug mode build via msvc will throw debug assertions
71
+ echo ruby sass-spec\sass-spec.rb -c win\bin\Debug\sassc.exe -s --ignore-todo sass-spec/spec
72
+ } else {
73
+ ruby sass-spec\sass-spec.rb -c win\bin\sassc.exe -s --ignore-todo sass-spec/spec
74
+ }
75
+ }
76
+
@@ -0,0 +1,581 @@
1
+ #include "ast.hpp"
2
+ #include "context.hpp"
3
+ #include "to_string.hpp"
4
+ #include <set>
5
+ #include <algorithm>
6
+ #include <iostream>
7
+
8
+ namespace Sass {
9
+ using namespace std;
10
+
11
+ bool Compound_Selector::operator<(const Compound_Selector& rhs) const
12
+ {
13
+ To_String to_string;
14
+ // ugly
15
+ return const_cast<Compound_Selector*>(this)->perform(&to_string) <
16
+ const_cast<Compound_Selector&>(rhs).perform(&to_string);
17
+ }
18
+
19
+ bool Complex_Selector::operator<(const Complex_Selector& rhs) const
20
+ {
21
+ To_String to_string;
22
+ return const_cast<Complex_Selector*>(this)->perform(&to_string) <
23
+ const_cast<Complex_Selector&>(rhs).perform(&to_string);
24
+ }
25
+
26
+ bool Complex_Selector::operator==(const Complex_Selector& rhs) const {
27
+ // TODO: We have to access the tail directly using tail_ since ADD_PROPERTY doesn't provide a const version.
28
+
29
+ const Complex_Selector* pOne = this;
30
+ const Complex_Selector* pTwo = &rhs;
31
+
32
+ // Consume any empty references at the beginning of the Complex_Selector
33
+ if (pOne->combinator() == Complex_Selector::ANCESTOR_OF && pOne->head()->is_empty_reference()) {
34
+ pOne = pOne->tail_;
35
+ }
36
+ if (pTwo->combinator() == Complex_Selector::ANCESTOR_OF && pTwo->head()->is_empty_reference()) {
37
+ pTwo = pTwo->tail_;
38
+ }
39
+
40
+ while (pOne && pTwo) {
41
+ if (pOne->combinator() != pTwo->combinator()) {
42
+ return false;
43
+ }
44
+
45
+ if (*(pOne->head()) != *(pTwo->head())) {
46
+ return false;
47
+ }
48
+
49
+ pOne = pOne->tail_;
50
+ pTwo = pTwo->tail_;
51
+ }
52
+
53
+ return pOne == NULL && pTwo == NULL;
54
+ }
55
+
56
+ Compound_Selector* Compound_Selector::unify_with(Compound_Selector* rhs, Context& ctx)
57
+ {
58
+ Compound_Selector* unified = rhs;
59
+ for (size_t i = 0, L = length(); i < L; ++i)
60
+ {
61
+ if (!unified) break;
62
+ else unified = (*this)[i]->unify_with(unified, ctx);
63
+ }
64
+ return unified;
65
+ }
66
+
67
+ bool Simple_Selector::operator==(const Simple_Selector& rhs) const
68
+ {
69
+ // Compare the string representations for equality.
70
+
71
+ // Cast away const here. To_String should take a const object, but it doesn't.
72
+ Simple_Selector* pLHS = const_cast<Simple_Selector*>(this);
73
+ Simple_Selector* pRHS = const_cast<Simple_Selector*>(&rhs);
74
+
75
+ To_String to_string;
76
+ return pLHS->perform(&to_string) == pRHS->perform(&to_string);
77
+ }
78
+
79
+ bool Simple_Selector::operator<(const Simple_Selector& rhs) const {
80
+ // Use the string representation for ordering.
81
+
82
+ // Cast away const here. To_String should take a const object, but it doesn't.
83
+ Simple_Selector* pLHS = const_cast<Simple_Selector*>(this);
84
+ Simple_Selector* pRHS = const_cast<Simple_Selector*>(&rhs);
85
+
86
+ To_String to_string;
87
+ return pLHS->perform(&to_string) < pRHS->perform(&to_string);
88
+ }
89
+
90
+ Compound_Selector* Simple_Selector::unify_with(Compound_Selector* rhs, Context& ctx)
91
+ {
92
+ To_String to_string;
93
+ for (size_t i = 0, L = rhs->length(); i < L; ++i)
94
+ { if (perform(&to_string) == (*rhs)[i]->perform(&to_string)) return rhs; }
95
+
96
+ // check for pseudo elements because they need to come last
97
+ size_t i, L;
98
+ bool found = false;
99
+ if (typeid(*this) == typeid(Pseudo_Selector) || typeid(*this) == typeid(Wrapped_Selector))
100
+ {
101
+ for (i = 0, L = rhs->length(); i < L; ++i)
102
+ {
103
+ if ((typeid(*(*rhs)[i]) == typeid(Pseudo_Selector) || typeid(*(*rhs)[i]) == typeid(Wrapped_Selector)) && (*rhs)[L-1]->is_pseudo_element())
104
+ { found = true; break; }
105
+ }
106
+ }
107
+ else
108
+ {
109
+ for (i = 0, L = rhs->length(); i < L; ++i)
110
+ {
111
+ if (typeid(*(*rhs)[i]) == typeid(Pseudo_Selector) || typeid(*(*rhs)[i]) == typeid(Wrapped_Selector))
112
+ { found = true; break; }
113
+ }
114
+ }
115
+ if (!found)
116
+ {
117
+ Compound_Selector* cpy = new (ctx.mem) Compound_Selector(*rhs);
118
+ (*cpy) << this;
119
+ return cpy;
120
+ }
121
+ Compound_Selector* cpy = new (ctx.mem) Compound_Selector(rhs->path(), rhs->position());
122
+ for (size_t j = 0; j < i; ++j)
123
+ { (*cpy) << (*rhs)[j]; }
124
+ (*cpy) << this;
125
+ for (size_t j = i; j < L; ++j)
126
+ { (*cpy) << (*rhs)[j]; }
127
+ return cpy;
128
+ }
129
+
130
+ Compound_Selector* Type_Selector::unify_with(Compound_Selector* rhs, Context& ctx)
131
+ {
132
+ // TODO: handle namespaces
133
+
134
+ // if the rhs is empty, just return a copy of this
135
+ if (rhs->length() == 0) {
136
+ Compound_Selector* cpy = new (ctx.mem) Compound_Selector(rhs->path(), rhs->position());
137
+ (*cpy) << this;
138
+ return cpy;
139
+ }
140
+
141
+ // if this is a universal selector and rhs is not empty, just return the rhs
142
+ if (name() == "*")
143
+ { return new (ctx.mem) Compound_Selector(*rhs); }
144
+
145
+
146
+ Simple_Selector* rhs_0 = (*rhs)[0];
147
+ // otherwise, this is a tag name
148
+ if (typeid(*rhs_0) == typeid(Type_Selector))
149
+ {
150
+ // if rhs is universal, just return this tagname + rhs's qualifiers
151
+ if (static_cast<Type_Selector*>(rhs_0)->name() == "*")
152
+ {
153
+ Compound_Selector* cpy = new (ctx.mem) Compound_Selector(rhs->path(), rhs->position());
154
+ (*cpy) << this;
155
+ for (size_t i = 1, L = rhs->length(); i < L; ++i)
156
+ { (*cpy) << (*rhs)[i]; }
157
+ return cpy;
158
+ }
159
+ // if rhs is another tag name and it matches this, return rhs
160
+ else if (static_cast<Type_Selector*>(rhs_0)->name() == name())
161
+ { return new (ctx.mem) Compound_Selector(*rhs); }
162
+ // else the tag names don't match; return nil
163
+ else
164
+ { return 0; }
165
+ }
166
+ // else it's a tag name and a bunch of qualifiers -- just append them
167
+ Compound_Selector* cpy = new (ctx.mem) Compound_Selector(rhs->path(), rhs->position());
168
+ (*cpy) << this;
169
+ (*cpy) += rhs;
170
+ return cpy;
171
+ }
172
+
173
+ Compound_Selector* Selector_Qualifier::unify_with(Compound_Selector* rhs, Context& ctx)
174
+ {
175
+ if (name()[0] == '#')
176
+ {
177
+ for (size_t i = 0, L = rhs->length(); i < L; ++i)
178
+ {
179
+ Simple_Selector* rhs_i = (*rhs)[i];
180
+ if (typeid(*rhs_i) == typeid(Selector_Qualifier) &&
181
+ static_cast<Selector_Qualifier*>(rhs_i)->name()[0] == '#' &&
182
+ static_cast<Selector_Qualifier*>(rhs_i)->name() != name())
183
+ return 0;
184
+ }
185
+ }
186
+ return Simple_Selector::unify_with(rhs, ctx);
187
+ }
188
+
189
+ Compound_Selector* Pseudo_Selector::unify_with(Compound_Selector* rhs, Context& ctx)
190
+ {
191
+ if (is_pseudo_element())
192
+ {
193
+ for (size_t i = 0, L = rhs->length(); i < L; ++i)
194
+ {
195
+ Simple_Selector* rhs_i = (*rhs)[i];
196
+ if (typeid(*rhs_i) == typeid(Pseudo_Selector) &&
197
+ static_cast<Pseudo_Selector*>(rhs_i)->is_pseudo_element() &&
198
+ static_cast<Pseudo_Selector*>(rhs_i)->name() != name())
199
+ { return 0; }
200
+ }
201
+ }
202
+ return Simple_Selector::unify_with(rhs, ctx);
203
+ }
204
+
205
+ bool Compound_Selector::is_superselector_of(Compound_Selector* rhs)
206
+ {
207
+ To_String to_string;
208
+
209
+ Simple_Selector* lbase = base();
210
+ Simple_Selector* rbase = rhs->base();
211
+
212
+ // Check if pseudo-elements are the same between the selectors
213
+
214
+ set<string> lpsuedoset, rpsuedoset;
215
+ for (size_t i = 0, L = length(); i < L; ++i)
216
+ {
217
+ if ((*this)[i]->is_pseudo_element()) {
218
+ string pseudo((*this)[i]->perform(&to_string));
219
+ pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
220
+ lpsuedoset.insert(pseudo);
221
+ }
222
+ }
223
+ for (size_t i = 0, L = rhs->length(); i < L; ++i)
224
+ {
225
+ if ((*rhs)[i]->is_pseudo_element()) {
226
+ string pseudo((*rhs)[i]->perform(&to_string));
227
+ pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
228
+ rpsuedoset.insert(pseudo);
229
+ }
230
+ }
231
+ if (lpsuedoset != rpsuedoset) {
232
+ return false;
233
+ }
234
+
235
+ // Check the Simple_Selectors
236
+
237
+ set<string> lset, rset;
238
+
239
+ if (!lbase) // no lbase; just see if the left-hand qualifiers are a subset of the right-hand selector
240
+ {
241
+ for (size_t i = 0, L = length(); i < L; ++i)
242
+ { lset.insert((*this)[i]->perform(&to_string)); }
243
+ for (size_t i = 0, L = rhs->length(); i < L; ++i)
244
+ { rset.insert((*rhs)[i]->perform(&to_string)); }
245
+ return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
246
+ }
247
+ else { // there's an lbase
248
+ for (size_t i = 1, L = length(); i < L; ++i)
249
+ { lset.insert((*this)[i]->perform(&to_string)); }
250
+ if (rbase)
251
+ {
252
+ if (lbase->perform(&to_string) != rbase->perform(&to_string)) // if there's an rbase, make sure they match
253
+ { return false; }
254
+ else // the bases do match, so compare qualifiers
255
+ {
256
+ for (size_t i = 1, L = rhs->length(); i < L; ++i)
257
+ { rset.insert((*rhs)[i]->perform(&to_string)); }
258
+ return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
259
+ }
260
+ }
261
+ }
262
+ // catch-all
263
+ return false;
264
+ }
265
+
266
+ bool Compound_Selector::operator==(const Compound_Selector& rhs) const {
267
+ To_String to_string;
268
+
269
+ // Check if pseudo-elements are the same between the selectors
270
+
271
+ set<string> lpsuedoset, rpsuedoset;
272
+ for (size_t i = 0, L = length(); i < L; ++i)
273
+ {
274
+ if ((*this)[i]->is_pseudo_element()) {
275
+ string pseudo((*this)[i]->perform(&to_string));
276
+ pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
277
+ lpsuedoset.insert(pseudo);
278
+ }
279
+ }
280
+ for (size_t i = 0, L = rhs.length(); i < L; ++i)
281
+ {
282
+ if (rhs[i]->is_pseudo_element()) {
283
+ string pseudo(rhs[i]->perform(&to_string));
284
+ pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
285
+ rpsuedoset.insert(pseudo);
286
+ }
287
+ }
288
+ if (lpsuedoset != rpsuedoset) {
289
+ return false;
290
+ }
291
+
292
+ // Check the base
293
+
294
+ const Simple_Selector* const lbase = base();
295
+ const Simple_Selector* const rbase = rhs.base();
296
+
297
+ if ((lbase && !rbase) ||
298
+ (!lbase && rbase) ||
299
+ ((lbase && rbase) && (*lbase != *rbase))) {
300
+ return false;
301
+ }
302
+
303
+
304
+ // Check the rest of the SimpleSelectors
305
+ // Use string representations. We can't create a set of Simple_Selector pointers because std::set == std::set is going to call ==
306
+ // on the pointers to determine equality. I don't know of a way to pass in a comparison object. The one you can specify as part of
307
+ // the template type is used for ordering, but not equality. We also can't just put in non-pointer Simple_Selectors because the
308
+ // class is intended to be subclassed, and we'd get splicing.
309
+
310
+ set<string> lset, rset;
311
+
312
+ for (size_t i = 0, L = length(); i < L; ++i)
313
+ { lset.insert((*this)[i]->perform(&to_string)); }
314
+ for (size_t i = 0, L = rhs.length(); i < L; ++i)
315
+ { rset.insert(rhs[i]->perform(&to_string)); }
316
+
317
+ return lset == rset;
318
+ }
319
+
320
+ bool Complex_Selector_Pointer_Compare::operator() (const Complex_Selector* const pLeft, const Complex_Selector* const pRight) const {
321
+ return *pLeft < *pRight;
322
+ }
323
+
324
+ bool Complex_Selector::is_superselector_of(Compound_Selector* rhs)
325
+ {
326
+ if (length() != 1)
327
+ { return false; }
328
+ return base()->is_superselector_of(rhs);
329
+ }
330
+
331
+ bool Complex_Selector::is_superselector_of(Complex_Selector* rhs)
332
+ {
333
+ Complex_Selector* lhs = this;
334
+ To_String to_string;
335
+ // check for selectors with leading or trailing combinators
336
+ if (!lhs->head() || !rhs->head())
337
+ { return false; }
338
+ Complex_Selector* l_innermost = lhs->innermost();
339
+ if (l_innermost->combinator() != Complex_Selector::ANCESTOR_OF && !l_innermost->tail())
340
+ { return false; }
341
+ Complex_Selector* r_innermost = rhs->innermost();
342
+ if (r_innermost->combinator() != Complex_Selector::ANCESTOR_OF && !r_innermost->tail())
343
+ { return false; }
344
+ // more complex (i.e., longer) selectors are always more specific
345
+ size_t l_len = lhs->length(), r_len = rhs->length();
346
+ if (l_len > r_len)
347
+ { return false; }
348
+
349
+ if (l_len == 1)
350
+ { return lhs->head()->is_superselector_of(rhs->base()); }
351
+
352
+ bool found = false;
353
+ Complex_Selector* marker = rhs;
354
+ for (size_t i = 0, L = rhs->length(); i < L; ++i) {
355
+ if (i == L-1)
356
+ { return false; }
357
+ if (lhs->head()->is_superselector_of(marker->head()))
358
+ { found = true; break; }
359
+ marker = marker->tail();
360
+ }
361
+ if (!found)
362
+ { return false; }
363
+
364
+ /*
365
+ Hmm, I hope I have the logic right:
366
+
367
+ if lhs has a combinator:
368
+ if !(marker has a combinator) return false
369
+ if !(lhs.combinator == '~' ? marker.combinator != '>' : lhs.combinator == marker.combinator) return false
370
+ return lhs.tail-without-innermost.is_superselector_of(marker.tail-without-innermost)
371
+ else if marker has a combinator:
372
+ if !(marker.combinator == ">") return false
373
+ return lhs.tail.is_superselector_of(marker.tail)
374
+ else
375
+ return lhs.tail.is_superselector_of(marker.tail)
376
+ */
377
+ if (lhs->combinator() != Complex_Selector::ANCESTOR_OF)
378
+ {
379
+ if (marker->combinator() == Complex_Selector::ANCESTOR_OF)
380
+ { return false; }
381
+ if (!(lhs->combinator() == Complex_Selector::PRECEDES ? marker->combinator() != Complex_Selector::PARENT_OF : lhs->combinator() == marker->combinator()))
382
+ { return false; }
383
+ return lhs->tail()->is_superselector_of(marker->tail());
384
+ }
385
+ else if (marker->combinator() != Complex_Selector::ANCESTOR_OF)
386
+ {
387
+ if (marker->combinator() != Complex_Selector::PARENT_OF)
388
+ { return false; }
389
+ return lhs->tail()->is_superselector_of(marker->tail());
390
+ }
391
+ else
392
+ {
393
+ return lhs->tail()->is_superselector_of(marker->tail());
394
+ }
395
+ // catch-all
396
+ return false;
397
+ }
398
+
399
+ size_t Complex_Selector::length()
400
+ {
401
+ // TODO: make this iterative
402
+ if (!tail()) return 1;
403
+ return 1 + tail()->length();
404
+ }
405
+
406
+ Compound_Selector* Complex_Selector::base()
407
+ {
408
+ if (!tail()) return head();
409
+ else return tail()->base();
410
+ }
411
+
412
+ Complex_Selector* Complex_Selector::context(Context& ctx)
413
+ {
414
+ if (!tail()) return 0;
415
+ if (!head()) return tail()->context(ctx);
416
+ return new (ctx.mem) Complex_Selector(path(), position(), combinator(), head(), tail()->context(ctx));
417
+ }
418
+
419
+ Complex_Selector* Complex_Selector::innermost()
420
+ {
421
+ if (!tail()) return this;
422
+ else return tail()->innermost();
423
+ }
424
+
425
+ Complex_Selector::Combinator Complex_Selector::clear_innermost()
426
+ {
427
+ Combinator c;
428
+ if (!tail() || tail()->length() == 1)
429
+ { c = combinator(); combinator(ANCESTOR_OF); tail(0); }
430
+ else
431
+ { c = tail()->clear_innermost(); }
432
+ return c;
433
+ }
434
+
435
+ void Complex_Selector::set_innermost(Complex_Selector* val, Combinator c)
436
+ {
437
+ if (!tail())
438
+ { tail(val); combinator(c); }
439
+ else
440
+ { tail()->set_innermost(val, c); }
441
+ }
442
+
443
+ Complex_Selector* Complex_Selector::clone(Context& ctx) const
444
+ {
445
+ Complex_Selector* cpy = new (ctx.mem) Complex_Selector(*this);
446
+ if (tail()) cpy->tail(tail()->clone(ctx));
447
+ return cpy;
448
+ }
449
+
450
+ Complex_Selector* Complex_Selector::cloneFully(Context& ctx) const
451
+ {
452
+ Complex_Selector* cpy = new (ctx.mem) Complex_Selector(*this);
453
+
454
+ if (head()) {
455
+ cpy->head(head()->clone(ctx));
456
+ }
457
+
458
+ if (tail()) {
459
+ cpy->tail(tail()->cloneFully(ctx));
460
+ }
461
+
462
+ return cpy;
463
+ }
464
+
465
+ Compound_Selector* Compound_Selector::clone(Context& ctx) const
466
+ {
467
+ Compound_Selector* cpy = new (ctx.mem) Compound_Selector(*this);
468
+ return cpy;
469
+ }
470
+
471
+
472
+
473
+ Selector_Placeholder* Selector::find_placeholder()
474
+ {
475
+ return 0;
476
+ }
477
+
478
+ void Selector_List::adjust_after_pushing(Complex_Selector* c)
479
+ {
480
+ if (c->has_reference()) has_reference(true);
481
+ if (c->has_placeholder()) has_placeholder(true);
482
+
483
+ #ifdef DEBUG
484
+ To_String to_string;
485
+ this->mCachedSelector(this->perform(&to_string));
486
+ #endif
487
+ }
488
+
489
+ Selector_Placeholder* Selector_List::find_placeholder()
490
+ {
491
+ if (has_placeholder()) {
492
+ for (size_t i = 0, L = length(); i < L; ++i) {
493
+ if ((*this)[i]->has_placeholder()) return (*this)[i]->find_placeholder();
494
+ }
495
+ }
496
+ return 0;
497
+ }
498
+
499
+ Selector_Placeholder* Complex_Selector::find_placeholder()
500
+ {
501
+ if (has_placeholder()) {
502
+ if (head() && head()->has_placeholder()) return head()->find_placeholder();
503
+ else if (tail() && tail()->has_placeholder()) return tail()->find_placeholder();
504
+ }
505
+ return 0;
506
+ }
507
+
508
+ Selector_Placeholder* Compound_Selector::find_placeholder()
509
+ {
510
+ if (has_placeholder()) {
511
+ for (size_t i = 0, L = length(); i < L; ++i) {
512
+ if ((*this)[i]->has_placeholder()) return (*this)[i]->find_placeholder();
513
+ }
514
+ // return this;
515
+ }
516
+ return 0;
517
+ }
518
+
519
+ Selector_Placeholder* Selector_Placeholder::find_placeholder()
520
+ {
521
+ return this;
522
+ }
523
+
524
+ vector<string> Compound_Selector::to_str_vec()
525
+ {
526
+ To_String to_string;
527
+ vector<string> result;
528
+ result.reserve(length());
529
+ for (size_t i = 0, L = length(); i < L; ++i)
530
+ { result.push_back((*this)[i]->perform(&to_string)); }
531
+ return result;
532
+ }
533
+
534
+ Compound_Selector* Compound_Selector::minus(Compound_Selector* rhs, Context& ctx)
535
+ {
536
+ To_String to_string;
537
+ Compound_Selector* result = new (ctx.mem) Compound_Selector(path(), position());
538
+
539
+ // not very efficient because it needs to preserve order
540
+ for (size_t i = 0, L = length(); i < L; ++i)
541
+ {
542
+ bool found = false;
543
+ string thisSelector((*this)[i]->perform(&to_string));
544
+ for (size_t j = 0, M = rhs->length(); j < M; ++j)
545
+ {
546
+ if (thisSelector == (*rhs)[j]->perform(&to_string))
547
+ {
548
+ found = true;
549
+ break;
550
+ }
551
+ }
552
+ if (!found) (*result) << (*this)[i];
553
+ }
554
+
555
+ return result;
556
+ }
557
+
558
+ void Compound_Selector::mergeSources(SourcesSet& sources, Context& ctx)
559
+ {
560
+ for (SourcesSet::iterator iterator = sources.begin(), endIterator = sources.end(); iterator != endIterator; ++iterator) {
561
+ this->sources_.insert((*iterator)->clone(ctx));
562
+ }
563
+ }
564
+
565
+ vector<Compound_Selector*> Complex_Selector::to_vector()
566
+ {
567
+ vector<Compound_Selector*> result;
568
+ Compound_Selector* h = head();
569
+ Complex_Selector* t = tail();
570
+ if (h) result.push_back(h);
571
+ while (t)
572
+ {
573
+ h = t->head();
574
+ t = t->tail();
575
+ if (h) result.push_back(h);
576
+ }
577
+ return result;
578
+ }
579
+
580
+ }
581
+