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.
- checksums.yaml +5 -5
- data/.travis.yml +2 -2
- data/CODE_OF_CONDUCT.md +10 -0
- data/README.md +4 -1
- data/ext/libsass/.editorconfig +1 -1
- data/ext/libsass/.github/CONTRIBUTING.md +7 -7
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +31 -6
- data/ext/libsass/.gitignore +3 -0
- data/ext/libsass/.travis.yml +37 -18
- data/ext/libsass/GNUmakefile.am +23 -37
- data/ext/libsass/Makefile +10 -6
- data/ext/libsass/Makefile.conf +3 -0
- data/ext/libsass/Readme.md +68 -63
- data/ext/libsass/appveyor.yml +7 -3
- data/ext/libsass/configure.ac +10 -14
- data/ext/libsass/docs/api-context-internal.md +29 -21
- data/ext/libsass/docs/api-context.md +26 -6
- data/ext/libsass/docs/api-doc.md +49 -16
- data/ext/libsass/docs/api-function-example.md +1 -1
- data/ext/libsass/docs/api-function.md +31 -7
- data/ext/libsass/docs/api-importer.md +19 -19
- data/ext/libsass/docs/api-value.md +4 -2
- data/ext/libsass/docs/build-on-windows.md +4 -4
- data/ext/libsass/docs/build-with-mingw.md +3 -3
- data/ext/libsass/docs/build.md +9 -9
- data/ext/libsass/docs/custom-functions-internal.md +10 -8
- data/ext/libsass/docs/implementations.md +20 -8
- data/ext/libsass/docs/unicode.md +16 -10
- data/ext/libsass/include/sass/base.h +0 -3
- data/ext/libsass/include/sass/context.h +20 -2
- data/ext/libsass/include/sass/functions.h +31 -0
- data/ext/libsass/include/sass/values.h +3 -1
- data/ext/libsass/include/sass/version.h +1 -1
- data/ext/libsass/include/sass/version.h.in +1 -1
- data/ext/libsass/include/sass2scss.h +1 -1
- data/ext/libsass/res/resource.rc +6 -6
- data/ext/libsass/script/ci-build-libsass +10 -5
- data/ext/libsass/script/ci-build-plugin +62 -0
- data/ext/libsass/script/ci-install-compiler +1 -1
- data/ext/libsass/script/ci-install-deps +4 -7
- data/ext/libsass/script/ci-report-coverage +13 -3
- data/ext/libsass/script/tap-driver +1 -1
- data/ext/libsass/script/tap-runner +1 -1
- data/ext/libsass/src/GNUmakefile.am +1 -1
- data/ext/libsass/src/ast.cpp +537 -762
- data/ext/libsass/src/ast.hpp +377 -419
- data/ext/libsass/src/ast_def_macros.hpp +26 -1
- data/ext/libsass/src/ast_fwd_decl.cpp +29 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +94 -21
- data/ext/libsass/src/b64/encode.h +3 -1
- data/ext/libsass/src/backtrace.cpp +46 -0
- data/ext/libsass/src/backtrace.hpp +7 -54
- data/ext/libsass/src/bind.cpp +72 -50
- data/ext/libsass/src/bind.hpp +0 -1
- data/ext/libsass/src/cencode.c +6 -0
- data/ext/libsass/src/check_nesting.cpp +157 -135
- data/ext/libsass/src/check_nesting.hpp +11 -10
- data/ext/libsass/src/color_maps.cpp +10 -6
- data/ext/libsass/src/color_maps.hpp +6 -8
- data/ext/libsass/src/constants.cpp +4 -3
- data/ext/libsass/src/constants.hpp +4 -3
- data/ext/libsass/src/context.cpp +110 -47
- data/ext/libsass/src/context.hpp +11 -1
- data/ext/libsass/src/cssize.cpp +105 -94
- data/ext/libsass/src/cssize.hpp +4 -5
- data/ext/libsass/src/debugger.hpp +247 -244
- data/ext/libsass/src/emitter.cpp +30 -6
- data/ext/libsass/src/emitter.hpp +7 -0
- data/ext/libsass/src/environment.cpp +67 -16
- data/ext/libsass/src/environment.hpp +28 -7
- data/ext/libsass/src/error_handling.cpp +92 -64
- data/ext/libsass/src/error_handling.hpp +64 -43
- data/ext/libsass/src/eval.cpp +494 -544
- data/ext/libsass/src/eval.hpp +17 -23
- data/ext/libsass/src/expand.cpp +182 -154
- data/ext/libsass/src/expand.hpp +4 -5
- data/ext/libsass/src/extend.cpp +299 -291
- data/ext/libsass/src/extend.hpp +46 -11
- data/ext/libsass/src/file.cpp +103 -36
- data/ext/libsass/src/file.hpp +21 -4
- data/ext/libsass/src/functions.cpp +561 -312
- data/ext/libsass/src/functions.hpp +8 -5
- data/ext/libsass/src/inspect.cpp +108 -53
- data/ext/libsass/src/inspect.hpp +5 -2
- data/ext/libsass/src/lexer.cpp +15 -7
- data/ext/libsass/src/lexer.hpp +13 -4
- data/ext/libsass/src/listize.cpp +3 -2
- data/ext/libsass/src/listize.hpp +0 -1
- data/ext/libsass/src/memory/SharedPtr.cpp +16 -18
- data/ext/libsass/src/memory/SharedPtr.hpp +47 -43
- data/ext/libsass/src/node.cpp +34 -38
- data/ext/libsass/src/node.hpp +6 -8
- data/ext/libsass/src/operation.hpp +2 -2
- data/ext/libsass/src/operators.cpp +240 -0
- data/ext/libsass/src/operators.hpp +30 -0
- data/ext/libsass/src/output.cpp +22 -20
- data/ext/libsass/src/parser.cpp +719 -358
- data/ext/libsass/src/parser.hpp +57 -22
- data/ext/libsass/src/plugins.cpp +28 -10
- data/ext/libsass/src/position.cpp +21 -3
- data/ext/libsass/src/position.hpp +2 -1
- data/ext/libsass/src/prelexer.cpp +104 -19
- data/ext/libsass/src/prelexer.hpp +10 -3
- data/ext/libsass/src/remove_placeholders.cpp +9 -10
- data/ext/libsass/src/remove_placeholders.hpp +1 -5
- data/ext/libsass/src/sass.cpp +62 -4
- data/ext/libsass/src/sass.hpp +5 -2
- data/ext/libsass/src/sass_context.cpp +96 -58
- data/ext/libsass/src/sass_context.hpp +7 -5
- data/ext/libsass/src/sass_functions.cpp +63 -1
- data/ext/libsass/src/sass_functions.hpp +19 -1
- data/ext/libsass/src/sass_util.cpp +3 -3
- data/ext/libsass/src/sass_util.hpp +4 -4
- data/ext/libsass/src/sass_values.cpp +42 -39
- data/ext/libsass/src/sass_values.hpp +2 -1
- data/ext/libsass/src/source_map.cpp +16 -18
- data/ext/libsass/src/subset_map.cpp +6 -8
- data/ext/libsass/src/subset_map.hpp +6 -6
- data/ext/libsass/src/to_c.cpp +2 -2
- data/ext/libsass/src/to_value.cpp +8 -3
- data/ext/libsass/src/to_value.hpp +1 -0
- data/ext/libsass/src/units.cpp +349 -45
- data/ext/libsass/src/units.hpp +39 -22
- data/ext/libsass/src/utf8/checked.h +7 -0
- data/ext/libsass/src/utf8/unchecked.h +7 -0
- data/ext/libsass/src/utf8_string.cpp +1 -1
- data/ext/libsass/src/util.cpp +139 -45
- data/ext/libsass/src/util.hpp +4 -7
- data/ext/libsass/src/values.cpp +15 -23
- data/ext/libsass/win/libsass.sln +13 -2
- data/ext/libsass/win/libsass.sln.DotSettings +9 -0
- data/ext/libsass/win/libsass.targets +3 -0
- data/ext/libsass/win/libsass.vcxproj.filters +9 -0
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +1 -1
- data/test/native_test.rb +1 -1
- metadata +11 -4
data/ext/libsass/src/parser.hpp
CHANGED
|
@@ -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
|
-
|
|
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),
|
|
47
|
-
|
|
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
|
-
//
|
|
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
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
-
|
|
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 (
|
|
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 (
|
|
369
|
+
if (!itpl.isNull()) schema->append(itpl);
|
|
350
370
|
} else {
|
|
351
|
-
return
|
|
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);
|
data/ext/libsass/src/plugins.cpp
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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<
|
|
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 !=
|
|
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<
|
|
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<
|
|
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
|
|
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
|
-
|
|
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 <
|
|
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,
|
|
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);
|