sassc 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/ext/libsass/.gitignore +13 -6
- data/ext/libsass/Makefile +42 -26
- data/ext/libsass/Makefile.am +43 -30
- data/ext/libsass/Readme.md +4 -2
- data/ext/libsass/appveyor.yml +10 -14
- data/ext/libsass/ast.cpp +54 -44
- data/ext/libsass/ast.hpp +404 -236
- data/ext/libsass/ast_def_macros.hpp +5 -0
- data/ext/libsass/ast_factory.hpp +6 -3
- data/ext/libsass/ast_fwd_decl.hpp +12 -0
- data/ext/libsass/b64/encode.h +2 -2
- data/ext/libsass/backtrace.hpp +13 -17
- data/ext/libsass/base64vlq.hpp +4 -1
- data/ext/libsass/bind.cpp +12 -15
- data/ext/libsass/bind.hpp +6 -6
- data/ext/libsass/color_names.hpp +4 -1
- data/ext/libsass/configure.ac +7 -21
- data/ext/libsass/constants.cpp +6 -4
- data/ext/libsass/constants.hpp +10 -4
- data/ext/libsass/context.cpp +89 -58
- data/ext/libsass/context.hpp +28 -35
- data/ext/libsass/contextualize.cpp +20 -10
- data/ext/libsass/contextualize.hpp +8 -23
- data/ext/libsass/contrib/libsass.spec +66 -0
- data/ext/libsass/cssize.cpp +547 -0
- data/ext/libsass/cssize.hpp +82 -0
- data/ext/libsass/debug.hpp +3 -3
- data/ext/libsass/debugger.hpp +358 -0
- data/ext/libsass/emitter.cpp +255 -0
- data/ext/libsass/emitter.hpp +83 -0
- data/ext/libsass/environment.hpp +7 -3
- data/ext/libsass/error_handling.cpp +11 -14
- data/ext/libsass/error_handling.hpp +9 -7
- data/ext/libsass/eval.cpp +253 -161
- data/ext/libsass/eval.hpp +13 -13
- data/ext/libsass/expand.cpp +135 -64
- data/ext/libsass/expand.hpp +11 -13
- data/ext/libsass/extend.cpp +66 -20
- data/ext/libsass/extend.hpp +6 -11
- data/ext/libsass/file.cpp +31 -26
- data/ext/libsass/file.hpp +6 -1
- data/ext/libsass/functions.cpp +270 -287
- data/ext/libsass/functions.hpp +8 -11
- data/ext/libsass/inspect.cpp +385 -255
- data/ext/libsass/inspect.hpp +15 -26
- data/ext/libsass/kwd_arg_macros.hpp +5 -0
- data/ext/libsass/mapping.hpp +4 -3
- data/ext/libsass/memory_manager.hpp +5 -2
- data/ext/libsass/node.cpp +50 -50
- data/ext/libsass/node.hpp +26 -27
- data/ext/libsass/operation.hpp +15 -4
- data/ext/libsass/output.cpp +401 -0
- data/ext/libsass/output.hpp +56 -0
- data/ext/libsass/parser.cpp +573 -399
- data/ext/libsass/parser.hpp +122 -88
- data/ext/libsass/paths.hpp +7 -2
- data/ext/libsass/plugins.cpp +155 -0
- data/ext/libsass/plugins.hpp +56 -0
- data/ext/libsass/position.cpp +128 -0
- data/ext/libsass/position.hpp +108 -11
- data/ext/libsass/prelexer.cpp +184 -110
- data/ext/libsass/prelexer.hpp +131 -24
- data/ext/libsass/remove_placeholders.cpp +1 -1
- data/ext/libsass/remove_placeholders.hpp +6 -6
- data/ext/libsass/sass.cpp +3 -3
- data/ext/libsass/sass.h +12 -4
- data/ext/libsass/sass2scss.cpp +3 -2
- data/ext/libsass/sass2scss.h +5 -0
- data/ext/libsass/sass_context.cpp +136 -37
- data/ext/libsass/sass_context.h +19 -10
- data/ext/libsass/sass_functions.cpp +29 -2
- data/ext/libsass/sass_functions.h +8 -2
- data/ext/libsass/sass_interface.cpp +32 -23
- data/ext/libsass/sass_interface.h +9 -4
- data/ext/libsass/sass_util.cpp +19 -23
- data/ext/libsass/sass_util.hpp +28 -27
- data/ext/libsass/sass_values.cpp +6 -4
- data/ext/libsass/sass_values.h +3 -3
- data/ext/libsass/script/ci-build-libsass +13 -1
- data/ext/libsass/script/ci-report-coverage +2 -1
- data/ext/libsass/source_map.cpp +79 -28
- data/ext/libsass/source_map.hpp +35 -16
- data/ext/libsass/subset_map.hpp +6 -4
- data/ext/libsass/to_c.hpp +4 -4
- data/ext/libsass/to_string.cpp +13 -8
- data/ext/libsass/to_string.hpp +6 -4
- data/ext/libsass/units.cpp +2 -1
- data/ext/libsass/units.hpp +6 -1
- data/ext/libsass/utf8_string.cpp +0 -5
- data/ext/libsass/utf8_string.hpp +3 -2
- data/ext/libsass/util.cpp +461 -49
- data/ext/libsass/util.hpp +34 -13
- data/ext/libsass/version.sh +10 -0
- data/ext/libsass/win/libsass.filters +20 -11
- data/ext/libsass/win/libsass.vcxproj +11 -8
- data/lib/sassc/importer.rb +1 -8
- data/lib/sassc/native.rb +7 -0
- data/lib/sassc/native/native_context_api.rb +5 -5
- data/lib/sassc/version.rb +1 -1
- data/test/native_test.rb +1 -1
- metadata +14 -10
- data/ext/libsass/copy_c_str.cpp +0 -13
- data/ext/libsass/copy_c_str.hpp +0 -5
- data/ext/libsass/output_compressed.cpp +0 -401
- data/ext/libsass/output_compressed.hpp +0 -95
- data/ext/libsass/output_nested.cpp +0 -364
- data/ext/libsass/output_nested.hpp +0 -108
- data/ext/libsass/test-driver +0 -127
- data/ext/libsass/token.hpp +0 -32
data/ext/libsass/prelexer.hpp
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
#
|
1
|
+
#ifndef SASS_PRELEXER_H
|
2
|
+
#define SASS_PRELEXER_H
|
3
|
+
|
4
|
+
#include <cstring>
|
2
5
|
|
3
6
|
namespace Sass {
|
4
7
|
namespace Prelexer {
|
@@ -16,7 +19,12 @@ namespace Sass {
|
|
16
19
|
template <const char* prefix>
|
17
20
|
const char* exactly(const char* src) {
|
18
21
|
const char* pre = prefix;
|
19
|
-
|
22
|
+
if (*src == 0) return 0;
|
23
|
+
// there is a small chance that the search prefix
|
24
|
+
// is longer than the rest of the string to look at
|
25
|
+
while (*pre && *src == *pre) {
|
26
|
+
++src, ++pre;
|
27
|
+
}
|
20
28
|
return *pre ? 0 : src;
|
21
29
|
}
|
22
30
|
|
@@ -50,6 +58,14 @@ namespace Sass {
|
|
50
58
|
return p == src ? 0 : p;
|
51
59
|
}
|
52
60
|
|
61
|
+
// Match a sequence of characters up to the next newline.
|
62
|
+
template <char end>
|
63
|
+
const char* until(const char* src) {
|
64
|
+
if (*src == '\n' && exactly<end>(src)) return 0;
|
65
|
+
while (*src && *src != '\n' && !exactly<end>(src)) ++src;
|
66
|
+
return ++src;
|
67
|
+
}
|
68
|
+
|
53
69
|
// Match a sequence of characters up to the next newline.
|
54
70
|
template <const char* prefix>
|
55
71
|
const char* to_endl(const char* src) {
|
@@ -72,6 +88,69 @@ namespace Sass {
|
|
72
88
|
}
|
73
89
|
}
|
74
90
|
|
91
|
+
// skip to delimiter (mx) inside given range
|
92
|
+
// this will savely skip over all quoted strings
|
93
|
+
// recursive skip stuff delimited by start/stop
|
94
|
+
// first start/opener must be consumed already!
|
95
|
+
template<prelexer start, prelexer stop>
|
96
|
+
const char* skip_over_scopes(const char* src, const char* end = 0) {
|
97
|
+
|
98
|
+
size_t level = 0;
|
99
|
+
bool in_squote = false;
|
100
|
+
bool in_dquote = false;
|
101
|
+
// bool in_braces = false;
|
102
|
+
|
103
|
+
while (*src) {
|
104
|
+
|
105
|
+
// check for abort condition
|
106
|
+
if (end && src >= end) break;
|
107
|
+
|
108
|
+
// has escaped sequence?
|
109
|
+
if (*src == '\\') {
|
110
|
+
++ src; // skip this (and next)
|
111
|
+
}
|
112
|
+
else if (*src == '"') {
|
113
|
+
in_dquote = ! in_dquote;
|
114
|
+
}
|
115
|
+
else if (*src == '\'') {
|
116
|
+
in_squote = ! in_squote;
|
117
|
+
}
|
118
|
+
else if (in_dquote || in_squote) {
|
119
|
+
// take everything literally
|
120
|
+
}
|
121
|
+
|
122
|
+
// find another opener inside?
|
123
|
+
else if (start(src)) {
|
124
|
+
++ level; // increase counter
|
125
|
+
}
|
126
|
+
|
127
|
+
// look for the closer (maybe final, maybe not)
|
128
|
+
else if (const char* final = stop(src)) {
|
129
|
+
// only close one level?
|
130
|
+
if (level > 0) -- level;
|
131
|
+
// return position at end of stop
|
132
|
+
// delimiter may be multiple chars
|
133
|
+
else return final;
|
134
|
+
}
|
135
|
+
|
136
|
+
// next
|
137
|
+
++ src;
|
138
|
+
}
|
139
|
+
|
140
|
+
return 0;
|
141
|
+
}
|
142
|
+
|
143
|
+
// Match a sequence of characters delimited by the supplied chars.
|
144
|
+
template <prelexer start, prelexer stop>
|
145
|
+
const char* recursive_scopes(const char* src) {
|
146
|
+
// parse opener
|
147
|
+
src = start(src);
|
148
|
+
// abort if not found
|
149
|
+
if (!src) return 0;
|
150
|
+
// parse the rest until final closer
|
151
|
+
return skip_over_scopes<start, stop>(src);
|
152
|
+
}
|
153
|
+
|
75
154
|
// Match a sequence of characters delimited by the supplied strings.
|
76
155
|
template <const char* beg, const char* end, bool esc>
|
77
156
|
const char* delimited_by(const char* src) {
|
@@ -93,12 +172,14 @@ namespace Sass {
|
|
93
172
|
const char* any_char_except(const char* src) {
|
94
173
|
return (*src && *src != c) ? src+1 : 0;
|
95
174
|
}
|
175
|
+
// Match word boundary (look ahead)
|
176
|
+
const char* word_boundary(const char* src);
|
96
177
|
|
97
178
|
// Matches zero characters (always succeeds without consuming input).
|
98
|
-
const char* epsilon(const char*);
|
179
|
+
// const char* epsilon(const char*);
|
99
180
|
|
100
181
|
// Matches the empty string.
|
101
|
-
const char* empty(const char*);
|
182
|
+
// const char* empty(const char*);
|
102
183
|
|
103
184
|
// Succeeds of the supplied matcher fails, and vice versa.
|
104
185
|
template <prelexer mx>
|
@@ -295,6 +376,10 @@ namespace Sass {
|
|
295
376
|
const char* xdigits(const char* src);
|
296
377
|
const char* alnums(const char* src);
|
297
378
|
const char* puncts(const char* src);
|
379
|
+
// Match certain white-space charactes.
|
380
|
+
const char* wspaces(const char* src);
|
381
|
+
// const char* newline(const char* src);
|
382
|
+
// const char* whitespace(const char* src);
|
298
383
|
|
299
384
|
// Match a line comment.
|
300
385
|
const char* line_comment(const char* src);
|
@@ -308,13 +393,16 @@ namespace Sass {
|
|
308
393
|
// Match double- and single-quoted strings.
|
309
394
|
const char* double_quoted_string(const char* src);
|
310
395
|
const char* single_quoted_string(const char* src);
|
311
|
-
const char*
|
396
|
+
const char* quoted_string(const char* src);
|
312
397
|
// Match interpolants.
|
313
398
|
const char* interpolant(const char* src);
|
399
|
+
// Match number prefix ([\+\-]+)
|
400
|
+
const char* number_prefix(const char* src);
|
314
401
|
|
315
402
|
// Whitespace handling.
|
316
403
|
const char* optional_spaces(const char* src);
|
317
|
-
const char* optional_comment(const char* src);
|
404
|
+
// const char* optional_comment(const char* src);
|
405
|
+
const char* optional_spaces_and_comments(const char* src);
|
318
406
|
const char* spaces_and_comments(const char* src);
|
319
407
|
const char* no_spaces(const char* src);
|
320
408
|
|
@@ -326,22 +414,25 @@ namespace Sass {
|
|
326
414
|
const char* identifier(const char* src);
|
327
415
|
const char* identifier_fragment(const char* src);
|
328
416
|
// Match selector names.
|
329
|
-
const char* sel_ident(const char* src);
|
417
|
+
// const char* sel_ident(const char* src);
|
330
418
|
// Match interpolant schemas
|
331
419
|
const char* identifier_schema(const char* src);
|
332
420
|
const char* value_schema(const char* src);
|
333
421
|
const char* filename(const char* src);
|
334
|
-
const char* filename_schema(const char* src);
|
335
|
-
const char* url_schema(const char* src);
|
336
|
-
const char* url_value(const char* src);
|
422
|
+
// const char* filename_schema(const char* src);
|
423
|
+
// const char* url_schema(const char* src);
|
424
|
+
// const char* url_value(const char* src);
|
337
425
|
const char* vendor_prefix(const char* src);
|
338
426
|
// Match CSS '@' keywords.
|
339
427
|
const char* at_keyword(const char* src);
|
340
428
|
const char* import(const char* src);
|
429
|
+
const char* at_root(const char* src);
|
430
|
+
const char* with_directive(const char* src);
|
431
|
+
const char* without_directive(const char* src);
|
341
432
|
const char* media(const char* src);
|
342
433
|
const char* supports(const char* src);
|
343
|
-
const char* keyframes(const char* src);
|
344
|
-
const char* keyf(const char* src);
|
434
|
+
// const char* keyframes(const char* src);
|
435
|
+
// const char* keyf(const char* src);
|
345
436
|
const char* mixin(const char* src);
|
346
437
|
const char* function(const char* src);
|
347
438
|
const char* return_directive(const char* src);
|
@@ -367,7 +458,7 @@ namespace Sass {
|
|
367
458
|
const char* err(const char* src);
|
368
459
|
const char* dbg(const char* src);
|
369
460
|
|
370
|
-
const char* directive(const char* src);
|
461
|
+
// const char* directive(const char* src);
|
371
462
|
const char* at_keyword(const char* src);
|
372
463
|
|
373
464
|
const char* null(const char* src);
|
@@ -396,10 +487,11 @@ namespace Sass {
|
|
396
487
|
const char* dimension(const char* src);
|
397
488
|
const char* hex(const char* src);
|
398
489
|
const char* hexa(const char* src);
|
399
|
-
const char*
|
490
|
+
const char* hex0(const char* src);
|
491
|
+
// const char* rgb_prefix(const char* src);
|
400
492
|
// Match CSS uri specifiers.
|
401
493
|
const char* uri_prefix(const char* src);
|
402
|
-
const char* uri(const char* src);
|
494
|
+
// const char* uri(const char* src);
|
403
495
|
const char* url(const char* src);
|
404
496
|
// Match CSS "!important" keyword.
|
405
497
|
const char* important(const char* src);
|
@@ -425,10 +517,10 @@ namespace Sass {
|
|
425
517
|
const char* suffix_match(const char* src);
|
426
518
|
const char* substring_match(const char* src);
|
427
519
|
// Match CSS combinators.
|
428
|
-
const char* adjacent_to(const char* src);
|
429
|
-
const char* precedes(const char* src);
|
430
|
-
const char* parent_of(const char* src);
|
431
|
-
const char* ancestor_of(const char* src);
|
520
|
+
// const char* adjacent_to(const char* src);
|
521
|
+
// const char* precedes(const char* src);
|
522
|
+
// const char* parent_of(const char* src);
|
523
|
+
// const char* ancestor_of(const char* src);
|
432
524
|
|
433
525
|
// Match SCSS variable names.
|
434
526
|
const char* variable(const char* src);
|
@@ -456,8 +548,8 @@ namespace Sass {
|
|
456
548
|
const char* url(const char* src);
|
457
549
|
|
458
550
|
// Path matching functions.
|
459
|
-
const char* folder(const char* src);
|
460
|
-
const char* folders(const char* src);
|
551
|
+
// const char* folder(const char* src);
|
552
|
+
// const char* folders(const char* src);
|
461
553
|
|
462
554
|
|
463
555
|
const char* static_string(const char* src);
|
@@ -477,8 +569,11 @@ namespace Sass {
|
|
477
569
|
}
|
478
570
|
template<prelexer mx>
|
479
571
|
const char* find_first_in_interval(const char* beg, const char* end) {
|
572
|
+
bool esc = false;
|
480
573
|
while ((beg < end) && *beg) {
|
481
|
-
if (
|
574
|
+
if (esc) esc = false;
|
575
|
+
else if (*beg == '\\') esc = true;
|
576
|
+
else if (mx(beg)) return beg;
|
482
577
|
++beg;
|
483
578
|
}
|
484
579
|
return 0;
|
@@ -486,8 +581,11 @@ namespace Sass {
|
|
486
581
|
template <char c>
|
487
582
|
unsigned int count_interval(const char* beg, const char* end) {
|
488
583
|
unsigned int counter = 0;
|
584
|
+
bool esc = false;
|
489
585
|
while (beg < end && *beg) {
|
490
|
-
if (
|
586
|
+
if (esc) esc = false;
|
587
|
+
else if (*beg == '\\') esc = true;
|
588
|
+
else if (*beg == c) ++counter;
|
491
589
|
++beg;
|
492
590
|
}
|
493
591
|
return counter;
|
@@ -495,9 +593,16 @@ namespace Sass {
|
|
495
593
|
template <prelexer mx>
|
496
594
|
unsigned int count_interval(const char* beg, const char* end) {
|
497
595
|
unsigned int counter = 0;
|
596
|
+
bool esc = false;
|
498
597
|
while (beg < end && *beg) {
|
499
598
|
const char* p;
|
500
|
-
if (
|
599
|
+
if (esc) {
|
600
|
+
esc = false;
|
601
|
+
++beg;
|
602
|
+
} else if (*beg == '\\') {
|
603
|
+
esc = true;
|
604
|
+
++beg;
|
605
|
+
} else if ((p = mx(beg))) {
|
501
606
|
++counter;
|
502
607
|
beg = p;
|
503
608
|
}
|
@@ -511,3 +616,5 @@ namespace Sass {
|
|
511
616
|
const char* chunk(const char* src);
|
512
617
|
}
|
513
618
|
}
|
619
|
+
|
620
|
+
#endif
|
@@ -17,7 +17,7 @@ namespace Sass {
|
|
17
17
|
Selector_List* sl = static_cast<Selector_List*>(r->selector());
|
18
18
|
|
19
19
|
if (sl) {
|
20
|
-
Selector_List* new_sl = new (ctx.mem) Selector_List(sl->
|
20
|
+
Selector_List* new_sl = new (ctx.mem) Selector_List(sl->pstate());
|
21
21
|
|
22
22
|
for (size_t i = 0, L = sl->length(); i < L; ++i) {
|
23
23
|
if (!(*sl)[i]->has_placeholder()) {
|
@@ -1,20 +1,18 @@
|
|
1
|
+
#ifndef SASS_REMOVE_PLACEHOLDERS_H
|
2
|
+
#define SASS_REMOVE_PLACEHOLDERS_H
|
3
|
+
|
1
4
|
#pragma once
|
2
5
|
|
3
6
|
#include <iostream>
|
4
7
|
|
5
|
-
#ifndef SASS_AST
|
6
8
|
#include "ast.hpp"
|
7
|
-
#endif
|
8
|
-
|
9
|
-
#ifndef SASS_OPERATION
|
10
9
|
#include "operation.hpp"
|
11
|
-
#endif
|
12
10
|
|
13
11
|
namespace Sass {
|
14
12
|
|
15
13
|
using namespace std;
|
16
14
|
|
17
|
-
|
15
|
+
class Context;
|
18
16
|
|
19
17
|
class Remove_Placeholders : public Operation_CRTP<void, Remove_Placeholders> {
|
20
18
|
|
@@ -41,3 +39,5 @@ namespace Sass {
|
|
41
39
|
};
|
42
40
|
|
43
41
|
}
|
42
|
+
|
43
|
+
#endif
|
data/ext/libsass/sass.cpp
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
#include <sstream>
|
5
5
|
|
6
6
|
#include "sass.h"
|
7
|
-
#include "
|
7
|
+
#include "util.hpp"
|
8
8
|
|
9
9
|
extern "C" {
|
10
10
|
using namespace std;
|
11
11
|
|
12
12
|
// caller must free the returned memory
|
13
|
-
char* ADDCALL sass_string_quote (const char *str, const char
|
14
|
-
string quoted = Sass::quote(str,
|
13
|
+
char* ADDCALL sass_string_quote (const char *str, const char quote_mark) {
|
14
|
+
string quoted = Sass::quote(str, quote_mark);
|
15
15
|
char *cstr = (char*) malloc(quoted.length() + 1);
|
16
16
|
std::strcpy(cstr, quoted.c_str());
|
17
17
|
return cstr;
|
data/ext/libsass/sass.h
CHANGED
@@ -1,9 +1,18 @@
|
|
1
|
-
#ifndef
|
2
|
-
#define
|
1
|
+
#ifndef SASS_H
|
2
|
+
#define SASS_H
|
3
3
|
|
4
4
|
#include <stddef.h>
|
5
5
|
#include <stdbool.h>
|
6
6
|
|
7
|
+
#ifdef __GNUC__
|
8
|
+
#define DEPRECATED(func) func __attribute__ ((deprecated))
|
9
|
+
#elif defined(_MSC_VER)
|
10
|
+
#define DEPRECATED(func) __declspec(deprecated) func
|
11
|
+
#else
|
12
|
+
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
|
13
|
+
#define DEPRECATED(func) func
|
14
|
+
#endif
|
15
|
+
|
7
16
|
#ifdef _WIN32
|
8
17
|
|
9
18
|
/* You should define ADD_EXPORTS *only* when building the DLL. */
|
@@ -46,13 +55,12 @@ enum Sass_Output_Style {
|
|
46
55
|
};
|
47
56
|
|
48
57
|
// Some convenient string helper function
|
49
|
-
ADDAPI char* ADDCALL sass_string_quote (const char *str, const char
|
58
|
+
ADDAPI char* ADDCALL sass_string_quote (const char *str, const char quote_mark);
|
50
59
|
ADDAPI char* ADDCALL sass_string_unquote (const char *str);
|
51
60
|
|
52
61
|
// Get compiled libsass version
|
53
62
|
ADDAPI const char* ADDCALL libsass_version(void);
|
54
63
|
|
55
|
-
|
56
64
|
#ifdef __cplusplus
|
57
65
|
} // __cplusplus defined.
|
58
66
|
#endif
|
data/ext/libsass/sass2scss.cpp
CHANGED
@@ -561,11 +561,12 @@ namespace Sass
|
|
561
561
|
|
562
562
|
}
|
563
563
|
|
564
|
-
// terminate
|
564
|
+
// terminate some statements immediately
|
565
565
|
else if (
|
566
566
|
sass.substr(pos_left, 5) == "@warn" ||
|
567
567
|
sass.substr(pos_left, 6) == "@debug" ||
|
568
|
-
sass.substr(pos_left, 6) == "@error"
|
568
|
+
sass.substr(pos_left, 6) == "@error" ||
|
569
|
+
sass.substr(pos_left, 8) == "@charset"
|
569
570
|
) { sass = indent + sass.substr(pos_left); }
|
570
571
|
// replace some specific sass shorthand directives (if not fallowed by a white space character)
|
571
572
|
else if (sass.substr(pos_left, 1) == "=" && sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left) != pos_left + 1)
|
data/ext/libsass/sass2scss.h
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
#ifdef _WIN32
|
2
2
|
#include <io.h>
|
3
|
+
#define LFEED "\n"
|
3
4
|
#else
|
4
5
|
#include <unistd.h>
|
6
|
+
#define LFEED "\n"
|
5
7
|
#endif
|
6
8
|
|
9
|
+
#include <cstring>
|
7
10
|
#include <stdexcept>
|
11
|
+
#include "file.hpp"
|
8
12
|
#include "json.hpp"
|
13
|
+
#include "util.hpp"
|
9
14
|
#include "context.hpp"
|
10
15
|
#include "sass_values.h"
|
11
16
|
#include "sass_context.h"
|
17
|
+
#include "error_handling.hpp"
|
12
18
|
|
13
19
|
extern "C" {
|
14
20
|
using namespace std;
|
@@ -68,22 +74,30 @@ extern "C" {
|
|
68
74
|
// information in source-maps etc.
|
69
75
|
char* output_path;
|
70
76
|
|
71
|
-
//
|
72
|
-
char*
|
77
|
+
// String to be used for indentation
|
78
|
+
const char* indent;
|
79
|
+
// String to be used to for line feeds
|
80
|
+
const char* linefeed;
|
73
81
|
|
74
82
|
// Colon-separated list of paths
|
75
83
|
// Semicolon-separated on Windows
|
76
84
|
// Maybe use array interface instead?
|
77
85
|
char* include_path;
|
86
|
+
char* plugin_path;
|
78
87
|
|
79
|
-
// Include
|
88
|
+
// Include paths (linked string list)
|
80
89
|
struct string_list* include_paths;
|
90
|
+
// Plugin paths (linked string list)
|
91
|
+
struct string_list* plugin_paths;
|
81
92
|
|
82
93
|
// Path to source map file
|
83
94
|
// Enables source map generation
|
84
95
|
// Used to create sourceMappingUrl
|
85
96
|
char* source_map_file;
|
86
97
|
|
98
|
+
// Directly inserted in source maps
|
99
|
+
char* source_map_root;
|
100
|
+
|
87
101
|
// Custom functions that can be called from sccs code
|
88
102
|
Sass_C_Function_List c_functions;
|
89
103
|
|
@@ -108,6 +122,7 @@ extern "C" {
|
|
108
122
|
// error status
|
109
123
|
int error_status;
|
110
124
|
char* error_json;
|
125
|
+
char* error_text;
|
111
126
|
char* error_message;
|
112
127
|
// error position
|
113
128
|
char* error_file;
|
@@ -162,7 +177,7 @@ extern "C" {
|
|
162
177
|
#define IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(type, option) \
|
163
178
|
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return options->option; } \
|
164
179
|
void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) \
|
165
|
-
{ free(options->option); options->option = option ?
|
180
|
+
{ free(options->option); options->option = option ? sass_strdup(option) : 0; }
|
166
181
|
|
167
182
|
#define IMPLEMENT_SASS_CONTEXT_GETTER(type, option) \
|
168
183
|
type ADDCALL sass_context_get_##option (struct Sass_Context* ctx) { return ctx->option; }
|
@@ -175,7 +190,7 @@ extern "C" {
|
|
175
190
|
return str == NULL ? "" : str;
|
176
191
|
}
|
177
192
|
|
178
|
-
static void copy_strings(const std::vector<std::string>& strings, char*** array, int skip = 0) {
|
193
|
+
static void copy_strings(const std::vector<std::string>& strings, char*** array, int skip = 0) throw() {
|
179
194
|
int num = static_cast<int>(strings.size());
|
180
195
|
char** arr = (char**) malloc(sizeof(char*) * (num + 1));
|
181
196
|
if (arr == 0) throw(bad_alloc());
|
@@ -210,19 +225,37 @@ extern "C" {
|
|
210
225
|
}
|
211
226
|
catch (Sass_Error& e) {
|
212
227
|
stringstream msg_stream;
|
228
|
+
string cwd(Sass::File::get_cwd());
|
213
229
|
JsonNode* json_err = json_mkobject();
|
214
230
|
json_append_member(json_err, "status", json_mknumber(1));
|
215
|
-
json_append_member(json_err, "file", json_mkstring(e.path.c_str()));
|
216
|
-
json_append_member(json_err, "line", json_mknumber(e.
|
217
|
-
json_append_member(json_err, "column", json_mknumber(e.
|
231
|
+
json_append_member(json_err, "file", json_mkstring(e.pstate.path.c_str()));
|
232
|
+
json_append_member(json_err, "line", json_mknumber(e.pstate.line+1));
|
233
|
+
json_append_member(json_err, "column", json_mknumber(e.pstate.column+1));
|
218
234
|
json_append_member(json_err, "message", json_mkstring(e.message.c_str()));
|
219
|
-
|
235
|
+
string rel_path(Sass::File::resolve_relative_path(e.pstate.path, cwd, cwd));
|
236
|
+
|
237
|
+
string msg_prefix("Error: ");
|
238
|
+
bool got_newline = false;
|
239
|
+
msg_stream << msg_prefix;
|
240
|
+
for (char chr : e.message) {
|
241
|
+
if (chr == '\n') {
|
242
|
+
got_newline = true;
|
243
|
+
} else if (got_newline) {
|
244
|
+
msg_stream << string(msg_prefix.size(), ' ');
|
245
|
+
got_newline = false;
|
246
|
+
}
|
247
|
+
msg_stream << chr;
|
248
|
+
}
|
249
|
+
if (!got_newline) msg_stream << "\n";
|
250
|
+
msg_stream << string(msg_prefix.size(), ' ');
|
251
|
+
msg_stream << " on line " << e.pstate.line+1 << " of " << rel_path << "\n";
|
220
252
|
c_ctx->error_json = json_stringify(json_err, " ");;
|
221
|
-
c_ctx->error_message =
|
253
|
+
c_ctx->error_message = sass_strdup(msg_stream.str().c_str());
|
254
|
+
c_ctx->error_text = strdup(e.message.c_str());
|
222
255
|
c_ctx->error_status = 1;
|
223
|
-
c_ctx->error_file =
|
224
|
-
c_ctx->error_line = e.
|
225
|
-
c_ctx->error_column = e.
|
256
|
+
c_ctx->error_file = sass_strdup(e.pstate.path.c_str());
|
257
|
+
c_ctx->error_line = e.pstate.line+1;
|
258
|
+
c_ctx->error_column = e.pstate.column+1;
|
226
259
|
c_ctx->output_string = 0;
|
227
260
|
c_ctx->source_map_string = 0;
|
228
261
|
json_delete(json_err);
|
@@ -234,7 +267,8 @@ extern "C" {
|
|
234
267
|
json_append_member(json_err, "status", json_mknumber(2));
|
235
268
|
json_append_member(json_err, "message", json_mkstring(ba.what()));
|
236
269
|
c_ctx->error_json = json_stringify(json_err, " ");;
|
237
|
-
c_ctx->error_message =
|
270
|
+
c_ctx->error_message = sass_strdup(msg_stream.str().c_str());
|
271
|
+
c_ctx->error_text = strdup(ba.what());
|
238
272
|
c_ctx->error_status = 2;
|
239
273
|
c_ctx->output_string = 0;
|
240
274
|
c_ctx->source_map_string = 0;
|
@@ -247,7 +281,8 @@ extern "C" {
|
|
247
281
|
json_append_member(json_err, "status", json_mknumber(3));
|
248
282
|
json_append_member(json_err, "message", json_mkstring(e.what()));
|
249
283
|
c_ctx->error_json = json_stringify(json_err, " ");;
|
250
|
-
c_ctx->error_message =
|
284
|
+
c_ctx->error_message = sass_strdup(msg_stream.str().c_str());
|
285
|
+
c_ctx->error_text = strdup(e.what());
|
251
286
|
c_ctx->error_status = 3;
|
252
287
|
c_ctx->output_string = 0;
|
253
288
|
c_ctx->source_map_string = 0;
|
@@ -260,7 +295,8 @@ extern "C" {
|
|
260
295
|
json_append_member(json_err, "status", json_mknumber(4));
|
261
296
|
json_append_member(json_err, "message", json_mkstring(e.c_str()));
|
262
297
|
c_ctx->error_json = json_stringify(json_err, " ");;
|
263
|
-
c_ctx->error_message =
|
298
|
+
c_ctx->error_message = sass_strdup(msg_stream.str().c_str());
|
299
|
+
c_ctx->error_text = strdup(e.c_str());
|
264
300
|
c_ctx->error_status = 4;
|
265
301
|
c_ctx->output_string = 0;
|
266
302
|
c_ctx->source_map_string = 0;
|
@@ -273,7 +309,8 @@ extern "C" {
|
|
273
309
|
json_append_member(json_err, "status", json_mknumber(5));
|
274
310
|
json_append_member(json_err, "message", json_mkstring("unknown"));
|
275
311
|
c_ctx->error_json = json_stringify(json_err, " ");;
|
276
|
-
c_ctx->error_message =
|
312
|
+
c_ctx->error_message = sass_strdup(msg_stream.str().c_str());
|
313
|
+
c_ctx->error_text = strdup("unknown");
|
277
314
|
c_ctx->error_status = 5;
|
278
315
|
c_ctx->output_string = 0;
|
279
316
|
c_ctx->source_map_string = 0;
|
@@ -297,19 +334,35 @@ extern "C" {
|
|
297
334
|
}
|
298
335
|
|
299
336
|
// convert include path linked list to static array
|
300
|
-
struct string_list*
|
337
|
+
struct string_list* inc = c_ctx->include_paths;
|
301
338
|
// very poor loop to get the length of the linked list
|
302
|
-
size_t
|
339
|
+
size_t inc_size = 0; while (inc) { inc_size ++; inc = inc->next; }
|
303
340
|
// create char* array to hold all paths plus null terminator
|
304
|
-
const char** include_paths = (const char**) calloc(
|
341
|
+
const char** include_paths = (const char**) calloc(inc_size + 1, sizeof(char*));
|
305
342
|
if (include_paths == 0) throw(bad_alloc());
|
306
343
|
// reset iterator
|
307
|
-
|
344
|
+
inc = c_ctx->include_paths;
|
345
|
+
// copy over the paths
|
346
|
+
for (size_t i = 0; inc; i++) {
|
347
|
+
include_paths[i] = inc->string;
|
348
|
+
inc = inc->next;
|
349
|
+
}
|
350
|
+
|
351
|
+
// convert plugin path linked list to static array
|
352
|
+
struct string_list* imp = c_ctx->plugin_paths;
|
353
|
+
// very poor loop to get the length of the linked list
|
354
|
+
size_t imp_size = 0; while (imp) { imp_size ++; imp = imp->next; }
|
355
|
+
// create char* array to hold all paths plus null terminator
|
356
|
+
const char** plugin_paths = (const char**) calloc(imp_size + 1, sizeof(char*));
|
357
|
+
if (plugin_paths == 0) throw(bad_alloc());
|
358
|
+
// reset iterator
|
359
|
+
imp = c_ctx->plugin_paths;
|
308
360
|
// copy over the paths
|
309
|
-
for (size_t i = 0;
|
310
|
-
|
311
|
-
|
361
|
+
for (size_t i = 0; imp; i++) {
|
362
|
+
plugin_paths[i] = imp->string;
|
363
|
+
imp = imp->next;
|
312
364
|
}
|
365
|
+
|
313
366
|
// transfer the options to c++
|
314
367
|
cpp_opt.input_path(input_path)
|
315
368
|
.output_path(output_path)
|
@@ -317,20 +370,26 @@ extern "C" {
|
|
317
370
|
.is_indented_syntax_src(c_ctx->is_indented_syntax_src)
|
318
371
|
.source_comments(c_ctx->source_comments)
|
319
372
|
.source_map_file(safe_str(c_ctx->source_map_file))
|
373
|
+
.source_map_root(safe_str(c_ctx->source_map_root))
|
320
374
|
.source_map_embed(c_ctx->source_map_embed)
|
321
375
|
.source_map_contents(c_ctx->source_map_contents)
|
322
376
|
.omit_source_map_url(c_ctx->omit_source_map_url)
|
323
|
-
.image_path(safe_str(c_ctx->image_path))
|
324
377
|
.include_paths_c_str(c_ctx->include_path)
|
325
|
-
.
|
378
|
+
.plugin_paths_c_str(c_ctx->plugin_path)
|
326
379
|
.include_paths_array(include_paths)
|
380
|
+
.plugin_paths_array(plugin_paths)
|
327
381
|
.include_paths(vector<string>())
|
328
|
-
.
|
382
|
+
.plugin_paths(vector<string>())
|
383
|
+
.importer(c_ctx->importer)
|
384
|
+
.precision(c_ctx->precision ? c_ctx->precision : 5)
|
385
|
+
.linefeed(c_ctx->linefeed ? c_ctx->linefeed : LFEED)
|
386
|
+
.indent(c_ctx->indent ? c_ctx->indent : " ");
|
329
387
|
|
330
388
|
// create new c++ Context
|
331
389
|
Context* cpp_ctx = new Context(cpp_opt);
|
332
390
|
// free intermediate data
|
333
391
|
free(include_paths);
|
392
|
+
free(plugin_paths);
|
334
393
|
|
335
394
|
// register our custom functions
|
336
395
|
if (c_ctx->c_functions) {
|
@@ -343,6 +402,7 @@ extern "C" {
|
|
343
402
|
|
344
403
|
// reset error status
|
345
404
|
c_ctx->error_json = 0;
|
405
|
+
c_ctx->error_text = 0;
|
346
406
|
c_ctx->error_message = 0;
|
347
407
|
c_ctx->error_status = 0;
|
348
408
|
// reset error position
|
@@ -386,7 +446,7 @@ extern "C" {
|
|
386
446
|
}
|
387
447
|
|
388
448
|
// copy the included files on to the context (dont forget to free)
|
389
|
-
copy_strings(cpp_ctx->get_included_files(skip), &c_ctx->included_files, skip);
|
449
|
+
if (root) copy_strings(cpp_ctx->get_included_files(skip), &c_ctx->included_files, skip);
|
390
450
|
|
391
451
|
// return parsed block
|
392
452
|
return root;
|
@@ -504,7 +564,7 @@ extern "C" {
|
|
504
564
|
if (*data_ctx->source_string == 0) { throw(runtime_error("Data context has empty source string")); }
|
505
565
|
cpp_opt.source_c_str(data_ctx->source_string);
|
506
566
|
}
|
507
|
-
catch (...) { return handle_errors(c_ctx)
|
567
|
+
catch (...) { return handle_errors(c_ctx) | 1; }
|
508
568
|
return sass_compile_context(c_ctx, cpp_opt);
|
509
569
|
}
|
510
570
|
|
@@ -520,7 +580,7 @@ extern "C" {
|
|
520
580
|
if (*file_ctx->input_path == 0) { throw(runtime_error("File context has empty input path")); }
|
521
581
|
cpp_opt.entry_point(file_ctx->input_path);
|
522
582
|
}
|
523
|
-
catch (...) { return handle_errors(c_ctx)
|
583
|
+
catch (...) { return handle_errors(c_ctx) | 1; }
|
524
584
|
return sass_compile_context(c_ctx, cpp_opt);
|
525
585
|
}
|
526
586
|
|
@@ -557,7 +617,7 @@ extern "C" {
|
|
557
617
|
// compile the parsed root block
|
558
618
|
try { compiler->c_ctx->output_string = cpp_ctx->compile_block(root); }
|
559
619
|
// pass catched errors to generic error handler
|
560
|
-
catch (...) { return handle_errors(compiler->c_ctx)
|
620
|
+
catch (...) { return handle_errors(compiler->c_ctx) | 1; }
|
561
621
|
// generate source map json and store on context
|
562
622
|
compiler->c_ctx->source_map_string = cpp_ctx->generate_source_map();
|
563
623
|
// success
|
@@ -576,7 +636,19 @@ extern "C" {
|
|
576
636
|
++this_func_data;
|
577
637
|
}
|
578
638
|
}
|
579
|
-
//
|
639
|
+
// Deallocate inc paths
|
640
|
+
if (options->plugin_paths) {
|
641
|
+
struct string_list* cur;
|
642
|
+
struct string_list* next;
|
643
|
+
cur = options->plugin_paths;
|
644
|
+
while (cur) {
|
645
|
+
next = cur->next;
|
646
|
+
free(cur->string);
|
647
|
+
free(cur);
|
648
|
+
cur = next;
|
649
|
+
}
|
650
|
+
}
|
651
|
+
// Deallocate inc paths
|
580
652
|
if (options->include_paths) {
|
581
653
|
struct string_list* cur;
|
582
654
|
struct string_list* next;
|
@@ -595,6 +667,7 @@ extern "C" {
|
|
595
667
|
// Make it null terminated
|
596
668
|
options->importer = 0;
|
597
669
|
options->c_functions = 0;
|
670
|
+
options->plugin_paths = 0;
|
598
671
|
options->include_paths = 0;
|
599
672
|
}
|
600
673
|
|
@@ -603,29 +676,31 @@ extern "C" {
|
|
603
676
|
static void sass_clear_context (struct Sass_Context* ctx)
|
604
677
|
{
|
605
678
|
if (ctx == 0) return;
|
606
|
-
// release the allocated memory (mostly via
|
679
|
+
// release the allocated memory (mostly via sass_strdup)
|
607
680
|
if (ctx->output_string) free(ctx->output_string);
|
608
681
|
if (ctx->source_map_string) free(ctx->source_map_string);
|
609
682
|
if (ctx->error_message) free(ctx->error_message);
|
683
|
+
if (ctx->error_text) free(ctx->error_text);
|
610
684
|
if (ctx->error_json) free(ctx->error_json);
|
611
685
|
if (ctx->error_file) free(ctx->error_file);
|
612
686
|
if (ctx->input_path) free(ctx->input_path);
|
613
687
|
if (ctx->output_path) free(ctx->output_path);
|
614
|
-
if (ctx->image_path) free(ctx->image_path);
|
615
688
|
if (ctx->include_path) free(ctx->include_path);
|
616
689
|
if (ctx->source_map_file) free(ctx->source_map_file);
|
690
|
+
if (ctx->source_map_root) free(ctx->source_map_root);
|
617
691
|
free_string_array(ctx->included_files);
|
618
692
|
// play safe and reset properties
|
619
693
|
ctx->output_string = 0;
|
620
694
|
ctx->source_map_string = 0;
|
621
695
|
ctx->error_message = 0;
|
696
|
+
ctx->error_text = 0;
|
622
697
|
ctx->error_json = 0;
|
623
698
|
ctx->error_file = 0;
|
624
699
|
ctx->input_path = 0;
|
625
700
|
ctx->output_path = 0;
|
626
|
-
ctx->image_path = 0;
|
627
701
|
ctx->include_path = 0;
|
628
702
|
ctx->source_map_file = 0;
|
703
|
+
ctx->source_map_root = 0;
|
629
704
|
ctx->included_files = 0;
|
630
705
|
// now clear the options
|
631
706
|
sass_clear_options(ctx);
|
@@ -665,16 +740,20 @@ extern "C" {
|
|
665
740
|
IMPLEMENT_SASS_OPTION_ACCESSOR(bool, is_indented_syntax_src);
|
666
741
|
IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_C_Function_List, c_functions);
|
667
742
|
IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_C_Import_Callback, importer);
|
743
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, indent);
|
744
|
+
IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, linefeed);
|
668
745
|
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, input_path);
|
669
746
|
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, output_path);
|
670
|
-
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*,
|
747
|
+
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, plugin_path);
|
671
748
|
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, include_path);
|
672
749
|
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_file);
|
750
|
+
IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_root);
|
673
751
|
|
674
752
|
// Create getter and setters for context
|
675
753
|
IMPLEMENT_SASS_CONTEXT_GETTER(int, error_status);
|
676
754
|
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_json);
|
677
755
|
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_message);
|
756
|
+
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_text);
|
678
757
|
IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_file);
|
679
758
|
IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_line);
|
680
759
|
IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_column);
|
@@ -685,6 +764,7 @@ extern "C" {
|
|
685
764
|
// Take ownership of memory (value on context is set to 0)
|
686
765
|
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_json);
|
687
766
|
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_message);
|
767
|
+
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_text);
|
688
768
|
IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_file);
|
689
769
|
IMPLEMENT_SASS_CONTEXT_TAKER(char*, output_string);
|
690
770
|
IMPLEMENT_SASS_CONTEXT_TAKER(char*, source_map_string);
|
@@ -695,7 +775,7 @@ extern "C" {
|
|
695
775
|
|
696
776
|
struct string_list* include_path = (struct string_list*) calloc(1, sizeof(struct string_list));
|
697
777
|
if (include_path == 0) return;
|
698
|
-
include_path->string =
|
778
|
+
include_path->string = path ? sass_strdup(path) : 0;
|
699
779
|
struct string_list* last = options->include_paths;
|
700
780
|
if (!options->include_paths) {
|
701
781
|
options->include_paths = include_path;
|
@@ -706,4 +786,23 @@ extern "C" {
|
|
706
786
|
}
|
707
787
|
|
708
788
|
}
|
789
|
+
|
790
|
+
// Push function for plugin paths (no manipulation support for now)
|
791
|
+
void ADDCALL sass_option_push_plugin_path(struct Sass_Options* options, const char* path)
|
792
|
+
{
|
793
|
+
|
794
|
+
struct string_list* plugin_path = (struct string_list*) calloc(1, sizeof(struct string_list));
|
795
|
+
if (plugin_path == 0) return;
|
796
|
+
plugin_path->string = path ? sass_strdup(path) : 0;
|
797
|
+
struct string_list* last = options->plugin_paths;
|
798
|
+
if (!options->plugin_paths) {
|
799
|
+
options->plugin_paths = plugin_path;
|
800
|
+
} else {
|
801
|
+
while (last->next)
|
802
|
+
last = last->next;
|
803
|
+
last->next = plugin_path;
|
804
|
+
}
|
805
|
+
|
806
|
+
}
|
807
|
+
|
709
808
|
}
|