sassc4 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +16 -0
  5. data/CHANGELOG.md +97 -0
  6. data/CODE_OF_CONDUCT.md +10 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +80 -0
  10. data/Rakefile +51 -0
  11. data/ext/depend +4 -0
  12. data/ext/extconf.rb +92 -0
  13. data/ext/libsass/VERSION +1 -0
  14. data/ext/libsass/contrib/plugin.cpp +60 -0
  15. data/ext/libsass/include/sass/base.h +97 -0
  16. data/ext/libsass/include/sass/context.h +174 -0
  17. data/ext/libsass/include/sass/functions.h +139 -0
  18. data/ext/libsass/include/sass/values.h +145 -0
  19. data/ext/libsass/include/sass/version.h +12 -0
  20. data/ext/libsass/include/sass.h +15 -0
  21. data/ext/libsass/include/sass2scss.h +120 -0
  22. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  23. data/ext/libsass/src/ast.cpp +953 -0
  24. data/ext/libsass/src/ast.hpp +1064 -0
  25. data/ext/libsass/src/ast2c.cpp +80 -0
  26. data/ext/libsass/src/ast2c.hpp +39 -0
  27. data/ext/libsass/src/ast_def_macros.hpp +140 -0
  28. data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
  29. data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
  30. data/ext/libsass/src/ast_helpers.hpp +316 -0
  31. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  32. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  33. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  34. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  35. data/ext/libsass/src/ast_selectors.cpp +1070 -0
  36. data/ext/libsass/src/ast_selectors.hpp +523 -0
  37. data/ext/libsass/src/ast_supports.cpp +114 -0
  38. data/ext/libsass/src/ast_supports.hpp +121 -0
  39. data/ext/libsass/src/ast_values.cpp +1154 -0
  40. data/ext/libsass/src/ast_values.hpp +498 -0
  41. data/ext/libsass/src/b64/cencode.h +32 -0
  42. data/ext/libsass/src/b64/encode.h +79 -0
  43. data/ext/libsass/src/backtrace.cpp +50 -0
  44. data/ext/libsass/src/backtrace.hpp +29 -0
  45. data/ext/libsass/src/base64vlq.cpp +47 -0
  46. data/ext/libsass/src/base64vlq.hpp +30 -0
  47. data/ext/libsass/src/bind.cpp +312 -0
  48. data/ext/libsass/src/bind.hpp +15 -0
  49. data/ext/libsass/src/c2ast.cpp +64 -0
  50. data/ext/libsass/src/c2ast.hpp +14 -0
  51. data/ext/libsass/src/c99func.c +54 -0
  52. data/ext/libsass/src/cencode.c +106 -0
  53. data/ext/libsass/src/check_nesting.cpp +393 -0
  54. data/ext/libsass/src/check_nesting.hpp +70 -0
  55. data/ext/libsass/src/color_maps.cpp +652 -0
  56. data/ext/libsass/src/color_maps.hpp +323 -0
  57. data/ext/libsass/src/color_spaces.cpp +241 -0
  58. data/ext/libsass/src/color_spaces.hpp +227 -0
  59. data/ext/libsass/src/constants.cpp +199 -0
  60. data/ext/libsass/src/constants.hpp +200 -0
  61. data/ext/libsass/src/context.cpp +870 -0
  62. data/ext/libsass/src/context.hpp +140 -0
  63. data/ext/libsass/src/cssize.cpp +521 -0
  64. data/ext/libsass/src/cssize.hpp +71 -0
  65. data/ext/libsass/src/dart_helpers.hpp +199 -0
  66. data/ext/libsass/src/debug.hpp +43 -0
  67. data/ext/libsass/src/debugger.hpp +964 -0
  68. data/ext/libsass/src/emitter.cpp +297 -0
  69. data/ext/libsass/src/emitter.hpp +101 -0
  70. data/ext/libsass/src/environment.cpp +260 -0
  71. data/ext/libsass/src/environment.hpp +124 -0
  72. data/ext/libsass/src/error_handling.cpp +239 -0
  73. data/ext/libsass/src/error_handling.hpp +248 -0
  74. data/ext/libsass/src/eval.cpp +1543 -0
  75. data/ext/libsass/src/eval.hpp +110 -0
  76. data/ext/libsass/src/eval_selectors.cpp +75 -0
  77. data/ext/libsass/src/expand.cpp +875 -0
  78. data/ext/libsass/src/expand.hpp +98 -0
  79. data/ext/libsass/src/extender.cpp +1226 -0
  80. data/ext/libsass/src/extender.hpp +399 -0
  81. data/ext/libsass/src/extension.cpp +43 -0
  82. data/ext/libsass/src/extension.hpp +89 -0
  83. data/ext/libsass/src/file.cpp +531 -0
  84. data/ext/libsass/src/file.hpp +124 -0
  85. data/ext/libsass/src/fn_colors.cpp +836 -0
  86. data/ext/libsass/src/fn_colors.hpp +99 -0
  87. data/ext/libsass/src/fn_lists.cpp +285 -0
  88. data/ext/libsass/src/fn_lists.hpp +34 -0
  89. data/ext/libsass/src/fn_maps.cpp +94 -0
  90. data/ext/libsass/src/fn_maps.hpp +30 -0
  91. data/ext/libsass/src/fn_miscs.cpp +248 -0
  92. data/ext/libsass/src/fn_miscs.hpp +40 -0
  93. data/ext/libsass/src/fn_numbers.cpp +246 -0
  94. data/ext/libsass/src/fn_numbers.hpp +45 -0
  95. data/ext/libsass/src/fn_selectors.cpp +205 -0
  96. data/ext/libsass/src/fn_selectors.hpp +35 -0
  97. data/ext/libsass/src/fn_strings.cpp +268 -0
  98. data/ext/libsass/src/fn_strings.hpp +34 -0
  99. data/ext/libsass/src/fn_utils.cpp +159 -0
  100. data/ext/libsass/src/fn_utils.hpp +62 -0
  101. data/ext/libsass/src/inspect.cpp +1126 -0
  102. data/ext/libsass/src/inspect.hpp +101 -0
  103. data/ext/libsass/src/json.cpp +1436 -0
  104. data/ext/libsass/src/json.hpp +117 -0
  105. data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
  106. data/ext/libsass/src/lexer.cpp +122 -0
  107. data/ext/libsass/src/lexer.hpp +304 -0
  108. data/ext/libsass/src/listize.cpp +70 -0
  109. data/ext/libsass/src/listize.hpp +37 -0
  110. data/ext/libsass/src/mapping.hpp +19 -0
  111. data/ext/libsass/src/memory/allocator.cpp +48 -0
  112. data/ext/libsass/src/memory/allocator.hpp +138 -0
  113. data/ext/libsass/src/memory/config.hpp +20 -0
  114. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  115. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  116. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  117. data/ext/libsass/src/memory.hpp +12 -0
  118. data/ext/libsass/src/operation.hpp +223 -0
  119. data/ext/libsass/src/operators.cpp +267 -0
  120. data/ext/libsass/src/operators.hpp +30 -0
  121. data/ext/libsass/src/ordered_map.hpp +112 -0
  122. data/ext/libsass/src/output.cpp +320 -0
  123. data/ext/libsass/src/output.hpp +47 -0
  124. data/ext/libsass/src/parser.cpp +3059 -0
  125. data/ext/libsass/src/parser.hpp +395 -0
  126. data/ext/libsass/src/parser_selectors.cpp +189 -0
  127. data/ext/libsass/src/permutate.hpp +164 -0
  128. data/ext/libsass/src/plugins.cpp +188 -0
  129. data/ext/libsass/src/plugins.hpp +57 -0
  130. data/ext/libsass/src/position.cpp +163 -0
  131. data/ext/libsass/src/position.hpp +147 -0
  132. data/ext/libsass/src/prelexer.cpp +1780 -0
  133. data/ext/libsass/src/prelexer.hpp +484 -0
  134. data/ext/libsass/src/remove_placeholders.cpp +86 -0
  135. data/ext/libsass/src/remove_placeholders.hpp +37 -0
  136. data/ext/libsass/src/sass.cpp +156 -0
  137. data/ext/libsass/src/sass.hpp +147 -0
  138. data/ext/libsass/src/sass2scss.cpp +895 -0
  139. data/ext/libsass/src/sass_context.cpp +742 -0
  140. data/ext/libsass/src/sass_context.hpp +129 -0
  141. data/ext/libsass/src/sass_functions.cpp +210 -0
  142. data/ext/libsass/src/sass_functions.hpp +50 -0
  143. data/ext/libsass/src/sass_values.cpp +362 -0
  144. data/ext/libsass/src/sass_values.hpp +82 -0
  145. data/ext/libsass/src/settings.hpp +19 -0
  146. data/ext/libsass/src/source.cpp +69 -0
  147. data/ext/libsass/src/source.hpp +95 -0
  148. data/ext/libsass/src/source_data.hpp +32 -0
  149. data/ext/libsass/src/source_map.cpp +202 -0
  150. data/ext/libsass/src/source_map.hpp +65 -0
  151. data/ext/libsass/src/stylesheet.cpp +22 -0
  152. data/ext/libsass/src/stylesheet.hpp +57 -0
  153. data/ext/libsass/src/to_value.cpp +114 -0
  154. data/ext/libsass/src/to_value.hpp +46 -0
  155. data/ext/libsass/src/units.cpp +507 -0
  156. data/ext/libsass/src/units.hpp +110 -0
  157. data/ext/libsass/src/utf8/checked.h +336 -0
  158. data/ext/libsass/src/utf8/core.h +332 -0
  159. data/ext/libsass/src/utf8/unchecked.h +235 -0
  160. data/ext/libsass/src/utf8.h +34 -0
  161. data/ext/libsass/src/utf8_string.cpp +104 -0
  162. data/ext/libsass/src/utf8_string.hpp +38 -0
  163. data/ext/libsass/src/util.cpp +723 -0
  164. data/ext/libsass/src/util.hpp +105 -0
  165. data/ext/libsass/src/util_string.cpp +125 -0
  166. data/ext/libsass/src/util_string.hpp +73 -0
  167. data/ext/libsass/src/values.cpp +140 -0
  168. data/ext/libsass/src/values.hpp +12 -0
  169. data/lib/sassc/dependency.rb +17 -0
  170. data/lib/sassc/engine.rb +141 -0
  171. data/lib/sassc/error.rb +37 -0
  172. data/lib/sassc/functions_handler.rb +73 -0
  173. data/lib/sassc/import_handler.rb +50 -0
  174. data/lib/sassc/importer.rb +31 -0
  175. data/lib/sassc/native/native_context_api.rb +147 -0
  176. data/lib/sassc/native/native_functions_api.rb +159 -0
  177. data/lib/sassc/native/sass2scss_api.rb +10 -0
  178. data/lib/sassc/native/sass_input_style.rb +13 -0
  179. data/lib/sassc/native/sass_output_style.rb +12 -0
  180. data/lib/sassc/native/sass_value.rb +97 -0
  181. data/lib/sassc/native/string_list.rb +10 -0
  182. data/lib/sassc/native.rb +64 -0
  183. data/lib/sassc/sass_2_scss.rb +9 -0
  184. data/lib/sassc/script/functions.rb +8 -0
  185. data/lib/sassc/script/value/bool.rb +32 -0
  186. data/lib/sassc/script/value/color.rb +95 -0
  187. data/lib/sassc/script/value/list.rb +136 -0
  188. data/lib/sassc/script/value/map.rb +69 -0
  189. data/lib/sassc/script/value/number.rb +389 -0
  190. data/lib/sassc/script/value/string.rb +96 -0
  191. data/lib/sassc/script/value.rb +137 -0
  192. data/lib/sassc/script/value_conversion/base.rb +13 -0
  193. data/lib/sassc/script/value_conversion/bool.rb +13 -0
  194. data/lib/sassc/script/value_conversion/color.rb +18 -0
  195. data/lib/sassc/script/value_conversion/list.rb +25 -0
  196. data/lib/sassc/script/value_conversion/map.rb +21 -0
  197. data/lib/sassc/script/value_conversion/number.rb +13 -0
  198. data/lib/sassc/script/value_conversion/string.rb +17 -0
  199. data/lib/sassc/script/value_conversion.rb +69 -0
  200. data/lib/sassc/script.rb +17 -0
  201. data/lib/sassc/util/normalized_map.rb +117 -0
  202. data/lib/sassc/util.rb +231 -0
  203. data/lib/sassc/version.rb +5 -0
  204. data/lib/sassc.rb +57 -0
  205. data/sassc.gemspec +69 -0
  206. data/test/css_color_level4_test.rb +168 -0
  207. data/test/custom_importer_test.rb +127 -0
  208. data/test/engine_test.rb +314 -0
  209. data/test/error_test.rb +29 -0
  210. data/test/fixtures/paths.scss +10 -0
  211. data/test/functions_test.rb +340 -0
  212. data/test/native_test.rb +213 -0
  213. data/test/output_style_test.rb +107 -0
  214. data/test/sass_2_scss_test.rb +14 -0
  215. data/test/test_helper.rb +45 -0
  216. metadata +396 -0
@@ -0,0 +1,395 @@
1
+ #ifndef SASS_PARSER_H
2
+ #define SASS_PARSER_H
3
+
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
7
+
8
+ #include <string>
9
+ #include <vector>
10
+
11
+ #include "ast.hpp"
12
+ #include "position.hpp"
13
+ #include "context.hpp"
14
+ #include "position.hpp"
15
+ #include "prelexer.hpp"
16
+ #include "source.hpp"
17
+
18
+ #ifndef MAX_NESTING
19
+ // Note that this limit is not an exact science
20
+ // it depends on various factors, which some are
21
+ // not under our control (compile time or even OS
22
+ // dependent settings on the available stack size)
23
+ // It should fix most common segfault cases though.
24
+ #define MAX_NESTING 512
25
+ #endif
26
+
27
+ struct Lookahead {
28
+ const char* found;
29
+ const char* error;
30
+ const char* position;
31
+ bool parsable;
32
+ bool has_interpolants;
33
+ bool is_custom_property;
34
+ };
35
+
36
+ namespace Sass {
37
+
38
+ class Parser : public SourceSpan {
39
+ public:
40
+
41
+ enum Scope { Root, Mixin, Function, Media, Control, Properties, Rules, AtRoot };
42
+
43
+ Context& ctx;
44
+ sass::vector<Block_Obj> block_stack;
45
+ sass::vector<Scope> stack;
46
+ SourceDataObj source;
47
+ const char* begin;
48
+ const char* position;
49
+ const char* end;
50
+ Offset before_token;
51
+ Offset after_token;
52
+ SourceSpan pstate;
53
+ Backtraces traces;
54
+ size_t indentation;
55
+ size_t nestings;
56
+ bool allow_parent;
57
+ Token lexed;
58
+
59
+ Parser(SourceData* source, Context& ctx, Backtraces, bool allow_parent = true);
60
+
61
+ // special static parsers to convert strings into certain selectors
62
+ static SelectorListObj parse_selector(SourceData* source, Context& ctx, Backtraces, bool allow_parent = true);
63
+
64
+ #ifdef __clang__
65
+
66
+ // lex and peak uses the template parameter to branch on the action, which
67
+ // triggers clangs tautological comparison on the single-comparison
68
+ // branches. This is not a bug, just a merging of behaviour into
69
+ // one function
70
+
71
+ #pragma clang diagnostic push
72
+ #pragma clang diagnostic ignored "-Wtautological-compare"
73
+
74
+ #endif
75
+
76
+
77
+ // skip current token and next whitespace
78
+ // moves SourceSpan right before next token
79
+ void advanceToNextToken();
80
+
81
+ bool peek_newline(const char* start = 0);
82
+
83
+ // skip over spaces, tabs and line comments
84
+ template <Prelexer::prelexer mx>
85
+ const char* sneak(const char* start = 0)
86
+ {
87
+ using namespace Prelexer;
88
+
89
+ // maybe use optional start position from arguments?
90
+ const char* it_position = start ? start : position;
91
+
92
+ // skip white-space?
93
+ if (mx == spaces ||
94
+ mx == no_spaces ||
95
+ mx == css_comments ||
96
+ mx == css_whitespace ||
97
+ mx == optional_spaces ||
98
+ mx == optional_css_comments ||
99
+ mx == optional_css_whitespace
100
+ ) {
101
+ return it_position;
102
+ }
103
+
104
+ // skip over spaces, tabs and sass line comments
105
+ const char* pos = optional_css_whitespace(it_position);
106
+ // always return a valid position
107
+ return pos ? pos : it_position;
108
+
109
+ }
110
+
111
+ // match will not skip over space, tabs and line comment
112
+ // return the position where the lexer match will occur
113
+ template <Prelexer::prelexer mx>
114
+ const char* match(const char* start = 0)
115
+ {
116
+ // match the given prelexer
117
+ return mx(position);
118
+ }
119
+
120
+ // peek will only skip over space, tabs and line comment
121
+ // return the position where the lexer match will occur
122
+ template <Prelexer::prelexer mx>
123
+ const char* peek(const char* start = 0)
124
+ {
125
+
126
+ // sneak up to the actual token we want to lex
127
+ // this should skip over white-space if desired
128
+ const char* it_before_token = sneak < mx >(start);
129
+
130
+ // match the given prelexer
131
+ const char* match = mx(it_before_token);
132
+
133
+ // check if match is in valid range
134
+ return match <= end ? match : 0;
135
+
136
+ }
137
+
138
+ // white-space handling is built into the lexer
139
+ // this way you do not need to parse it yourself
140
+ // some matchers don't accept certain white-space
141
+ // we do not support start arg, since we manipulate
142
+ // sourcemap offset and we modify the position pointer!
143
+ // lex will only skip over space, tabs and line comment
144
+ template <Prelexer::prelexer mx>
145
+ const char* lex(bool lazy = true, bool force = false)
146
+ {
147
+
148
+ if (*position == 0) return 0;
149
+
150
+ // position considered before lexed token
151
+ // we can skip whitespace or comments for
152
+ // lazy developers (but we need control)
153
+ const char* it_before_token = position;
154
+
155
+ // sneak up to the actual token we want to lex
156
+ // this should skip over white-space if desired
157
+ if (lazy) it_before_token = sneak < mx >(position);
158
+
159
+ // now call matcher to get position after token
160
+ const char* it_after_token = mx(it_before_token);
161
+
162
+ // check if match is in valid range
163
+ if (it_after_token > end) return 0;
164
+
165
+ // maybe we want to update the parser state anyway?
166
+ if (force == false) {
167
+ // assertion that we got a valid match
168
+ if (it_after_token == 0) return 0;
169
+ // assertion that we actually lexed something
170
+ if (it_after_token == it_before_token) return 0;
171
+ }
172
+
173
+ // create new lexed token object (holds the parse results)
174
+ lexed = Token(position, it_before_token, it_after_token);
175
+
176
+ // advance position (add whitespace before current token)
177
+ before_token = after_token.add(position, it_before_token);
178
+
179
+ // update after_token position for current token
180
+ after_token.add(it_before_token, it_after_token);
181
+
182
+ // ToDo: could probably do this incremental on original object (API wants offset?)
183
+ pstate = SourceSpan(source, before_token, after_token - before_token);
184
+
185
+ // advance internal char iterator
186
+ return position = it_after_token;
187
+
188
+ }
189
+
190
+ // lex_css skips over space, tabs, line and block comment
191
+ // all block comments will be consumed and thrown away
192
+ // source-map position will point to token after the comment
193
+ template <Prelexer::prelexer mx>
194
+ const char* lex_css()
195
+ {
196
+ // copy old token
197
+ Token prev = lexed;
198
+ // store previous pointer
199
+ const char* oldpos = position;
200
+ Offset bt = before_token;
201
+ Offset at = after_token;
202
+ SourceSpan op = pstate;
203
+ // throw away comments
204
+ // update srcmap position
205
+ lex < Prelexer::css_comments >();
206
+ // now lex a new token
207
+ const char* pos = lex< mx >();
208
+ // maybe restore prev state
209
+ if (pos == 0) {
210
+ pstate = op;
211
+ lexed = prev;
212
+ position = oldpos;
213
+ after_token = at;
214
+ before_token = bt;
215
+ }
216
+ // return match
217
+ return pos;
218
+ }
219
+
220
+ // all block comments will be skipped and thrown away
221
+ template <Prelexer::prelexer mx>
222
+ const char* peek_css(const char* start = 0)
223
+ {
224
+ // now peek a token (skip comments first)
225
+ return peek< mx >(peek < Prelexer::css_comments >(start));
226
+ }
227
+
228
+ #ifdef __clang__
229
+
230
+ #pragma clang diagnostic pop
231
+
232
+ #endif
233
+
234
+ void error(sass::string msg);
235
+ // generate message with given and expected sample
236
+ // text before and in the middle are configurable
237
+ void css_error(const sass::string& msg,
238
+ const sass::string& prefix = " after ",
239
+ const sass::string& middle = ", was: ",
240
+ const bool trim = true);
241
+ void read_bom();
242
+
243
+ Block_Obj parse();
244
+ Import_Obj parse_import();
245
+ Definition_Obj parse_definition(Definition::Type which_type);
246
+ Parameters_Obj parse_parameters();
247
+ Parameter_Obj parse_parameter();
248
+ Mixin_Call_Obj parse_include_directive();
249
+ Arguments_Obj parse_arguments();
250
+ Arguments_Obj parse_color_arguments();
251
+ Argument_Obj parse_argument();
252
+ Assignment_Obj parse_assignment();
253
+ StyleRuleObj parse_ruleset(Lookahead lookahead);
254
+ SelectorListObj parseSelectorList(bool chroot);
255
+ ComplexSelectorObj parseComplexSelector(bool chroot);
256
+ Selector_Schema_Obj parse_selector_schema(const char* end_of_selector, bool chroot);
257
+ CompoundSelectorObj parseCompoundSelector();
258
+ SimpleSelectorObj parse_simple_selector();
259
+ PseudoSelectorObj parse_negated_selector2();
260
+ Expression* parse_binominal();
261
+ SimpleSelectorObj parse_pseudo_selector();
262
+ AttributeSelectorObj parse_attribute_selector();
263
+ Block_Obj parse_block(bool is_root = false);
264
+ Block_Obj parse_css_block(bool is_root = false);
265
+ bool parse_block_nodes(bool is_root = false);
266
+ bool parse_block_node(bool is_root = false);
267
+
268
+ Declaration_Obj parse_declaration();
269
+ ExpressionObj parse_map();
270
+ ExpressionObj parse_bracket_list();
271
+ ExpressionObj parse_list(bool delayed = false);
272
+ ExpressionObj parse_comma_list(bool delayed = false);
273
+ ExpressionObj parse_space_list();
274
+ ExpressionObj parse_disjunction();
275
+ ExpressionObj parse_conjunction();
276
+ ExpressionObj parse_relation();
277
+ ExpressionObj parse_expression();
278
+ ExpressionObj parse_operators();
279
+ ExpressionObj parse_factor();
280
+ ExpressionObj parse_value();
281
+ Function_Call_Obj parse_calc_function();
282
+ Function_Call_Obj parse_function_call();
283
+ Function_Call_Obj parse_function_call_schema();
284
+ String_Obj parse_url_function_string();
285
+ String_Obj parse_url_function_argument();
286
+ String_Obj parse_interpolated_chunk(Token, bool constant = false, bool css = true);
287
+ String_Obj parse_string();
288
+ ValueObj parse_static_value();
289
+ String_Schema_Obj parse_css_variable_value();
290
+ String_Obj parse_ie_property();
291
+ String_Obj parse_ie_keyword_arg();
292
+ String_Schema_Obj parse_value_schema(const char* stop);
293
+ String_Obj parse_identifier_schema();
294
+ If_Obj parse_if_directive(bool else_if = false);
295
+ ForRuleObj parse_for_directive();
296
+ EachRuleObj parse_each_directive();
297
+ WhileRuleObj parse_while_directive();
298
+ MediaRule_Obj parseMediaRule();
299
+ sass::vector<CssMediaQuery_Obj> parseCssMediaQueries();
300
+ sass::string parseIdentifier();
301
+ CssMediaQuery_Obj parseCssMediaQuery();
302
+ Return_Obj parse_return_directive();
303
+ Content_Obj parse_content_directive();
304
+ void parse_charset_directive();
305
+ List_Obj parse_media_queries();
306
+ Media_Query_Obj parse_media_query();
307
+ Media_Query_ExpressionObj parse_media_expression();
308
+ SupportsRuleObj parse_supports_directive();
309
+ SupportsConditionObj parse_supports_condition(bool top_level);
310
+ SupportsConditionObj parse_supports_negation();
311
+ SupportsConditionObj parse_supports_operator(bool top_level);
312
+ SupportsConditionObj parse_supports_interpolation();
313
+ SupportsConditionObj parse_supports_declaration();
314
+ SupportsConditionObj parse_supports_condition_in_parens(bool parens_required);
315
+ AtRootRuleObj parse_at_root_block();
316
+ At_Root_Query_Obj parse_at_root_query();
317
+ String_Schema_Obj parse_almost_any_value();
318
+ AtRuleObj parse_directive();
319
+ WarningRuleObj parse_warning();
320
+ ErrorRuleObj parse_error();
321
+ DebugRuleObj parse_debug();
322
+
323
+ Value* color_or_string(const sass::string& lexed) const;
324
+
325
+ // be more like ruby sass
326
+ ExpressionObj lex_almost_any_value_token();
327
+ ExpressionObj lex_almost_any_value_chars();
328
+ ExpressionObj lex_interp_string();
329
+ ExpressionObj lex_interp_uri();
330
+ ExpressionObj lex_interpolation();
331
+
332
+ // these will throw errors
333
+ Token lex_variable();
334
+ Token lex_identifier();
335
+
336
+ void parse_block_comments(bool store = true);
337
+
338
+ Lookahead lookahead_for_value(const char* start = 0);
339
+ Lookahead lookahead_for_selector(const char* start = 0);
340
+ Lookahead lookahead_for_include(const char* start = 0);
341
+
342
+ ExpressionObj fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, Operand op);
343
+ ExpressionObj fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, sass::vector<Operand>& ops, size_t i = 0);
344
+
345
+ void throw_syntax_error(sass::string message, size_t ln = 0);
346
+ void throw_read_error(sass::string message, size_t ln = 0);
347
+
348
+
349
+ template <Prelexer::prelexer open, Prelexer::prelexer close>
350
+ ExpressionObj lex_interp()
351
+ {
352
+ if (lex < open >(false)) {
353
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
354
+ // std::cerr << "LEX [[" << sass::string(lexed) << "]]\n";
355
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
356
+ if (position[0] == '#' && position[1] == '{') {
357
+ ExpressionObj itpl = lex_interpolation();
358
+ if (!itpl.isNull()) schema->append(itpl);
359
+ while (lex < close >(false)) {
360
+ // std::cerr << "LEX [[" << sass::string(lexed) << "]]\n";
361
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
362
+ if (position[0] == '#' && position[1] == '{') {
363
+ ExpressionObj itpl = lex_interpolation();
364
+ if (!itpl.isNull()) schema->append(itpl);
365
+ } else {
366
+ return schema;
367
+ }
368
+ }
369
+ } else {
370
+ return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
371
+ }
372
+ }
373
+ return {};
374
+ }
375
+
376
+ public:
377
+ static Number* lexed_number(const SourceSpan& pstate, const sass::string& parsed);
378
+ static Number* lexed_dimension(const SourceSpan& pstate, const sass::string& parsed);
379
+ static Number* lexed_percentage(const SourceSpan& pstate, const sass::string& parsed);
380
+ static Value* lexed_hex_color(const SourceSpan& pstate, const sass::string& parsed);
381
+ private:
382
+ Number* lexed_number(const sass::string& parsed) { return lexed_number(pstate, parsed); };
383
+ Number* lexed_dimension(const sass::string& parsed) { return lexed_dimension(pstate, parsed); };
384
+ Number* lexed_percentage(const sass::string& parsed) { return lexed_percentage(pstate, parsed); };
385
+ Value* lexed_hex_color(const sass::string& parsed) { return lexed_hex_color(pstate, parsed); };
386
+
387
+ static const char* re_attr_sensitive_close(const char* src);
388
+ static const char* re_attr_insensitive_close(const char* src);
389
+
390
+ };
391
+
392
+ size_t check_bom_chars(const char* src, const char *end, const unsigned char* bom, size_t len);
393
+ }
394
+
395
+ #endif
@@ -0,0 +1,189 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include "parser.hpp"
6
+
7
+ namespace Sass {
8
+
9
+ using namespace Prelexer;
10
+ using namespace Constants;
11
+
12
+ ComplexSelectorObj Parser::parseComplexSelector(bool chroot)
13
+ {
14
+
15
+ NESTING_GUARD(nestings);
16
+
17
+ lex < block_comment >();
18
+ advanceToNextToken();
19
+
20
+ ComplexSelectorObj sel = SASS_MEMORY_NEW(ComplexSelector, pstate);
21
+
22
+ if (peek < end_of_file >()) return sel;
23
+
24
+ while (true) {
25
+
26
+ lex < block_comment >();
27
+ advanceToNextToken();
28
+
29
+ // check for child (+) combinator
30
+ if (lex < exactly < selector_combinator_child > >()) {
31
+ sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::CHILD, peek_newline()));
32
+ }
33
+ // check for general sibling (~) combinator
34
+ else if (lex < exactly < selector_combinator_general > >()) {
35
+ sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::GENERAL, peek_newline()));
36
+ }
37
+ // check for adjecant sibling (+) combinator
38
+ else if (lex < exactly < selector_combinator_adjacent > >()) {
39
+ sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::ADJACENT, peek_newline()));
40
+ }
41
+ // check if we can parse a compound selector
42
+ else if (CompoundSelectorObj compound = parseCompoundSelector()) {
43
+ sel->append(compound);
44
+ }
45
+ else {
46
+ break;
47
+ }
48
+ }
49
+
50
+ if (sel->empty()) return {};
51
+
52
+ // check if we parsed any parent references
53
+ sel->chroots(sel->has_real_parent_ref() || chroot);
54
+
55
+ sel->update_pstate(pstate);
56
+
57
+ return sel;
58
+
59
+ }
60
+
61
+ SelectorListObj Parser::parseSelectorList(bool chroot)
62
+ {
63
+
64
+ bool reloop;
65
+ bool had_linefeed = false;
66
+ NESTING_GUARD(nestings);
67
+ SelectorListObj list = SASS_MEMORY_NEW(SelectorList, pstate);
68
+
69
+ if (peek_css< alternatives < end_of_file, exactly <'{'>, exactly <','> > >()) {
70
+ css_error("Invalid CSS", " after ", ": expected selector, was ");
71
+ }
72
+
73
+ do {
74
+ reloop = false;
75
+
76
+ had_linefeed = had_linefeed || peek_newline();
77
+
78
+ if (peek_css< alternatives < class_char < selector_list_delims > > >())
79
+ break; // in case there are superfluous commas at the end
80
+
81
+ // now parse the complex selector
82
+ ComplexSelectorObj complex = parseComplexSelector(chroot);
83
+ if (complex.isNull()) return list.detach();
84
+ complex->hasPreLineFeed(had_linefeed);
85
+
86
+ had_linefeed = false;
87
+
88
+ while (peek_css< exactly<','> >())
89
+ {
90
+ lex< css_comments >(false);
91
+ // consume everything up and including the comma separator
92
+ reloop = lex< exactly<','> >() != 0;
93
+ // remember line break (also between some commas)
94
+ had_linefeed = had_linefeed || peek_newline();
95
+ // remember line break (also between some commas)
96
+ }
97
+ list->append(complex);
98
+
99
+ } while (reloop);
100
+
101
+ while (lex_css< kwd_optional >()) {
102
+ list->is_optional(true);
103
+ }
104
+
105
+ // update for end position
106
+ list->update_pstate(pstate);
107
+
108
+ return list.detach();
109
+ }
110
+
111
+ // parse one compound selector, which is basically
112
+ // a list of simple selectors (directly adjacent)
113
+ // lex them exactly (without skipping white-space)
114
+ CompoundSelectorObj Parser::parseCompoundSelector()
115
+ {
116
+ // init an empty compound selector wrapper
117
+ CompoundSelectorObj seq = SASS_MEMORY_NEW(CompoundSelector, pstate);
118
+
119
+ // skip initial white-space
120
+ lex < block_comment >();
121
+ advanceToNextToken();
122
+
123
+ if (lex< exactly<'&'> >(false))
124
+ {
125
+ // ToDo: check the conditions and try to simplify flag passing
126
+ if (!allow_parent) error("Parent selectors aren't allowed here.");
127
+ // Create and append a new parent selector object
128
+ seq->hasRealParent(true);
129
+ }
130
+
131
+ // parse list
132
+ while (true)
133
+ {
134
+ // remove all block comments
135
+ // leaves trailing white-space
136
+ lex < block_comment >();
137
+ // parse parent selector
138
+ if (lex< exactly<'&'> >(false))
139
+ {
140
+ // parent selector only allowed at start
141
+ // upcoming Sass may allow also trailing
142
+ SourceSpan state(pstate);
143
+ sass::string found("&");
144
+ if (lex < identifier >()) {
145
+ found += sass::string(lexed);
146
+ }
147
+ sass::string sel(seq->hasRealParent() ? "&" : "");
148
+ if (!seq->empty()) { sel = seq->last()->to_string({ NESTED, 5 }); }
149
+ // ToDo: parser should throw parser exceptions
150
+ error("Invalid CSS after \"" + sel + "\": expected \"{\", was \"" + found + "\"\n\n"
151
+ "\"" + found + "\" may only be used at the beginning of a compound selector.");
152
+ }
153
+ // parse functional
154
+ else if (match < re_functional >())
155
+ {
156
+ seq->append(parse_simple_selector());
157
+ }
158
+
159
+ // parse type selector
160
+ else if (lex< re_type_selector >(false))
161
+ {
162
+ seq->append(SASS_MEMORY_NEW(TypeSelector, pstate, lexed));
163
+ }
164
+ // peek for abort conditions
165
+ else if (peek< spaces >()) break;
166
+ else if (peek< end_of_file >()) { break; }
167
+ else if (peek_css < class_char < selector_combinator_ops > >()) break;
168
+ else if (peek_css < class_char < complex_selector_delims > >()) break;
169
+ // otherwise parse another simple selector
170
+ else {
171
+ SimpleSelectorObj sel = parse_simple_selector();
172
+ if (!sel) return {};
173
+ seq->append(sel);
174
+ }
175
+ }
176
+ // EO while true
177
+
178
+ if (seq && !peek_css<alternatives<end_of_file,exactly<'{'>>>()) {
179
+ seq->hasPostLineBreak(peek_newline());
180
+ }
181
+
182
+ // We may have set hasRealParent
183
+ if (seq && seq->empty() && !seq->hasRealParent()) return {};
184
+
185
+ return seq;
186
+ }
187
+
188
+
189
+ }