sassc 1.11.4 → 1.12.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 (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);