sassc 1.11.4 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +2 -2
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/README.md +4 -1
  5. data/ext/libsass/.editorconfig +1 -1
  6. data/ext/libsass/.github/CONTRIBUTING.md +7 -7
  7. data/ext/libsass/.github/ISSUE_TEMPLATE.md +31 -6
  8. data/ext/libsass/.gitignore +3 -0
  9. data/ext/libsass/.travis.yml +37 -18
  10. data/ext/libsass/GNUmakefile.am +23 -37
  11. data/ext/libsass/Makefile +10 -6
  12. data/ext/libsass/Makefile.conf +3 -0
  13. data/ext/libsass/Readme.md +68 -63
  14. data/ext/libsass/appveyor.yml +7 -3
  15. data/ext/libsass/configure.ac +10 -14
  16. data/ext/libsass/docs/api-context-internal.md +29 -21
  17. data/ext/libsass/docs/api-context.md +26 -6
  18. data/ext/libsass/docs/api-doc.md +49 -16
  19. data/ext/libsass/docs/api-function-example.md +1 -1
  20. data/ext/libsass/docs/api-function.md +31 -7
  21. data/ext/libsass/docs/api-importer.md +19 -19
  22. data/ext/libsass/docs/api-value.md +4 -2
  23. data/ext/libsass/docs/build-on-windows.md +4 -4
  24. data/ext/libsass/docs/build-with-mingw.md +3 -3
  25. data/ext/libsass/docs/build.md +9 -9
  26. data/ext/libsass/docs/custom-functions-internal.md +10 -8
  27. data/ext/libsass/docs/implementations.md +20 -8
  28. data/ext/libsass/docs/unicode.md +16 -10
  29. data/ext/libsass/include/sass/base.h +0 -3
  30. data/ext/libsass/include/sass/context.h +20 -2
  31. data/ext/libsass/include/sass/functions.h +31 -0
  32. data/ext/libsass/include/sass/values.h +3 -1
  33. data/ext/libsass/include/sass/version.h +1 -1
  34. data/ext/libsass/include/sass/version.h.in +1 -1
  35. data/ext/libsass/include/sass2scss.h +1 -1
  36. data/ext/libsass/res/resource.rc +6 -6
  37. data/ext/libsass/script/ci-build-libsass +10 -5
  38. data/ext/libsass/script/ci-build-plugin +62 -0
  39. data/ext/libsass/script/ci-install-compiler +1 -1
  40. data/ext/libsass/script/ci-install-deps +4 -7
  41. data/ext/libsass/script/ci-report-coverage +13 -3
  42. data/ext/libsass/script/tap-driver +1 -1
  43. data/ext/libsass/script/tap-runner +1 -1
  44. data/ext/libsass/src/GNUmakefile.am +1 -1
  45. data/ext/libsass/src/ast.cpp +537 -762
  46. data/ext/libsass/src/ast.hpp +377 -419
  47. data/ext/libsass/src/ast_def_macros.hpp +26 -1
  48. data/ext/libsass/src/ast_fwd_decl.cpp +29 -0
  49. data/ext/libsass/src/ast_fwd_decl.hpp +94 -21
  50. data/ext/libsass/src/b64/encode.h +3 -1
  51. data/ext/libsass/src/backtrace.cpp +46 -0
  52. data/ext/libsass/src/backtrace.hpp +7 -54
  53. data/ext/libsass/src/bind.cpp +72 -50
  54. data/ext/libsass/src/bind.hpp +0 -1
  55. data/ext/libsass/src/cencode.c +6 -0
  56. data/ext/libsass/src/check_nesting.cpp +157 -135
  57. data/ext/libsass/src/check_nesting.hpp +11 -10
  58. data/ext/libsass/src/color_maps.cpp +10 -6
  59. data/ext/libsass/src/color_maps.hpp +6 -8
  60. data/ext/libsass/src/constants.cpp +4 -3
  61. data/ext/libsass/src/constants.hpp +4 -3
  62. data/ext/libsass/src/context.cpp +110 -47
  63. data/ext/libsass/src/context.hpp +11 -1
  64. data/ext/libsass/src/cssize.cpp +105 -94
  65. data/ext/libsass/src/cssize.hpp +4 -5
  66. data/ext/libsass/src/debugger.hpp +247 -244
  67. data/ext/libsass/src/emitter.cpp +30 -6
  68. data/ext/libsass/src/emitter.hpp +7 -0
  69. data/ext/libsass/src/environment.cpp +67 -16
  70. data/ext/libsass/src/environment.hpp +28 -7
  71. data/ext/libsass/src/error_handling.cpp +92 -64
  72. data/ext/libsass/src/error_handling.hpp +64 -43
  73. data/ext/libsass/src/eval.cpp +494 -544
  74. data/ext/libsass/src/eval.hpp +17 -23
  75. data/ext/libsass/src/expand.cpp +182 -154
  76. data/ext/libsass/src/expand.hpp +4 -5
  77. data/ext/libsass/src/extend.cpp +299 -291
  78. data/ext/libsass/src/extend.hpp +46 -11
  79. data/ext/libsass/src/file.cpp +103 -36
  80. data/ext/libsass/src/file.hpp +21 -4
  81. data/ext/libsass/src/functions.cpp +561 -312
  82. data/ext/libsass/src/functions.hpp +8 -5
  83. data/ext/libsass/src/inspect.cpp +108 -53
  84. data/ext/libsass/src/inspect.hpp +5 -2
  85. data/ext/libsass/src/lexer.cpp +15 -7
  86. data/ext/libsass/src/lexer.hpp +13 -4
  87. data/ext/libsass/src/listize.cpp +3 -2
  88. data/ext/libsass/src/listize.hpp +0 -1
  89. data/ext/libsass/src/memory/SharedPtr.cpp +16 -18
  90. data/ext/libsass/src/memory/SharedPtr.hpp +47 -43
  91. data/ext/libsass/src/node.cpp +34 -38
  92. data/ext/libsass/src/node.hpp +6 -8
  93. data/ext/libsass/src/operation.hpp +2 -2
  94. data/ext/libsass/src/operators.cpp +240 -0
  95. data/ext/libsass/src/operators.hpp +30 -0
  96. data/ext/libsass/src/output.cpp +22 -20
  97. data/ext/libsass/src/parser.cpp +719 -358
  98. data/ext/libsass/src/parser.hpp +57 -22
  99. data/ext/libsass/src/plugins.cpp +28 -10
  100. data/ext/libsass/src/position.cpp +21 -3
  101. data/ext/libsass/src/position.hpp +2 -1
  102. data/ext/libsass/src/prelexer.cpp +104 -19
  103. data/ext/libsass/src/prelexer.hpp +10 -3
  104. data/ext/libsass/src/remove_placeholders.cpp +9 -10
  105. data/ext/libsass/src/remove_placeholders.hpp +1 -5
  106. data/ext/libsass/src/sass.cpp +62 -4
  107. data/ext/libsass/src/sass.hpp +5 -2
  108. data/ext/libsass/src/sass_context.cpp +96 -58
  109. data/ext/libsass/src/sass_context.hpp +7 -5
  110. data/ext/libsass/src/sass_functions.cpp +63 -1
  111. data/ext/libsass/src/sass_functions.hpp +19 -1
  112. data/ext/libsass/src/sass_util.cpp +3 -3
  113. data/ext/libsass/src/sass_util.hpp +4 -4
  114. data/ext/libsass/src/sass_values.cpp +42 -39
  115. data/ext/libsass/src/sass_values.hpp +2 -1
  116. data/ext/libsass/src/source_map.cpp +16 -18
  117. data/ext/libsass/src/subset_map.cpp +6 -8
  118. data/ext/libsass/src/subset_map.hpp +6 -6
  119. data/ext/libsass/src/to_c.cpp +2 -2
  120. data/ext/libsass/src/to_value.cpp +8 -3
  121. data/ext/libsass/src/to_value.hpp +1 -0
  122. data/ext/libsass/src/units.cpp +349 -45
  123. data/ext/libsass/src/units.hpp +39 -22
  124. data/ext/libsass/src/utf8/checked.h +7 -0
  125. data/ext/libsass/src/utf8/unchecked.h +7 -0
  126. data/ext/libsass/src/utf8_string.cpp +1 -1
  127. data/ext/libsass/src/util.cpp +139 -45
  128. data/ext/libsass/src/util.hpp +4 -7
  129. data/ext/libsass/src/values.cpp +15 -23
  130. data/ext/libsass/win/libsass.sln +13 -2
  131. data/ext/libsass/win/libsass.sln.DotSettings +9 -0
  132. data/ext/libsass/win/libsass.targets +3 -0
  133. data/ext/libsass/win/libsass.vcxproj.filters +9 -0
  134. data/lib/sassc/version.rb +1 -1
  135. data/sassc.gemspec +1 -1
  136. data/test/native_test.rb +1 -1
  137. metadata +11 -4
@@ -10,12 +10,22 @@
10
10
  #include "position.hpp"
11
11
  #include "prelexer.hpp"
12
12
 
13
+ #ifndef MAX_NESTING
14
+ // Note that this limit is not an exact science
15
+ // it depends on various factors, which some are
16
+ // not under our control (compile time or even OS
17
+ // dependent settings on the available stack size)
18
+ // It should fix most common segfault cases though.
19
+ #define MAX_NESTING 512
20
+ #endif
21
+
13
22
  struct Lookahead {
14
23
  const char* found;
15
24
  const char* error;
16
25
  const char* position;
17
26
  bool parsable;
18
27
  bool has_interpolants;
28
+ bool is_custom_property;
19
29
  };
20
30
 
21
31
  namespace Sass {
@@ -23,7 +33,7 @@ namespace Sass {
23
33
  class Parser : public ParserState {
24
34
  public:
25
35
 
26
- enum Scope { Root, Mixin, Function, Media, Control, Properties, Rules };
36
+ enum Scope { Root, Mixin, Function, Media, Control, Properties, Rules, AtRoot };
27
37
 
28
38
  Context& ctx;
29
39
  std::vector<Block_Obj> block_stack;
@@ -35,23 +45,26 @@ namespace Sass {
35
45
  Position before_token;
36
46
  Position after_token;
37
47
  ParserState pstate;
38
- int indentation;
39
-
48
+ Backtraces traces;
49
+ size_t indentation;
50
+ size_t nestings;
40
51
 
41
52
  Token lexed;
42
- bool in_at_root;
43
53
 
44
- Parser(Context& ctx, const ParserState& pstate)
54
+ Parser(Context& ctx, const ParserState& pstate, Backtraces traces)
45
55
  : ParserState(pstate), ctx(ctx), block_stack(), stack(0), last_media_block(),
46
- source(0), position(0), end(0), before_token(pstate), after_token(pstate), pstate(pstate), indentation(0)
47
- { in_at_root = false; stack.push_back(Scope::Root); }
56
+ source(0), position(0), end(0), before_token(pstate), after_token(pstate),
57
+ pstate(pstate), traces(traces), indentation(0), nestings(0)
58
+ {
59
+ stack.push_back(Scope::Root);
60
+ }
48
61
 
49
62
  // static Parser from_string(const std::string& src, Context& ctx, ParserState pstate = ParserState("[STRING]"));
50
- static Parser from_c_str(const char* src, Context& ctx, ParserState pstate = ParserState("[CSTRING]"), const char* source = 0);
51
- static Parser from_c_str(const char* beg, const char* end, Context& ctx, ParserState pstate = ParserState("[CSTRING]"), const char* source = 0);
52
- static Parser from_token(Token t, Context& ctx, ParserState pstate = ParserState("[TOKEN]"), const char* source = 0);
63
+ static Parser from_c_str(const char* src, Context& ctx, Backtraces, ParserState pstate = ParserState("[CSTRING]"), const char* source = 0);
64
+ static Parser from_c_str(const char* beg, const char* end, Context& ctx, Backtraces, ParserState pstate = ParserState("[CSTRING]"), const char* source = 0);
65
+ static Parser from_token(Token t, Context& ctx, Backtraces, ParserState pstate = ParserState("[TOKEN]"), const char* source = 0);
53
66
  // special static parsers to convert strings into certain selectors
54
- static Selector_List_Obj parse_selector(const char* src, Context& ctx, ParserState pstate = ParserState("[SELECTOR]"), const char* source = 0);
67
+ static Selector_List_Obj parse_selector(const char* src, Context& ctx, Backtraces, ParserState pstate = ParserState("[SELECTOR]"), const char* source = 0);
55
68
 
56
69
  #ifdef __clang__
57
70
 
@@ -100,7 +113,7 @@ namespace Sass {
100
113
 
101
114
  }
102
115
 
103
- // peek will only skip over space, tabs and line comment
116
+ // match will not skip over space, tabs and line comment
104
117
  // return the position where the lexer match will occur
105
118
  template <Prelexer::prelexer mx>
106
119
  const char* match(const char* start = 0)
@@ -223,12 +236,14 @@ namespace Sass {
223
236
 
224
237
  #endif
225
238
 
239
+ void error(std::string msg);
226
240
  void error(std::string msg, Position pos);
227
241
  // generate message with given and expected sample
228
242
  // text before and in the middle are configurable
229
243
  void css_error(const std::string& msg,
230
244
  const std::string& prefix = " after ",
231
- const std::string& middle = ", was: ");
245
+ const std::string& middle = ", was: ",
246
+ const bool trim = true);
232
247
  void read_bom();
233
248
 
234
249
  Block_Obj parse();
@@ -240,10 +255,10 @@ namespace Sass {
240
255
  Arguments_Obj parse_arguments();
241
256
  Argument_Obj parse_argument();
242
257
  Assignment_Obj parse_assignment();
243
- Ruleset_Obj parse_ruleset(Lookahead lookahead, bool is_root = false);
244
- Selector_Schema_Obj parse_selector_schema(const char* end_of_selector);
245
- Selector_List_Obj parse_selector_list(bool at_root = false);
246
- Complex_Selector_Obj parse_complex_selector(bool in_root = true);
258
+ Ruleset_Obj parse_ruleset(Lookahead lookahead);
259
+ Selector_List_Obj parse_selector_list(bool chroot);
260
+ Complex_Selector_Obj parse_complex_selector(bool chroot);
261
+ Selector_Schema_Obj parse_selector_schema(const char* end_of_selector, bool chroot);
247
262
  Compound_Selector_Obj parse_compound_selector();
248
263
  Simple_Selector_Obj parse_simple_selector();
249
264
  Wrapped_Selector_Obj parse_negated_selector();
@@ -257,6 +272,7 @@ namespace Sass {
257
272
  bool parse_number_prefix();
258
273
  Declaration_Obj parse_declaration();
259
274
  Expression_Obj parse_map();
275
+ Expression_Obj parse_bracket_list();
260
276
  Expression_Obj parse_list(bool delayed = false);
261
277
  Expression_Obj parse_comma_list(bool delayed = false);
262
278
  Expression_Obj parse_space_list();
@@ -272,9 +288,11 @@ namespace Sass {
272
288
  Function_Call_Schema_Obj parse_function_call_schema();
273
289
  String_Obj parse_url_function_string();
274
290
  String_Obj parse_url_function_argument();
275
- String_Obj parse_interpolated_chunk(Token, bool constant = false);
291
+ String_Obj parse_interpolated_chunk(Token, bool constant = false, bool css = true);
276
292
  String_Obj parse_string();
277
- String_Constant_Obj parse_static_value();
293
+ Value_Obj parse_static_value();
294
+ String_Schema_Obj parse_css_variable_value(bool top_level = true);
295
+ String_Schema_Obj parse_css_variable_value_token(bool top_level = true);
278
296
  String_Obj parse_ie_property();
279
297
  String_Obj parse_ie_keyword_arg();
280
298
  String_Schema_Obj parse_value_schema(const char* stop);
@@ -307,6 +325,8 @@ namespace Sass {
307
325
  Error_Obj parse_error();
308
326
  Debug_Obj parse_debug();
309
327
 
328
+ Value_Ptr color_or_string(const std::string& lexed) const;
329
+
310
330
  // be more like ruby sass
311
331
  Expression_Obj lex_almost_any_value_token();
312
332
  Expression_Obj lex_almost_any_value_chars();
@@ -340,15 +360,15 @@ namespace Sass {
340
360
  schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
341
361
  if (position[0] == '#' && position[1] == '{') {
342
362
  Expression_Obj itpl = lex_interpolation();
343
- if (&itpl) schema->append(&itpl);
363
+ if (!itpl.isNull()) schema->append(itpl);
344
364
  while (lex < close >(false)) {
345
365
  // std::cerr << "LEX [[" << std::string(lexed) << "]]\n";
346
366
  schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
347
367
  if (position[0] == '#' && position[1] == '{') {
348
368
  Expression_Obj itpl = lex_interpolation();
349
- if (&itpl) schema->append(&itpl);
369
+ if (!itpl.isNull()) schema->append(itpl);
350
370
  } else {
351
- return &schema;
371
+ return schema;
352
372
  }
353
373
  }
354
374
  } else {
@@ -357,6 +377,21 @@ namespace Sass {
357
377
  }
358
378
  return 0;
359
379
  }
380
+
381
+ public:
382
+ static Number_Ptr lexed_number(const ParserState& pstate, const std::string& parsed);
383
+ static Number_Ptr lexed_dimension(const ParserState& pstate, const std::string& parsed);
384
+ static Number_Ptr lexed_percentage(const ParserState& pstate, const std::string& parsed);
385
+ static Value_Ptr lexed_hex_color(const ParserState& pstate, const std::string& parsed);
386
+ private:
387
+ Number_Ptr lexed_number(const std::string& parsed) { return lexed_number(pstate, parsed); };
388
+ Number_Ptr lexed_dimension(const std::string& parsed) { return lexed_dimension(pstate, parsed); };
389
+ Number_Ptr lexed_percentage(const std::string& parsed) { return lexed_percentage(pstate, parsed); };
390
+ Value_Ptr lexed_hex_color(const std::string& parsed) { return lexed_hex_color(pstate, parsed); };
391
+
392
+ static const char* re_attr_sensitive_close(const char* src);
393
+ static const char* re_attr_insensitive_close(const char* src);
394
+
360
395
  };
361
396
 
362
397
  size_t check_bom_chars(const char* src, const char *end, const unsigned char* bom, size_t len);
@@ -1,3 +1,8 @@
1
+ #include "sass.hpp"
2
+ #include <iostream>
3
+ #include "output.hpp"
4
+ #include "plugins.hpp"
5
+
1
6
  #ifdef _WIN32
2
7
  #include <windows.h>
3
8
  #else
@@ -7,15 +12,21 @@
7
12
  #include <dlfcn.h>
8
13
  #endif
9
14
 
10
- #include "sass.hpp"
11
- #include <iostream>
12
- #include "output.hpp"
13
- #include "plugins.hpp"
14
-
15
15
  namespace Sass {
16
16
 
17
17
  Plugins::Plugins(void) { }
18
- Plugins::~Plugins(void) { }
18
+ Plugins::~Plugins(void)
19
+ {
20
+ for (auto function : functions) {
21
+ sass_delete_function(function);
22
+ }
23
+ for (auto importer : importers) {
24
+ sass_delete_importer(importer);
25
+ }
26
+ for (auto header : headers) {
27
+ sass_delete_importer(header);
28
+ }
29
+ }
19
30
 
20
31
  // check if plugin is compatible with this version
21
32
  // plugins may be linked static against libsass
@@ -57,20 +68,23 @@ namespace Sass {
57
68
  // try to get import address for "libsass_load_functions"
58
69
  if (LOAD_LIB_FN(__plugin_load_fns__, plugin_load_functions, "libsass_load_functions"))
59
70
  {
60
- Sass_Function_List fns = plugin_load_functions();
71
+ Sass_Function_List fns = plugin_load_functions(), _p = fns;
61
72
  while (fns && *fns) { functions.push_back(*fns); ++ fns; }
73
+ sass_free_memory(_p); // only delete the container, items not yet
62
74
  }
63
75
  // try to get import address for "libsass_load_importers"
64
76
  if (LOAD_LIB_FN(__plugin_load_imps__, plugin_load_importers, "libsass_load_importers"))
65
77
  {
66
- Sass_Importer_List imps = plugin_load_importers();
78
+ Sass_Importer_List imps = plugin_load_importers(), _p = imps;
67
79
  while (imps && *imps) { importers.push_back(*imps); ++ imps; }
80
+ sass_free_memory(_p); // only delete the container, items not yet
68
81
  }
69
82
  // try to get import address for "libsass_load_headers"
70
83
  if (LOAD_LIB_FN(__plugin_load_imps__, plugin_load_headers, "libsass_load_headers"))
71
84
  {
72
- Sass_Importer_List imps = plugin_load_headers();
85
+ Sass_Importer_List imps = plugin_load_headers(), _p = imps;
73
86
  while (imps && *imps) { headers.push_back(*imps); ++ imps; }
87
+ sass_free_memory(_p); // only delete the container, items not yet
74
88
  }
75
89
  // success
76
90
  return true;
@@ -153,7 +167,11 @@ namespace Sass {
153
167
  struct dirent *dirp;
154
168
  if((dp = opendir(path.c_str())) == NULL) return -1;
155
169
  while ((dirp = readdir(dp)) != NULL) {
156
- if (!ends_with(dirp->d_name, ".so")) continue;
170
+ #if __APPLE__
171
+ if (!ends_with(dirp->d_name, ".dylib")) continue;
172
+ #else
173
+ if (!ends_with(dirp->d_name, ".so")) continue;
174
+ #endif
157
175
  if (load_plugin(path + dirp->d_name)) ++ loaded;
158
176
  }
159
177
  closedir(dp);
@@ -4,6 +4,11 @@
4
4
  namespace Sass {
5
5
 
6
6
 
7
+ Offset::Offset(const char chr)
8
+ : line(chr == '\n' ? 1 : 0),
9
+ column(chr == '\n' ? 0 : 1)
10
+ {}
11
+
7
12
  Offset::Offset(const char* string)
8
13
  : line(0), column(0)
9
14
  {
@@ -32,7 +37,6 @@ namespace Sass {
32
37
 
33
38
  // increase offset by given string (mostly called by lexer)
34
39
  // increase line counter and count columns on the last line
35
- // ToDo: make the col count utf8 aware
36
40
  Offset Offset::add(const char* begin, const char* end)
37
41
  {
38
42
  if (end == 0) return *this;
@@ -42,9 +46,23 @@ namespace Sass {
42
46
  // start new line
43
47
  column = 0;
44
48
  } else {
45
- ++ column;
49
+ // do not count any utf8 continuation bytes
50
+ // https://stackoverflow.com/a/9356203/1550314
51
+ // https://en.wikipedia.org/wiki/UTF-8#Description
52
+ unsigned char chr = *begin;
53
+ // skip over 10xxxxxx
54
+ // is 1st bit not set
55
+ if ((chr & 128) == 0) {
56
+ // regular ascii char
57
+ column += 1;
58
+ }
59
+ // is 2nd bit not set
60
+ else if ((chr & 64) == 0) {
61
+ // first utf8 byte
62
+ column += 1;
63
+ }
46
64
  }
47
- ++begin;
65
+ ++ begin;
48
66
  }
49
67
  return *this;
50
68
  }
@@ -11,6 +11,7 @@ namespace Sass {
11
11
  class Offset {
12
12
 
13
13
  public: // c-tor
14
+ Offset(const char chr);
14
15
  Offset(const char* string);
15
16
  Offset(const std::string& text);
16
17
  Offset(const size_t line, const size_t column);
@@ -85,7 +86,7 @@ namespace Sass {
85
86
 
86
87
  size_t length() const { return end - begin; }
87
88
  std::string ws_before() const { return std::string(prefix, begin); }
88
- std::string to_string() const { return std::string(begin, end); }
89
+ const std::string to_string() const { return std::string(begin, end); }
89
90
  std::string time_wspace() const {
90
91
  std::string str(to_string());
91
92
  std::string whitespaces(" \t\f\v\n\r");
@@ -1,6 +1,5 @@
1
1
  #include "sass.hpp"
2
2
  #include <cctype>
3
- #include <cstddef>
4
3
  #include <iostream>
5
4
  #include <iomanip>
6
5
  #include "util.hpp"
@@ -438,6 +437,10 @@ namespace Sass {
438
437
  optional <
439
438
  sequence <
440
439
  exactly <'/'>,
440
+ negate < sequence <
441
+ exactly < calc_fn_kwd >,
442
+ exactly < '(' >
443
+ > >,
441
444
  multiple_units
442
445
  > >
443
446
  >(src);
@@ -577,7 +580,7 @@ namespace Sass {
577
580
  const char* value_combinations(const char* src) {
578
581
  // `2px-2px` is invalid combo
579
582
  bool was_number = false;
580
- const char* pos = src;
583
+ const char* pos;
581
584
  while (src) {
582
585
  if ((pos = alternatives < quoted_string, identifier, percentage, hex >(src))) {
583
586
  was_number = false;
@@ -643,10 +646,7 @@ namespace Sass {
643
646
  >,
644
647
  sequence <
645
648
  negate <
646
- sequence <
647
- exactly < url_kwd >,
648
- exactly <'('>
649
- >
649
+ uri_prefix
650
650
  >,
651
651
  neg_class_char <
652
652
  almost_any_value_class
@@ -998,7 +998,17 @@ namespace Sass {
998
998
  digits>(src);
999
999
  }
1000
1000
  const char* number(const char* src) {
1001
- return sequence< optional<sign>, unsigned_number>(src);
1001
+ return sequence<
1002
+ optional<sign>,
1003
+ unsigned_number,
1004
+ optional<
1005
+ sequence<
1006
+ exactly<'e'>,
1007
+ optional<sign>,
1008
+ unsigned_number
1009
+ >
1010
+ >
1011
+ >(src);
1002
1012
  }
1003
1013
  const char* coefficient(const char* src) {
1004
1014
  return alternatives< sequence< optional<sign>, digits >,
@@ -1037,7 +1047,7 @@ namespace Sass {
1037
1047
  const char* hexa(const char* src) {
1038
1048
  const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);
1039
1049
  ptrdiff_t len = p - src;
1040
- return (len != 4 && len != 7 && len != 9) ? 0 : p;
1050
+ return (len != 5 && len != 9) ? 0 : p;
1041
1051
  }
1042
1052
  const char* hex0(const char* src) {
1043
1053
  const char* p = sequence< exactly<'0'>, exactly<'x'>, one_plus<xdigit> >(src);
@@ -1047,7 +1057,7 @@ namespace Sass {
1047
1057
 
1048
1058
  /* no longer used - remove?
1049
1059
  const char* rgb_prefix(const char* src) {
1050
- return word<rgb_kwd>(src);
1060
+ return word<rgb_fn_kwd>(src);
1051
1061
  }*/
1052
1062
  // Match CSS uri specifiers.
1053
1063
 
@@ -1161,7 +1171,7 @@ namespace Sass {
1161
1171
  }
1162
1172
  // Match the CSS negation pseudo-class.
1163
1173
  const char* pseudo_not(const char* src) {
1164
- return word< pseudo_not_kwd >(src);
1174
+ return word< pseudo_not_fn_kwd >(src);
1165
1175
  }
1166
1176
  // Match CSS 'odd' and 'even' keywords for functional pseudo-classes.
1167
1177
  const char* even(const char* src) {
@@ -1269,7 +1279,7 @@ namespace Sass {
1269
1279
  optional_css_whitespace,
1270
1280
  exactly<'='>,
1271
1281
  optional_css_whitespace,
1272
- alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >,
1282
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hex, hexa >,
1273
1283
  zero_plus< sequence<
1274
1284
  optional_css_whitespace,
1275
1285
  exactly<','>,
@@ -1279,7 +1289,7 @@ namespace Sass {
1279
1289
  optional_css_whitespace,
1280
1290
  exactly<'='>,
1281
1291
  optional_css_whitespace,
1282
- alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >
1292
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hex, hexa >
1283
1293
  >
1284
1294
  > >
1285
1295
  > >,
@@ -1314,6 +1324,7 @@ namespace Sass {
1314
1324
  identifier,
1315
1325
  quoted_string,
1316
1326
  number,
1327
+ hex,
1317
1328
  hexa,
1318
1329
  sequence <
1319
1330
  exactly < '(' >,
@@ -1420,6 +1431,28 @@ namespace Sass {
1420
1431
  >(src);
1421
1432
  }
1422
1433
 
1434
+ const char* list_terminator(const char* src) {
1435
+ return alternatives <
1436
+ exactly<';'>,
1437
+ exactly<'}'>,
1438
+ exactly<'{'>,
1439
+ exactly<')'>,
1440
+ exactly<']'>,
1441
+ exactly<':'>,
1442
+ end_of_file,
1443
+ exactly<ellipsis>,
1444
+ default_flag,
1445
+ global_flag
1446
+ >(src);
1447
+ };
1448
+
1449
+ const char* space_list_terminator(const char* src) {
1450
+ return alternatives <
1451
+ exactly<','>,
1452
+ list_terminator
1453
+ >(src);
1454
+ };
1455
+
1423
1456
 
1424
1457
  // const char* real_uri_prefix(const char* src) {
1425
1458
  // return alternatives<
@@ -1428,6 +1461,16 @@ namespace Sass {
1428
1461
  // >(src);
1429
1462
  // }
1430
1463
 
1464
+ const char* real_uri(const char* src) {
1465
+ return sequence<
1466
+ exactly< url_kwd >,
1467
+ exactly< '(' >,
1468
+ W,
1469
+ real_uri_value,
1470
+ exactly< ')' >
1471
+ >(src);
1472
+ }
1473
+
1431
1474
  const char* real_uri_suffix(const char* src) {
1432
1475
  return sequence< W, exactly< ')' > >(src);
1433
1476
  }
@@ -1478,6 +1521,7 @@ namespace Sass {
1478
1521
  static_string,
1479
1522
  percentage,
1480
1523
  hex,
1524
+ hexa,
1481
1525
  exactly<'|'>,
1482
1526
  // exactly<'+'>,
1483
1527
  sequence < number, unit_identifier >,
@@ -1545,6 +1589,40 @@ namespace Sass {
1545
1589
  >(src);
1546
1590
  }
1547
1591
 
1592
+ extern const char css_variable_url_negates[] = "()[]{}\"'#/";
1593
+ const char* css_variable_value(const char* src) {
1594
+ return sequence<
1595
+ alternatives<
1596
+ sequence<
1597
+ negate< exactly< url_fn_kwd > >,
1598
+ one_plus< neg_class_char< css_variable_url_negates > >
1599
+ >,
1600
+ sequence< exactly<'#'>, negate< exactly<'{'> > >,
1601
+ sequence< exactly<'/'>, negate< exactly<'*'> > >,
1602
+ static_string,
1603
+ real_uri,
1604
+ block_comment
1605
+ >
1606
+ >(src);
1607
+ }
1608
+
1609
+ extern const char css_variable_url_top_level_negates[] = "()[]{}\"'#/;";
1610
+ const char* css_variable_top_level_value(const char* src) {
1611
+ return sequence<
1612
+ alternatives<
1613
+ sequence<
1614
+ negate< exactly< url_fn_kwd > >,
1615
+ one_plus< neg_class_char< css_variable_url_top_level_negates > >
1616
+ >,
1617
+ sequence< exactly<'#'>, negate< exactly<'{'> > >,
1618
+ sequence< exactly<'/'>, negate< exactly<'*'> > >,
1619
+ static_string,
1620
+ real_uri,
1621
+ block_comment
1622
+ >
1623
+ >(src);
1624
+ }
1625
+
1548
1626
  const char* parenthese_scope(const char* src) {
1549
1627
  return sequence <
1550
1628
  exactly < '(' >,
@@ -1578,7 +1656,7 @@ namespace Sass {
1578
1656
  class_char < selector_lookahead_ops >,
1579
1657
  // match selector combinators /[>+~]/
1580
1658
  class_char < selector_combinator_ops >,
1581
- // match attribute compare operators
1659
+ // match pseudo selectors
1582
1660
  sequence <
1583
1661
  exactly <'('>,
1584
1662
  optional_spaces,
@@ -1586,6 +1664,7 @@ namespace Sass {
1586
1664
  optional_spaces,
1587
1665
  exactly <')'>
1588
1666
  >,
1667
+ // match attribute compare operators
1589
1668
  alternatives <
1590
1669
  exact_match, class_match, dash_match,
1591
1670
  prefix_match, suffix_match, substring_match
@@ -1604,12 +1683,21 @@ namespace Sass {
1604
1683
  // class match
1605
1684
  exactly <'.'>,
1606
1685
  // single or double colon
1607
- optional < pseudo_prefix >
1686
+ sequence <
1687
+ optional < pseudo_prefix >,
1688
+ // fix libsass issue 2376
1689
+ negate < uri_prefix >
1690
+ >
1608
1691
  >,
1609
1692
  // accept hypens in token
1610
1693
  one_plus < sequence <
1611
1694
  // can start with hyphens
1612
- zero_plus < exactly<'-'> >,
1695
+ zero_plus <
1696
+ sequence <
1697
+ exactly <'-'>,
1698
+ optional_spaces
1699
+ >
1700
+ >,
1613
1701
  // now the main token
1614
1702
  alternatives <
1615
1703
  kwd_optional,
@@ -1636,10 +1724,7 @@ namespace Sass {
1636
1724
  return sequence< optional<namespace_schema>, identifier>(src);
1637
1725
  }
1638
1726
  const char* re_type_selector(const char* src) {
1639
- return alternatives< type_selector, universal, quoted_string, dimension, percentage, number, identifier_alnums >(src);
1640
- }
1641
- const char* re_type_selector2(const char* src) {
1642
- return alternatives< type_selector, universal, quoted_string, dimension, percentage, number, identifier_alnums >(src);
1727
+ return alternatives< type_selector, universal, dimension, percentage, number, identifier_alnums >(src);
1643
1728
  }
1644
1729
  const char* re_static_expression(const char* src) {
1645
1730
  return sequence< number, optional_spaces, exactly<'/'>, optional_spaces, number >(src);