sassc 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/ext/libsass/.gitignore +13 -6
  4. data/ext/libsass/Makefile +42 -26
  5. data/ext/libsass/Makefile.am +43 -30
  6. data/ext/libsass/Readme.md +4 -2
  7. data/ext/libsass/appveyor.yml +10 -14
  8. data/ext/libsass/ast.cpp +54 -44
  9. data/ext/libsass/ast.hpp +404 -236
  10. data/ext/libsass/ast_def_macros.hpp +5 -0
  11. data/ext/libsass/ast_factory.hpp +6 -3
  12. data/ext/libsass/ast_fwd_decl.hpp +12 -0
  13. data/ext/libsass/b64/encode.h +2 -2
  14. data/ext/libsass/backtrace.hpp +13 -17
  15. data/ext/libsass/base64vlq.hpp +4 -1
  16. data/ext/libsass/bind.cpp +12 -15
  17. data/ext/libsass/bind.hpp +6 -6
  18. data/ext/libsass/color_names.hpp +4 -1
  19. data/ext/libsass/configure.ac +7 -21
  20. data/ext/libsass/constants.cpp +6 -4
  21. data/ext/libsass/constants.hpp +10 -4
  22. data/ext/libsass/context.cpp +89 -58
  23. data/ext/libsass/context.hpp +28 -35
  24. data/ext/libsass/contextualize.cpp +20 -10
  25. data/ext/libsass/contextualize.hpp +8 -23
  26. data/ext/libsass/contrib/libsass.spec +66 -0
  27. data/ext/libsass/cssize.cpp +547 -0
  28. data/ext/libsass/cssize.hpp +82 -0
  29. data/ext/libsass/debug.hpp +3 -3
  30. data/ext/libsass/debugger.hpp +358 -0
  31. data/ext/libsass/emitter.cpp +255 -0
  32. data/ext/libsass/emitter.hpp +83 -0
  33. data/ext/libsass/environment.hpp +7 -3
  34. data/ext/libsass/error_handling.cpp +11 -14
  35. data/ext/libsass/error_handling.hpp +9 -7
  36. data/ext/libsass/eval.cpp +253 -161
  37. data/ext/libsass/eval.hpp +13 -13
  38. data/ext/libsass/expand.cpp +135 -64
  39. data/ext/libsass/expand.hpp +11 -13
  40. data/ext/libsass/extend.cpp +66 -20
  41. data/ext/libsass/extend.hpp +6 -11
  42. data/ext/libsass/file.cpp +31 -26
  43. data/ext/libsass/file.hpp +6 -1
  44. data/ext/libsass/functions.cpp +270 -287
  45. data/ext/libsass/functions.hpp +8 -11
  46. data/ext/libsass/inspect.cpp +385 -255
  47. data/ext/libsass/inspect.hpp +15 -26
  48. data/ext/libsass/kwd_arg_macros.hpp +5 -0
  49. data/ext/libsass/mapping.hpp +4 -3
  50. data/ext/libsass/memory_manager.hpp +5 -2
  51. data/ext/libsass/node.cpp +50 -50
  52. data/ext/libsass/node.hpp +26 -27
  53. data/ext/libsass/operation.hpp +15 -4
  54. data/ext/libsass/output.cpp +401 -0
  55. data/ext/libsass/output.hpp +56 -0
  56. data/ext/libsass/parser.cpp +573 -399
  57. data/ext/libsass/parser.hpp +122 -88
  58. data/ext/libsass/paths.hpp +7 -2
  59. data/ext/libsass/plugins.cpp +155 -0
  60. data/ext/libsass/plugins.hpp +56 -0
  61. data/ext/libsass/position.cpp +128 -0
  62. data/ext/libsass/position.hpp +108 -11
  63. data/ext/libsass/prelexer.cpp +184 -110
  64. data/ext/libsass/prelexer.hpp +131 -24
  65. data/ext/libsass/remove_placeholders.cpp +1 -1
  66. data/ext/libsass/remove_placeholders.hpp +6 -6
  67. data/ext/libsass/sass.cpp +3 -3
  68. data/ext/libsass/sass.h +12 -4
  69. data/ext/libsass/sass2scss.cpp +3 -2
  70. data/ext/libsass/sass2scss.h +5 -0
  71. data/ext/libsass/sass_context.cpp +136 -37
  72. data/ext/libsass/sass_context.h +19 -10
  73. data/ext/libsass/sass_functions.cpp +29 -2
  74. data/ext/libsass/sass_functions.h +8 -2
  75. data/ext/libsass/sass_interface.cpp +32 -23
  76. data/ext/libsass/sass_interface.h +9 -4
  77. data/ext/libsass/sass_util.cpp +19 -23
  78. data/ext/libsass/sass_util.hpp +28 -27
  79. data/ext/libsass/sass_values.cpp +6 -4
  80. data/ext/libsass/sass_values.h +3 -3
  81. data/ext/libsass/script/ci-build-libsass +13 -1
  82. data/ext/libsass/script/ci-report-coverage +2 -1
  83. data/ext/libsass/source_map.cpp +79 -28
  84. data/ext/libsass/source_map.hpp +35 -16
  85. data/ext/libsass/subset_map.hpp +6 -4
  86. data/ext/libsass/to_c.hpp +4 -4
  87. data/ext/libsass/to_string.cpp +13 -8
  88. data/ext/libsass/to_string.hpp +6 -4
  89. data/ext/libsass/units.cpp +2 -1
  90. data/ext/libsass/units.hpp +6 -1
  91. data/ext/libsass/utf8_string.cpp +0 -5
  92. data/ext/libsass/utf8_string.hpp +3 -2
  93. data/ext/libsass/util.cpp +461 -49
  94. data/ext/libsass/util.hpp +34 -13
  95. data/ext/libsass/version.sh +10 -0
  96. data/ext/libsass/win/libsass.filters +20 -11
  97. data/ext/libsass/win/libsass.vcxproj +11 -8
  98. data/lib/sassc/importer.rb +1 -8
  99. data/lib/sassc/native.rb +7 -0
  100. data/lib/sassc/native/native_context_api.rb +5 -5
  101. data/lib/sassc/version.rb +1 -1
  102. data/test/native_test.rb +1 -1
  103. metadata +14 -10
  104. data/ext/libsass/copy_c_str.cpp +0 -13
  105. data/ext/libsass/copy_c_str.hpp +0 -5
  106. data/ext/libsass/output_compressed.cpp +0 -401
  107. data/ext/libsass/output_compressed.hpp +0 -95
  108. data/ext/libsass/output_nested.cpp +0 -364
  109. data/ext/libsass/output_nested.hpp +0 -108
  110. data/ext/libsass/test-driver +0 -127
  111. data/ext/libsass/token.hpp +0 -32
@@ -0,0 +1,56 @@
1
+ #ifndef SASS_PLUGINS_H
2
+ #define SASS_PLUGINS_H
3
+
4
+ #include <string>
5
+ #include <vector>
6
+ #include "utf8_string.hpp"
7
+ #include "sass_functions.h"
8
+
9
+ #ifdef _WIN32
10
+
11
+ #define LOAD_LIB(var, path) HMODULE var = LoadLibraryW(UTF_8::convert_to_utf16(path).c_str())
12
+ #define LOAD_LIB_WCHR(var, path_wide_str) HMODULE var = LoadLibraryW(path_wide_str.c_str())
13
+ #define LOAD_LIB_FN(type, var, name) type var = (type) GetProcAddress(plugin, name)
14
+ #define CLOSE_LIB(var) FreeLibrary(var)
15
+
16
+ #ifndef dlerror
17
+ #define dlerror() 0
18
+ #endif
19
+
20
+ #else
21
+
22
+ #define LOAD_LIB(var, path) void* var = dlopen(path.c_str(), RTLD_LAZY)
23
+ #define LOAD_LIB_FN(type, var, name) type var = (type) dlsym(plugin, name)
24
+ #define CLOSE_LIB(var) dlclose(var)
25
+
26
+ #endif
27
+
28
+ namespace Sass {
29
+
30
+ using namespace std;
31
+
32
+ class Plugins {
33
+
34
+ public: // c-tor
35
+ Plugins(void);
36
+ ~Plugins(void);
37
+
38
+ public: // methods
39
+ // load one specific plugin
40
+ bool load_plugin(const string& path);
41
+ // load all plugins from a directory
42
+ size_t load_plugins(const string& path);
43
+
44
+ public: // public accessors
45
+ // const vector<Sass_C_Import_Callback> get_importers(void) { return importers; };
46
+ const vector<Sass_C_Function_Callback> get_functions(void) { return functions; };
47
+
48
+ private: // private vars
49
+ // vector<Sass_C_Import_Callback> importers;
50
+ vector<Sass_C_Function_Callback> functions;
51
+
52
+ };
53
+
54
+ }
55
+
56
+ #endif
@@ -0,0 +1,128 @@
1
+ #include "position.hpp"
2
+
3
+ namespace Sass {
4
+
5
+ using namespace std;
6
+
7
+ Offset::Offset(const char* string)
8
+ : line(0), column(0)
9
+ {
10
+ *this = inc(string, string + strlen(string));
11
+ }
12
+
13
+ Offset::Offset(const string& text)
14
+ : line(0), column(0)
15
+ {
16
+ *this = inc(text.c_str(), text.c_str() + text.size());
17
+ }
18
+
19
+ Offset::Offset(const size_t line, const size_t column)
20
+ : line(line), column(column) { }
21
+
22
+ // increase offset by given string (mostly called by lexer)
23
+ // increase line counter and count columns on the last line
24
+ Offset Offset::inc(const char* begin, const char* end) const
25
+ {
26
+ Offset offset(line, column);
27
+ while (begin < end && *begin) {
28
+ if (*begin == '\n') {
29
+ ++ offset.line;
30
+ offset.column = 0;
31
+ } else {
32
+ ++ offset.column;
33
+ }
34
+ ++begin;
35
+ }
36
+ return offset;
37
+ }
38
+
39
+ bool Offset::operator== (const Offset &pos) const
40
+ {
41
+ return line == pos.line && column == pos.column;
42
+ }
43
+
44
+ bool Offset::operator!= (const Offset &pos) const
45
+ {
46
+ return line != pos.line || column != pos.column;
47
+ }
48
+
49
+ void Offset::operator+= (const Offset &off)
50
+ {
51
+ *this = Offset(line + off.line, off.line > 0 ? off.column : off.column + column);
52
+ }
53
+
54
+ Offset Offset::operator+ (const Offset &off) const
55
+ {
56
+ return Offset(line + off.line, off.line > 0 ? off.column : off.column + column);
57
+ }
58
+
59
+ Position::Position(const size_t file)
60
+ : Offset(0, 0), file(file) { }
61
+
62
+ Position::Position(const size_t file, const Offset& offset)
63
+ : Offset(offset), file(file) { }
64
+
65
+ Position::Position(const size_t line, const size_t column)
66
+ : Offset(line, column), file(-1) { }
67
+
68
+ Position::Position(const size_t file, const size_t line, const size_t column)
69
+ : Offset(line, column), file(file) { }
70
+
71
+
72
+ ParserState::ParserState(string path)
73
+ : Position(-1, 0, 0), path(path), offset(0, 0), token() { }
74
+
75
+ ParserState::ParserState(string path, const size_t file)
76
+ : Position(file, 0, 0), path(path), offset(0, 0), token() { }
77
+
78
+ ParserState::ParserState(string path, Position position, Offset offset)
79
+ : Position(position), path(path), offset(offset), token() { }
80
+
81
+ ParserState::ParserState(string path, Token token, Position position, Offset offset)
82
+ : Position(position), path(path), offset(offset), token(token) { }
83
+
84
+ Position Position::inc(const char* begin, const char* end) const
85
+ {
86
+ Offset offset(line, column);
87
+ offset = offset.inc(begin, end);
88
+ return Position(file, offset);
89
+ }
90
+
91
+ bool Position::operator== (const Position &pos) const
92
+ {
93
+ return file == pos.file && line == pos.line && column == pos.column;
94
+ }
95
+
96
+ bool Position::operator!= (const Position &pos) const
97
+ {
98
+ return file == pos.file || line != pos.line || column != pos.column;
99
+ }
100
+
101
+ void Position::operator+= (const Offset &off)
102
+ {
103
+ *this = Position(file, line + off.line, off.line > 0 ? off.column : off.column + column);
104
+ }
105
+
106
+ const Position Position::operator+ (const Offset &off) const
107
+ {
108
+ return Position(file, line + off.line, off.line > 0 ? off.column : off.column + column);
109
+ }
110
+
111
+ /* not used anymore - remove?
112
+ std::ostream& operator<<(std::ostream& strm, const Offset& off)
113
+ {
114
+ if (off.line == string::npos) strm << "-1:"; else strm << off.line << ":";
115
+ if (off.column == string::npos) strm << "-1"; else strm << off.column;
116
+ return strm;
117
+ } */
118
+
119
+ /* not used anymore - remove?
120
+ std::ostream& operator<<(std::ostream& strm, const Position& pos)
121
+ {
122
+ if (pos.file != string::npos) strm << pos.file << ":";
123
+ if (pos.line == string::npos) strm << "-1:"; else strm << pos.line << ":";
124
+ if (pos.column == string::npos) strm << "-1"; else strm << pos.column;
125
+ return strm;
126
+ } */
127
+
128
+ }
@@ -1,22 +1,119 @@
1
- #define SASS_POSITION
1
+ #ifndef SASS_POSITION_H
2
+ #define SASS_POSITION_H
2
3
 
4
+ #include <string>
5
+ #include <cstring>
3
6
  #include <cstdlib>
7
+ #include <sstream>
8
+ #include <iostream>
4
9
 
5
10
  namespace Sass {
6
11
 
7
- struct Position {
8
- size_t file;
9
- size_t line;
10
- size_t column;
12
+ using namespace std;
11
13
 
12
- Position()
13
- : file(0), line(0), column(0) { }
14
+ class Offset {
14
15
 
15
- Position(const size_t file, const size_t line, const size_t column)
16
- : file(file), line(line), column(column) { }
16
+ public: // c-tor
17
+ Offset(const char* string);
18
+ Offset(const string& text);
19
+ Offset(const size_t line, const size_t column);
20
+
21
+ // return new position, incremented by the given string
22
+ Offset inc(const char* begin, const char* end) const;
23
+
24
+ public: // overload operators for position
25
+ void operator+= (const Offset &pos);
26
+ bool operator== (const Offset &pos) const;
27
+ bool operator!= (const Offset &pos) const;
28
+ Offset operator+ (const Offset &off) const;
29
+
30
+ public: // overload output stream operator
31
+ // friend ostream& operator<<(ostream& strm, const Offset& off);
32
+
33
+ public:
34
+ Offset off() { return *this; };
35
+
36
+ public:
37
+ size_t line;
38
+ size_t column;
39
+
40
+ };
41
+
42
+ class Position : public Offset {
43
+
44
+ public: // c-tor
45
+ Position(const size_t file); // line(0), column(0)
46
+ Position(const size_t file, const Offset& offset);
47
+ Position(const size_t line, const size_t column); // file(-1)
48
+ Position(const size_t file, const size_t line, const size_t column);
49
+
50
+ public: // overload operators for position
51
+ void operator+= (const Offset &off);
52
+ bool operator== (const Position &pos) const;
53
+ bool operator!= (const Position &pos) const;
54
+ const Position operator+ (const Offset &off) const;
55
+ // return new position, incremented by the given string
56
+ Position inc(const char* begin, const char* end) const;
57
+
58
+ public: // overload output stream operator
59
+ // friend ostream& operator<<(ostream& strm, const Position& pos);
60
+
61
+ public:
62
+ size_t file;
63
+
64
+ };
65
+
66
+ // Token type for representing lexed chunks of text
67
+ class Token {
68
+ public:
69
+ const char* prefix;
70
+ const char* begin;
71
+ const char* end;
72
+ const char* suffix;
73
+ Position start;
74
+ Position stop;
75
+
76
+ Token()
77
+ : prefix(0), begin(0), end(0), suffix(0), start(0), stop(0) { }
78
+ Token(const char* b, const char* e, const Position pos)
79
+ : prefix(b), begin(b), end(e), suffix(e), start(pos), stop(pos.inc(b, e)) { }
80
+ Token(const char* s, const Position pos)
81
+ : prefix(s), begin(s), end(s + strlen(s)), suffix(end), start(pos), stop(pos.inc(s, s + strlen(s))) { }
82
+ Token(const char* p, const char* b, const char* e, const char* s, const Position pos)
83
+ : prefix(p), begin(b), end(e), suffix(s), start(pos), stop(pos.inc(b, e)) { }
84
+
85
+ size_t length() const { return end - begin; }
86
+ string ws_before() const { return string(prefix, begin); }
87
+ string to_string() const { return string(begin, end); }
88
+ string ws_after() const { return string(end, suffix); }
89
+
90
+ // string unquote() const;
91
+
92
+ operator bool() { return begin && end && begin >= end; }
93
+ operator string() { return to_string(); }
94
+
95
+ bool operator==(Token t) { return to_string() == t.to_string(); }
96
+ };
97
+
98
+ class ParserState : public Position {
99
+
100
+ public: // c-tor
101
+ ParserState(string path);
102
+ ParserState(string path, const size_t file);
103
+ ParserState(string path, Position position, Offset offset = Offset(0, 0));
104
+ ParserState(string path, Token token, Position position, Offset offset = Offset(0, 0));
105
+
106
+ public: // down casts
107
+ Offset off() { return *this; };
108
+ Position pos() { return *this; };
109
+
110
+ public:
111
+ string path;
112
+ Offset offset;
113
+ Token token;
17
114
 
18
- Position(const size_t line, const size_t column)
19
- : file(0), line(line), column(column) { }
20
115
  };
21
116
 
22
117
  }
118
+
119
+ #endif
@@ -2,9 +2,10 @@
2
2
  #include <cstddef>
3
3
  #include <iostream>
4
4
  #include <iomanip>
5
- #include "constants.hpp"
6
- #include "prelexer.hpp"
7
5
  #include "util.hpp"
6
+ #include "position.hpp"
7
+ #include "prelexer.hpp"
8
+ #include "constants.hpp"
8
9
 
9
10
 
10
11
  namespace Sass {
@@ -13,16 +14,20 @@ namespace Sass {
13
14
  namespace Prelexer {
14
15
  using std::ptrdiff_t;
15
16
  // Matches zero characters (always succeeds without consuming input).
17
+ /* not used anymore - remove?
16
18
  const char* epsilon(char *src) {
17
19
  return src;
18
- }
20
+ }*/
19
21
  // Matches the empty string.
22
+ /* not used anymore - remove?
20
23
  const char* empty(char *src) {
21
24
  return *src ? 0 : src;
22
- }
25
+ }*/
23
26
 
24
27
  // Match any single character.
25
28
  const char* any_char(const char* src) { return *src ? src+1 : src; }
29
+ // Match word boundary (look ahead)
30
+ const char* word_boundary(const char* src) { return !*src || isspace(*src) || ispunct(*src) || !Sass::Util::isAscii(*src) ? src : 0 ; }
26
31
 
27
32
  // Match a single character satisfying the ctype predicates.
28
33
  const char* space(const char* src) { return std::isspace(*src) ? src+1 : 0; }
@@ -54,9 +59,18 @@ namespace Sass {
54
59
  }
55
60
  // Match either comment.
56
61
  const char* comment(const char* src) {
57
- return alternatives<block_comment, line_comment>(src);
62
+ return line_comment(src);
63
+ }
64
+
65
+ const char* wspaces(const char* src) {
66
+ return
67
+ alternatives<
68
+ exactly<' '>,
69
+ exactly<'\t'>
70
+ >(src);
58
71
  }
59
72
 
73
+ /* not used anymore - remove?
60
74
  const char* newline(const char* src) {
61
75
  return
62
76
  alternatives<
@@ -65,79 +79,31 @@ namespace Sass {
65
79
  exactly<'\r'>,
66
80
  exactly<'\f'>
67
81
  >(src);
68
- }
82
+ }*/
69
83
 
84
+ /* not used anymore - remove?
70
85
  const char* whitespace(const char* src) {
71
- return
72
- alternatives<
73
- newline,
74
- exactly<' '>,
75
- exactly<'\t'>
76
- >(src);
77
- }
86
+ return spaces(src);
87
+ }*/
78
88
 
89
+ /* not used anymore - remove?
79
90
  const char* escape(const char* src) {
80
91
  return
81
92
  sequence<
82
93
  exactly<'\\'>,
83
94
  any_char
84
95
  >(src);
85
- }
86
-
87
- // Match double- and single-quoted strings.
88
- const char* double_quoted_string(const char* src) {
89
- src = exactly<'"'>(src);
90
- if (!src) return 0;
91
- const char* p;
92
- while (1) {
93
- if (!*src) return 0;
94
- if((p = escape(src))) {
95
- src = p;
96
- continue;
97
- }
98
- else if((p = exactly<'"'>(src))) {
99
- return p;
100
- }
101
- else {
102
- ++src;
103
- }
104
- }
105
- return 0;
106
- }
107
- const char* single_quoted_string(const char* src) {
108
- src = exactly<'\''>(src);
109
- if (!src) return 0;
110
- const char* p;
111
- while (1) {
112
- if (!*src) return 0;
113
- if((p = escape(src))) {
114
- src = p;
115
- continue;
116
- }
117
- else if((p = exactly<'\''>(src))) {
118
- return p;
119
- }
120
- else {
121
- ++src;
122
- }
123
- }
124
- return 0;
125
- }
126
- const char* string_constant(const char* src) {
127
- return alternatives<double_quoted_string, single_quoted_string>(src);
128
- }
129
- // Match interpolants.
96
+ }*/
130
97
 
131
98
 
132
- const char* interpolant(const char* src) {
133
- return delimited_by<hash_lbrace, rbrace, false>(src);
134
- }
135
-
136
99
  // Whitespace handling.
137
100
  const char* optional_spaces(const char* src) { return optional<spaces>(src); }
138
- const char* optional_comment(const char* src) { return optional<comment>(src); }
101
+ // const char* optional_comment(const char* src) { return optional<comment>(src); }
102
+ const char* optional_spaces_and_comments(const char* src) {
103
+ return zero_plus< alternatives<spaces, line_comment> >(src);
104
+ }
139
105
  const char* spaces_and_comments(const char* src) {
140
- return zero_plus< alternatives<spaces, comment> >(src);
106
+ return one_plus< alternatives<spaces, line_comment> >(src);
141
107
  }
142
108
  const char* no_spaces(const char* src) {
143
109
  return negate< spaces >(src);
@@ -165,6 +131,7 @@ namespace Sass {
165
131
  }
166
132
 
167
133
  // Match CSS selectors.
134
+ /* not used anymore - remove?
168
135
  const char* sel_ident(const char* src) {
169
136
  return sequence< optional< alternatives< exactly<'-'>, exactly<'|'> > >,
170
137
  alternatives< alpha, exactly<'_'>, backslash_something, exactly<'|'> >,
@@ -173,13 +140,25 @@ namespace Sass {
173
140
  exactly<'_'>,
174
141
  exactly<'|'>,
175
142
  backslash_something > > >(src);
176
- }
143
+ }*/
177
144
 
178
145
  // Match CSS css variables.
179
146
  const char* custom_property_name(const char* src) {
180
147
  return sequence< exactly<'-'>, exactly<'-'>, identifier >(src);
181
148
  }
182
149
 
150
+ // Match number prefix ([\+\-]+)
151
+ const char* number_prefix(const char* src) {
152
+ return alternatives <
153
+ exactly < '+' >,
154
+ sequence <
155
+ exactly < '-' >,
156
+ optional_spaces_and_comments,
157
+ exactly< '-' >
158
+ >
159
+ >(src);
160
+ }
161
+
183
162
  // Match interpolant schemas
184
163
  const char* identifier_schema(const char* src) {
185
164
  // follows this pattern: (x*ix*)+ ... well, not quite
@@ -188,17 +167,71 @@ namespace Sass {
188
167
  zero_plus< alternatives< identifier, number, exactly<'-'> > > > >,
189
168
  negate< exactly<'%'> > >(src);
190
169
  }
170
+
171
+ // interpolants can be recursive/nested
172
+ const char* interpolant(const char* src) {
173
+ return recursive_scopes< exactly<hash_lbrace>, exactly<rbrace> >(src);
174
+ }
175
+
176
+ // $re_squote = /'(?:$re_itplnt|\\.|[^'])*'/
177
+ const char* single_quoted_string(const char* src) {
178
+ // match a single quoted string, while skipping interpolants
179
+ return sequence <
180
+ exactly <'\''>,
181
+ zero_plus <
182
+ alternatives <
183
+ // skip all escaped chars first
184
+ backslash_something,
185
+ // skip interpolants
186
+ interpolant,
187
+ // skip non delimiters
188
+ any_char_except < '\'' >
189
+ >
190
+ >,
191
+ exactly <'\''>
192
+ >(src);
193
+ }
194
+
195
+ // $re_dquote = /"(?:$re_itp|\\.|[^"])*"/
196
+ const char* double_quoted_string(const char* src) {
197
+ // match a single quoted string, while skipping interpolants
198
+ return sequence <
199
+ exactly <'"'>,
200
+ zero_plus <
201
+ alternatives <
202
+ // skip all escaped chars first
203
+ backslash_something,
204
+ // skip interpolants
205
+ interpolant,
206
+ // skip non delimiters
207
+ any_char_except < '"' >
208
+ >
209
+ >,
210
+ exactly <'"'>
211
+ >(src);
212
+ }
213
+
214
+ // $re_quoted = /(?:$re_squote|$re_dquote)/
215
+ const char* quoted_string(const char* src) {
216
+ // match a quoted string, while skipping interpolants
217
+ return alternatives<
218
+ single_quoted_string,
219
+ double_quoted_string
220
+ >(src);
221
+ }
222
+
191
223
  const char* value_schema(const char* src) {
192
224
  // follows this pattern: ([xyz]*i[xyz]*)+
193
- return one_plus< sequence< zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant > >,
225
+ return one_plus< sequence< zero_plus< alternatives< identifier, percentage, dimension, hex, number, quoted_string > >,
194
226
  interpolant,
195
- zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant, exactly<'%'> > > > >(src);
227
+ zero_plus< alternatives< identifier, percentage, dimension, hex, number, quoted_string, exactly<'%'> > > > >(src);
196
228
  }
229
+ /* not used anymore - remove?
197
230
  const char* filename_schema(const char* src) {
198
231
  return one_plus< sequence< zero_plus< alternatives< identifier, number, exactly<'.'>, exactly<'/'> > >,
199
232
  interpolant,
200
233
  zero_plus< alternatives< identifier, number, exactly<'.'>, exactly<'/'> > > > >(src);
201
- }
234
+ }*/
202
235
 
203
236
  const char* filename(const char* src) {
204
237
  return one_plus< alternatives< identifier, number, exactly<'.'> > >(src);
@@ -213,6 +246,18 @@ namespace Sass {
213
246
  return exactly<import_kwd>(src);
214
247
  }
215
248
 
249
+ const char* at_root(const char* src) {
250
+ return exactly<at_root_kwd>(src);
251
+ }
252
+
253
+ const char* with_directive(const char* src) {
254
+ return exactly<with_kwd>(src);
255
+ }
256
+
257
+ const char* without_directive(const char* src) {
258
+ return exactly<without_kwd>(src);
259
+ }
260
+
216
261
  const char* media(const char* src) {
217
262
  return exactly<media_kwd>(src);
218
263
  }
@@ -221,17 +266,20 @@ namespace Sass {
221
266
  return exactly<supports_kwd>(src);
222
267
  }
223
268
 
269
+ /* not used anymore - remove?
224
270
  const char* keyframes(const char* src) {
225
271
  return sequence< exactly<'@'>, optional< vendor_prefix >, exactly< keyframes_kwd > >(src);
226
- }
272
+ } */
227
273
 
274
+ /* not used anymore - remove?
228
275
  const char* vendor_prefix(const char* src) {
229
276
  return alternatives< exactly< vendor_opera_kwd >, exactly< vendor_webkit_kwd >, exactly< vendor_mozilla_kwd >, exactly< vendor_ms_kwd >, exactly< vendor_khtml_kwd > >(src);
230
- }
277
+ } */
231
278
 
279
+ /* not used anymore - remove?
232
280
  const char* keyf(const char* src) {
233
281
  return one_plus< alternatives< to, from, percentage > >(src);
234
- }
282
+ } */
235
283
 
236
284
  const char* mixin(const char* src) {
237
285
  return exactly<mixin_kwd>(src);
@@ -254,7 +302,7 @@ namespace Sass {
254
302
  }
255
303
 
256
304
  const char* extend(const char* src) {
257
- return exactly<extend_kwd>(src);
305
+ return sequence < exactly<extend_kwd>, word_boundary >(src);
258
306
  }
259
307
 
260
308
 
@@ -267,7 +315,7 @@ namespace Sass {
267
315
  }
268
316
  const char* elseif_directive(const char* src) {
269
317
  return sequence< else_directive,
270
- spaces_and_comments,
318
+ optional_spaces_and_comments,
271
319
  exactly< if_after_else_kwd > >(src);
272
320
  }
273
321
 
@@ -318,9 +366,10 @@ namespace Sass {
318
366
  return exactly<debug_kwd>(src);
319
367
  }
320
368
 
369
+ /* not used anymore - remove?
321
370
  const char* directive(const char* src) {
322
371
  return sequence< exactly<'@'>, identifier >(src);
323
- }
372
+ } */
324
373
 
325
374
  const char* null(const char* src) {
326
375
  return exactly<null_kwd>(src);
@@ -389,11 +438,12 @@ namespace Sass {
389
438
  return sequence< number, exactly<'%'> >(src);
390
439
  }
391
440
 
441
+ /* not used anymore - remove?
392
442
  const char* em(const char* src) {
393
443
  return sequence< number, exactly<em_kwd> >(src);
394
- }
444
+ } */
395
445
  const char* dimension(const char* src) {
396
- return sequence<number, identifier>(src);
446
+ return sequence<number, one_plus< alpha > >(src);
397
447
  }
398
448
  const char* hex(const char* src) {
399
449
  const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);
@@ -405,54 +455,63 @@ namespace Sass {
405
455
  ptrdiff_t len = p - src;
406
456
  return (len != 4 && len != 7 && len != 9) ? 0 : p;
407
457
  }
458
+ const char* hex0(const char* src) {
459
+ const char* p = sequence< exactly<'0'>, exactly<'x'>, one_plus<xdigit> >(src);
460
+ ptrdiff_t len = p - src;
461
+ return (len != 5 && len != 8) ? 0 : p;
462
+ }
408
463
 
464
+ /* no longer used - remove?
409
465
  const char* rgb_prefix(const char* src) {
410
466
  return exactly<rgb_kwd>(src);
411
- }
467
+ }*/
412
468
  // Match CSS uri specifiers.
413
469
 
414
470
  const char* uri_prefix(const char* src) {
415
471
  return exactly<url_kwd>(src);
416
472
  }
417
473
  // TODO: rename the following two functions
474
+ /* no longer used - remove?
418
475
  const char* uri(const char* src) {
419
476
  return sequence< exactly<url_kwd>,
420
477
  optional<spaces>,
421
- string_constant,
478
+ quoted_string,
422
479
  optional<spaces>,
423
480
  exactly<')'> >(src);
424
- }
481
+ }*/
482
+ /* no longer used - remove?
425
483
  const char* url_value(const char* src) {
426
484
  return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
427
485
  one_plus< sequence< zero_plus< exactly<'/'> >, filename > >, // one or more folders and/or trailing filename
428
486
  optional< exactly<'/'> > >(src);
429
- }
487
+ }*/
488
+ /* no longer used - remove?
430
489
  const char* url_schema(const char* src) {
431
490
  return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
432
491
  filename_schema >(src); // optional trailing slash
433
- }
492
+ }*/
434
493
  // Match CSS "!important" keyword.
435
494
  const char* important(const char* src) {
436
495
  return sequence< exactly<'!'>,
437
- spaces_and_comments,
496
+ optional_spaces_and_comments,
438
497
  exactly<important_kwd> >(src);
439
498
  }
440
499
  // Match CSS "!optional" keyword.
441
500
  const char* optional(const char* src) {
442
501
  return sequence< exactly<'!'>,
443
- spaces_and_comments,
502
+ optional_spaces_and_comments,
444
503
  exactly<optional_kwd> >(src);
445
504
  }
446
505
  // Match Sass "!default" keyword.
447
506
  const char* default_flag(const char* src) {
448
507
  return sequence< exactly<'!'>,
449
- spaces_and_comments,
508
+ optional_spaces_and_comments,
450
509
  exactly<default_kwd> >(src);
451
510
  }
452
511
  // Match Sass "!global" keyword.
453
512
  const char* global_flag(const char* src) {
454
513
  return sequence< exactly<'!'>,
455
- spaces_and_comments,
514
+ optional_spaces_and_comments,
456
515
  exactly<global_kwd> >(src);
457
516
  }
458
517
  // Match CSS pseudo-class/element prefixes.
@@ -485,6 +544,7 @@ namespace Sass {
485
544
  const char* suffix_match(const char* src) { return exactly<dollar_equal>(src); }
486
545
  const char* substring_match(const char* src) { return exactly<star_equal>(src); }
487
546
  // Match CSS combinators.
547
+ /* not used anymore - remove?
488
548
  const char* adjacent_to(const char* src) {
489
549
  return sequence< optional_spaces, exactly<'+'> >(src);
490
550
  }
@@ -496,7 +556,7 @@ namespace Sass {
496
556
  }
497
557
  const char* ancestor_of(const char* src) {
498
558
  return sequence< spaces, negate< exactly<'{'> > >(src);
499
- }
559
+ }*/
500
560
 
501
561
  // Match SCSS variable names.
502
562
  const char* variable(const char* src) {
@@ -550,29 +610,28 @@ namespace Sass {
550
610
  > >,
551
611
  zero_plus < sequence<
552
612
  exactly<'('>,
553
- spaces_and_comments,
613
+ optional_spaces_and_comments,
554
614
  optional < sequence<
555
615
  alternatives< variable, identifier_schema, identifier >,
556
- spaces_and_comments,
616
+ optional_spaces_and_comments,
557
617
  exactly<'='>,
558
- spaces_and_comments,
559
- alternatives< variable, identifier_schema, identifier, string_constant, number, hexa >,
618
+ optional_spaces_and_comments,
619
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >,
560
620
  zero_plus< sequence<
561
- spaces_and_comments,
621
+ optional_spaces_and_comments,
562
622
  exactly<','>,
563
- spaces_and_comments,
623
+ optional_spaces_and_comments,
564
624
  sequence<
565
625
  alternatives< variable, identifier_schema, identifier >,
566
- spaces_and_comments,
626
+ optional_spaces_and_comments,
567
627
  exactly<'='>,
568
- spaces_and_comments,
569
- alternatives< variable, identifier_schema, identifier, string_constant, number, hexa >
628
+ optional_spaces_and_comments,
629
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >
570
630
  >
571
631
  > >
572
632
  > >,
573
- spaces_and_comments,
574
- exactly<')'>,
575
- spaces_and_comments
633
+ optional_spaces_and_comments,
634
+ exactly<')'>
576
635
  > >
577
636
  >(src);
578
637
  }
@@ -584,22 +643,29 @@ namespace Sass {
584
643
  }
585
644
 
586
645
  // const char* ie_args(const char* src) {
587
- // return sequence< alternatives< ie_keyword_arg, value_schema, string_constant, interpolant, number, identifier, delimited_by< '(', ')', true> >,
588
- // zero_plus< sequence< spaces_and_comments, exactly<','>, spaces_and_comments, alternatives< ie_keyword_arg, value_schema, string_constant, interpolant, number, identifier, delimited_by<'(', ')', true> > > > >(src);
646
+ // return sequence< alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by< '(', ')', true> >,
647
+ // zero_plus< sequence< optional_spaces_and_comments, exactly<','>, optional_spaces_and_comments, alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by<'(', ')', true> > > > >(src);
589
648
  // }
590
649
 
591
650
  const char* ie_keyword_arg(const char* src) {
592
- return sequence< alternatives< variable, identifier_schema, identifier >, spaces_and_comments, exactly<'='>, spaces_and_comments, alternatives< variable, identifier_schema, identifier, string_constant, number, hexa > >(src);
651
+ return sequence<
652
+ alternatives< variable, identifier_schema, identifier >,
653
+ optional_spaces_and_comments,
654
+ exactly<'='>,
655
+ optional_spaces_and_comments,
656
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >
657
+ >(src);
593
658
  }
594
659
 
595
660
  // Path matching functions.
661
+ /* not used anymore - remove?
596
662
  const char* folder(const char* src) {
597
663
  return sequence< zero_plus< any_char_except<'/'> >,
598
664
  exactly<'/'> >(src);
599
665
  }
600
666
  const char* folders(const char* src) {
601
667
  return zero_plus< folder >(src);
602
- }
668
+ }*/
603
669
 
604
670
  const char* chunk(const char* src) {
605
671
  char inside_str = 0;
@@ -629,26 +695,30 @@ namespace Sass {
629
695
  }
630
696
 
631
697
  // follow the CSS spec more closely and see if this helps us scan URLs correctly
698
+ /* not used anymore - remove?
632
699
  const char* NL(const char* src) {
633
700
  return alternatives< exactly<'\n'>,
634
701
  sequence< exactly<'\r'>, exactly<'\n'> >,
635
702
  exactly<'\r'>,
636
703
  exactly<'\f'> >(src);
637
- }
704
+ }*/
638
705
 
706
+ /* not used anymore - remove?
639
707
  const char* H(const char* src) {
640
708
  return std::isxdigit(*src) ? src+1 : 0;
641
- }
709
+ }*/
642
710
 
711
+ /* not used anymore - remove?
643
712
  const char* unicode(const char* src) {
644
713
  return sequence< exactly<'\\'>,
645
714
  between<H, 1, 6>,
646
715
  optional< class_char<url_space_chars> > >(src);
647
- }
716
+ }*/
648
717
 
718
+ /* not used anymore - remove?
649
719
  const char* ESCAPE(const char* src) {
650
720
  return alternatives< unicode, class_char<escape_chars> >(src);
651
- }
721
+ }*/
652
722
 
653
723
  const char* url(const char* src) {
654
724
  return chunk(src);
@@ -656,8 +726,8 @@ namespace Sass {
656
726
 
657
727
  const char* static_string(const char* src) {
658
728
  const char* pos = src;
659
- const char * s = string_constant(pos);
660
- Token t(pos, s);
729
+ const char * s = quoted_string(pos);
730
+ Token t(pos, s, Position(0, 0));
661
731
  const unsigned int p = count_interval< interpolant >(t.begin, t.end);
662
732
  return (p == 0) ? t.end : 0;
663
733
  }
@@ -665,6 +735,7 @@ namespace Sass {
665
735
  const char* static_component(const char* src) {
666
736
  return alternatives< identifier,
667
737
  static_string,
738
+ percentage,
668
739
  hex,
669
740
  number,
670
741
  sequence< exactly<'!'>, exactly<important_kwd> >
@@ -675,8 +746,11 @@ namespace Sass {
675
746
  return sequence< static_component,
676
747
  zero_plus < sequence<
677
748
  alternatives<
678
- sequence< optional_spaces, exactly<'/'>, optional_spaces >,
679
- sequence< optional_spaces, exactly<','>, optional_spaces >,
749
+ sequence< optional_spaces, alternatives<
750
+ exactly < '/' >,
751
+ exactly < ',' >,
752
+ exactly < ' ' >
753
+ >, optional_spaces >,
680
754
  spaces
681
755
  >,
682
756
  static_component