sassc 2.0.0 → 2.4.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 +4 -4
- data/.gitignore +2 -0
- data/.gitmodules +1 -1
- data/.travis.yml +9 -3
- data/CHANGELOG.md +36 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/README.md +1 -1
- data/Rakefile +43 -7
- data/ext/depend +4 -0
- data/ext/extconf.rb +92 -0
- data/ext/libsass/VERSION +1 -0
- data/ext/libsass/include/sass/base.h +9 -1
- data/ext/libsass/include/sass/context.h +5 -1
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +755 -2028
- data/ext/libsass/src/ast.hpp +492 -2477
- data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +70 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +275 -0
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +1043 -0
- data/ext/libsass/src/ast_selectors.hpp +522 -0
- data/ext/libsass/src/ast_supports.cpp +114 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +1154 -0
- data/ext/libsass/src/ast_values.hpp +498 -0
- data/ext/libsass/src/backtrace.cpp +11 -7
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +5 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +35 -34
- data/ext/libsass/src/bind.hpp +3 -1
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +83 -88
- data/ext/libsass/src/check_nesting.hpp +39 -34
- data/ext/libsass/src/color_maps.cpp +168 -164
- data/ext/libsass/src/color_maps.hpp +152 -160
- data/ext/libsass/src/constants.cpp +20 -0
- data/ext/libsass/src/constants.hpp +19 -0
- data/ext/libsass/src/context.cpp +104 -121
- data/ext/libsass/src/context.hpp +43 -55
- data/ext/libsass/src/cssize.cpp +103 -188
- data/ext/libsass/src/cssize.hpp +45 -51
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +524 -361
- data/ext/libsass/src/emitter.cpp +26 -26
- data/ext/libsass/src/emitter.hpp +20 -18
- data/ext/libsass/src/environment.cpp +41 -27
- data/ext/libsass/src/environment.hpp +33 -22
- data/ext/libsass/src/error_handling.cpp +92 -94
- data/ext/libsass/src/error_handling.hpp +73 -50
- data/ext/libsass/src/eval.cpp +380 -515
- data/ext/libsass/src/eval.hpp +64 -57
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +322 -263
- data/ext/libsass/src/expand.hpp +55 -39
- data/ext/libsass/src/extender.cpp +1188 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +134 -88
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +596 -0
- data/ext/libsass/src/fn_colors.hpp +85 -0
- data/ext/libsass/src/fn_lists.cpp +285 -0
- data/ext/libsass/src/fn_lists.hpp +34 -0
- data/ext/libsass/src/fn_maps.cpp +94 -0
- data/ext/libsass/src/fn_maps.hpp +30 -0
- data/ext/libsass/src/fn_miscs.cpp +244 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +227 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +205 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +268 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +158 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +253 -266
- data/ext/libsass/src/inspect.hpp +72 -74
- data/ext/libsass/src/json.cpp +2 -2
- data/ext/libsass/src/lexer.cpp +25 -84
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +27 -43
- data/ext/libsass/src/listize.hpp +14 -11
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
- data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
- data/ext/libsass/src/operation.hpp +193 -143
- data/ext/libsass/src/operators.cpp +56 -29
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +59 -75
- data/ext/libsass/src/output.hpp +15 -22
- data/ext/libsass/src/parser.cpp +662 -818
- data/ext/libsass/src/parser.hpp +96 -100
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +12 -8
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +10 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +14 -8
- data/ext/libsass/src/prelexer.hpp +9 -9
- data/ext/libsass/src/remove_placeholders.cpp +59 -57
- data/ext/libsass/src/remove_placeholders.hpp +20 -18
- data/ext/libsass/src/sass.cpp +25 -18
- data/ext/libsass/src/sass.hpp +22 -14
- data/ext/libsass/src/sass2scss.cpp +49 -18
- data/ext/libsass/src/sass_context.cpp +104 -132
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +7 -4
- data/ext/libsass/src/sass_functions.hpp +1 -1
- data/ext/libsass/src/sass_values.cpp +26 -21
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +27 -20
- data/ext/libsass/src/source_map.hpp +14 -11
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +24 -22
- data/ext/libsass/src/to_value.hpp +18 -22
- data/ext/libsass/src/units.cpp +28 -22
- data/ext/libsass/src/units.hpp +9 -8
- data/ext/libsass/src/utf8/checked.h +12 -10
- data/ext/libsass/src/utf8/core.h +3 -0
- data/ext/libsass/src/utf8_string.cpp +12 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +97 -107
- data/ext/libsass/src/util.hpp +74 -30
- data/ext/libsass/src/util_string.cpp +125 -0
- data/ext/libsass/src/util_string.hpp +73 -0
- data/ext/libsass/src/values.cpp +33 -24
- data/ext/libsass/src/values.hpp +2 -2
- data/lib/sassc.rb +24 -0
- data/lib/sassc/engine.rb +7 -5
- data/lib/sassc/functions_handler.rb +11 -13
- data/lib/sassc/native.rb +10 -9
- data/lib/sassc/native/native_functions_api.rb +0 -5
- data/lib/sassc/script.rb +4 -6
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +32 -12
- data/test/engine_test.rb +32 -2
- data/test/functions_test.rb +38 -1
- data/test/native_test.rb +4 -4
- metadata +95 -109
- data/ext/Rakefile +0 -3
- data/ext/libsass/.editorconfig +0 -15
- data/ext/libsass/.gitattributes +0 -2
- data/ext/libsass/.github/CONTRIBUTING.md +0 -65
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
- data/ext/libsass/.gitignore +0 -85
- data/ext/libsass/.travis.yml +0 -64
- data/ext/libsass/COPYING +0 -25
- data/ext/libsass/GNUmakefile.am +0 -88
- data/ext/libsass/INSTALL +0 -1
- data/ext/libsass/LICENSE +0 -25
- data/ext/libsass/Makefile +0 -351
- data/ext/libsass/Makefile.conf +0 -55
- data/ext/libsass/Readme.md +0 -104
- data/ext/libsass/SECURITY.md +0 -10
- data/ext/libsass/appveyor.yml +0 -91
- data/ext/libsass/configure.ac +0 -138
- data/ext/libsass/contrib/libsass.spec +0 -66
- data/ext/libsass/docs/README.md +0 -20
- data/ext/libsass/docs/api-context-example.md +0 -45
- data/ext/libsass/docs/api-context-internal.md +0 -163
- data/ext/libsass/docs/api-context.md +0 -295
- data/ext/libsass/docs/api-doc.md +0 -215
- data/ext/libsass/docs/api-function-example.md +0 -67
- data/ext/libsass/docs/api-function-internal.md +0 -8
- data/ext/libsass/docs/api-function.md +0 -74
- data/ext/libsass/docs/api-importer-example.md +0 -112
- data/ext/libsass/docs/api-importer-internal.md +0 -20
- data/ext/libsass/docs/api-importer.md +0 -86
- data/ext/libsass/docs/api-value-example.md +0 -55
- data/ext/libsass/docs/api-value-internal.md +0 -76
- data/ext/libsass/docs/api-value.md +0 -154
- data/ext/libsass/docs/build-on-darwin.md +0 -27
- data/ext/libsass/docs/build-on-gentoo.md +0 -55
- data/ext/libsass/docs/build-on-windows.md +0 -139
- data/ext/libsass/docs/build-shared-library.md +0 -35
- data/ext/libsass/docs/build-with-autotools.md +0 -78
- data/ext/libsass/docs/build-with-makefiles.md +0 -68
- data/ext/libsass/docs/build-with-mingw.md +0 -107
- data/ext/libsass/docs/build-with-visual-studio.md +0 -90
- data/ext/libsass/docs/build.md +0 -97
- data/ext/libsass/docs/compatibility-plan.md +0 -48
- data/ext/libsass/docs/contributing.md +0 -17
- data/ext/libsass/docs/custom-functions-internal.md +0 -122
- data/ext/libsass/docs/dev-ast-memory.md +0 -223
- data/ext/libsass/docs/implementations.md +0 -56
- data/ext/libsass/docs/plugins.md +0 -47
- data/ext/libsass/docs/setup-environment.md +0 -68
- data/ext/libsass/docs/source-map-internals.md +0 -51
- data/ext/libsass/docs/trace.md +0 -26
- data/ext/libsass/docs/triage.md +0 -17
- data/ext/libsass/docs/unicode.md +0 -39
- data/ext/libsass/extconf.rb +0 -6
- data/ext/libsass/include/sass/version.h.in +0 -12
- data/ext/libsass/m4/.gitkeep +0 -0
- data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
- data/ext/libsass/res/resource.rc +0 -35
- data/ext/libsass/script/bootstrap +0 -13
- data/ext/libsass/script/branding +0 -10
- data/ext/libsass/script/ci-build-libsass +0 -134
- data/ext/libsass/script/ci-build-plugin +0 -62
- data/ext/libsass/script/ci-install-compiler +0 -6
- data/ext/libsass/script/ci-install-deps +0 -20
- data/ext/libsass/script/ci-report-coverage +0 -42
- data/ext/libsass/script/spec +0 -5
- data/ext/libsass/script/tap-driver +0 -652
- data/ext/libsass/script/tap-runner +0 -1
- data/ext/libsass/script/test-leaks.pl +0 -103
- data/ext/libsass/src/GNUmakefile.am +0 -54
- data/ext/libsass/src/extend.cpp +0 -2130
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/functions.cpp +0 -2234
- data/ext/libsass/src/functions.hpp +0 -198
- data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
- data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
- data/ext/libsass/src/node.cpp +0 -319
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -149
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -55
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/ext/libsass/src/support/libsass.pc.in +0 -11
- data/ext/libsass/src/to_c.hpp +0 -39
- data/ext/libsass/test/test_node.cpp +0 -94
- data/ext/libsass/test/test_paths.cpp +0 -28
- data/ext/libsass/test/test_selector_difference.cpp +0 -25
- data/ext/libsass/test/test_specificity.cpp +0 -25
- data/ext/libsass/test/test_subset_map.cpp +0 -472
- data/ext/libsass/test/test_superselector.cpp +0 -69
- data/ext/libsass/test/test_unification.cpp +0 -31
- data/ext/libsass/version.sh +0 -10
- data/ext/libsass/win/libsass.sln +0 -39
- data/ext/libsass/win/libsass.sln.DotSettings +0 -9
- data/ext/libsass/win/libsass.targets +0 -118
- data/ext/libsass/win/libsass.vcxproj +0 -188
- data/ext/libsass/win/libsass.vcxproj.filters +0 -357
- data/lib/sassc/native/lib_c.rb +0 -21
- data/lib/tasks/libsass.rb +0 -33
data/ext/libsass/src/file.cpp
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
1
3
|
#include "sass.hpp"
|
|
4
|
+
|
|
2
5
|
#ifdef _WIN32
|
|
3
6
|
# ifdef __MINGW32__
|
|
4
7
|
# ifndef off64_t
|
|
@@ -10,9 +13,7 @@
|
|
|
10
13
|
#else
|
|
11
14
|
# include <unistd.h>
|
|
12
15
|
#endif
|
|
13
|
-
#include <
|
|
14
|
-
#include <fstream>
|
|
15
|
-
#include <cctype>
|
|
16
|
+
#include <cstdio>
|
|
16
17
|
#include <vector>
|
|
17
18
|
#include <algorithm>
|
|
18
19
|
#include <sys/stat.h>
|
|
@@ -21,6 +22,9 @@
|
|
|
21
22
|
#include "prelexer.hpp"
|
|
22
23
|
#include "utf8_string.hpp"
|
|
23
24
|
#include "sass_functions.hpp"
|
|
25
|
+
#include "error_handling.hpp"
|
|
26
|
+
#include "util.hpp"
|
|
27
|
+
#include "util_string.hpp"
|
|
24
28
|
#include "sass2scss.h"
|
|
25
29
|
|
|
26
30
|
#ifdef _WIN32
|
|
@@ -28,16 +32,16 @@
|
|
|
28
32
|
|
|
29
33
|
# ifdef _MSC_VER
|
|
30
34
|
# include <codecvt>
|
|
31
|
-
inline static
|
|
35
|
+
inline static Sass::sass::string wstring_to_string(const std::wstring& wstr)
|
|
32
36
|
{
|
|
33
37
|
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wchar_converter;
|
|
34
38
|
return wchar_converter.to_bytes(wstr);
|
|
35
39
|
}
|
|
36
40
|
# else // mingw(/gcc) does not support C++11's codecvt yet.
|
|
37
|
-
inline static
|
|
41
|
+
inline static Sass::sass::string wstring_to_string(const std::wstring &wstr)
|
|
38
42
|
{
|
|
39
43
|
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
|
|
40
|
-
|
|
44
|
+
Sass::sass::string strTo(size_needed, 0);
|
|
41
45
|
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
|
|
42
46
|
return strTo;
|
|
43
47
|
}
|
|
@@ -50,7 +54,7 @@ namespace Sass {
|
|
|
50
54
|
// return the current directory
|
|
51
55
|
// always with forward slashes
|
|
52
56
|
// always with trailing slash
|
|
53
|
-
|
|
57
|
+
sass::string get_cwd()
|
|
54
58
|
{
|
|
55
59
|
const size_t wd_len = 4096;
|
|
56
60
|
#ifndef _WIN32
|
|
@@ -59,12 +63,12 @@ namespace Sass {
|
|
|
59
63
|
// we should check error for more detailed info (e.g. ENOENT)
|
|
60
64
|
// http://man7.org/linux/man-pages/man2/getcwd.2.html#ERRORS
|
|
61
65
|
if (pwd == NULL) throw Exception::OperationError("cwd gone missing");
|
|
62
|
-
|
|
66
|
+
sass::string cwd = pwd;
|
|
63
67
|
#else
|
|
64
68
|
wchar_t wd[wd_len];
|
|
65
69
|
wchar_t* pwd = _wgetcwd(wd, wd_len);
|
|
66
70
|
if (pwd == NULL) throw Exception::OperationError("cwd gone missing");
|
|
67
|
-
|
|
71
|
+
sass::string cwd = wstring_to_string(pwd);
|
|
68
72
|
//convert backslashes to forward slashes
|
|
69
73
|
replace(cwd.begin(), cwd.end(), '\\', '/');
|
|
70
74
|
#endif
|
|
@@ -73,13 +77,16 @@ namespace Sass {
|
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
// test if path exists and is a file
|
|
76
|
-
bool file_exists(const
|
|
80
|
+
bool file_exists(const sass::string& path)
|
|
77
81
|
{
|
|
78
82
|
#ifdef _WIN32
|
|
79
83
|
wchar_t resolved[32768];
|
|
80
84
|
// windows unicode filepaths are encoded in utf16
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
sass::string abspath(join_paths(get_cwd(), path));
|
|
86
|
+
if (!(abspath[0] == '/' && abspath[1] == '/')) {
|
|
87
|
+
abspath = "//?/" + abspath;
|
|
88
|
+
}
|
|
89
|
+
std::wstring wpath(UTF_8::convert_to_utf16(abspath));
|
|
83
90
|
std::replace(wpath.begin(), wpath.end(), '/', '\\');
|
|
84
91
|
DWORD rv = GetFullPathNameW(wpath.c_str(), 32767, resolved, NULL);
|
|
85
92
|
if (rv > 32767) throw Exception::OperationError("Path is too long");
|
|
@@ -96,35 +103,35 @@ namespace Sass {
|
|
|
96
103
|
|
|
97
104
|
// return if given path is absolute
|
|
98
105
|
// works with *nix and windows paths
|
|
99
|
-
bool is_absolute_path(const
|
|
106
|
+
bool is_absolute_path(const sass::string& path)
|
|
100
107
|
{
|
|
101
108
|
#ifdef _WIN32
|
|
102
|
-
if (path.length() >= 2 &&
|
|
109
|
+
if (path.length() >= 2 && Util::ascii_isalpha(path[0]) && path[1] == ':') return true;
|
|
103
110
|
#endif
|
|
104
111
|
size_t i = 0;
|
|
105
112
|
// check if we have a protocol
|
|
106
|
-
if (path[i] &&
|
|
113
|
+
if (path[i] && Util::ascii_isalpha(static_cast<unsigned char>(path[i]))) {
|
|
107
114
|
// skip over all alphanumeric characters
|
|
108
|
-
while (path[i] &&
|
|
115
|
+
while (path[i] && Util::ascii_isalnum(static_cast<unsigned char>(path[i]))) ++i;
|
|
109
116
|
i = i && path[i] == ':' ? i + 1 : 0;
|
|
110
117
|
}
|
|
111
118
|
return path[i] == '/';
|
|
112
119
|
}
|
|
113
120
|
|
|
114
|
-
// helper function to find the last directory
|
|
115
|
-
inline size_t find_last_folder_separator(const
|
|
121
|
+
// helper function to find the last directory separator
|
|
122
|
+
inline size_t find_last_folder_separator(const sass::string& path, size_t limit = sass::string::npos)
|
|
116
123
|
{
|
|
117
124
|
size_t pos;
|
|
118
125
|
size_t pos_p = path.find_last_of('/', limit);
|
|
119
126
|
#ifdef _WIN32
|
|
120
127
|
size_t pos_w = path.find_last_of('\\', limit);
|
|
121
128
|
#else
|
|
122
|
-
size_t pos_w =
|
|
129
|
+
size_t pos_w = sass::string::npos;
|
|
123
130
|
#endif
|
|
124
|
-
if (pos_p !=
|
|
131
|
+
if (pos_p != sass::string::npos && pos_w != sass::string::npos) {
|
|
125
132
|
pos = std::max(pos_p, pos_w);
|
|
126
133
|
}
|
|
127
|
-
else if (pos_p !=
|
|
134
|
+
else if (pos_p != sass::string::npos) {
|
|
128
135
|
pos = pos_p;
|
|
129
136
|
}
|
|
130
137
|
else {
|
|
@@ -134,24 +141,24 @@ namespace Sass {
|
|
|
134
141
|
}
|
|
135
142
|
|
|
136
143
|
// return only the directory part of path
|
|
137
|
-
|
|
144
|
+
sass::string dir_name(const sass::string& path)
|
|
138
145
|
{
|
|
139
146
|
size_t pos = find_last_folder_separator(path);
|
|
140
|
-
if (pos ==
|
|
147
|
+
if (pos == sass::string::npos) return "";
|
|
141
148
|
else return path.substr(0, pos+1);
|
|
142
149
|
}
|
|
143
150
|
|
|
144
151
|
// return only the filename part of path
|
|
145
|
-
|
|
152
|
+
sass::string base_name(const sass::string& path)
|
|
146
153
|
{
|
|
147
154
|
size_t pos = find_last_folder_separator(path);
|
|
148
|
-
if (pos ==
|
|
155
|
+
if (pos == sass::string::npos) return path;
|
|
149
156
|
else return path.substr(pos+1);
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
// do a logical clean up of the path
|
|
153
160
|
// no physical check on the filesystem
|
|
154
|
-
|
|
161
|
+
sass::string make_canonical_path (sass::string path)
|
|
155
162
|
{
|
|
156
163
|
|
|
157
164
|
// declarations
|
|
@@ -163,18 +170,18 @@ namespace Sass {
|
|
|
163
170
|
#endif
|
|
164
171
|
|
|
165
172
|
pos = 0; // remove all self references inside the path string
|
|
166
|
-
while((pos = path.find("/./", pos)) !=
|
|
173
|
+
while((pos = path.find("/./", pos)) != sass::string::npos) path.erase(pos, 2);
|
|
167
174
|
|
|
168
175
|
// remove all leading and trailing self references
|
|
169
|
-
while(path.
|
|
170
|
-
while((pos = path.length()) > 1 && path
|
|
176
|
+
while(path.size() >= 2 && path[0] == '.' && path[1] == '/') path.erase(0, 2);
|
|
177
|
+
while((pos = path.length()) > 1 && path[pos - 2] == '/' && path[pos - 1] == '.') path.erase(pos - 2);
|
|
171
178
|
|
|
172
179
|
|
|
173
180
|
size_t proto = 0;
|
|
174
181
|
// check if we have a protocol
|
|
175
|
-
if (path[proto] &&
|
|
182
|
+
if (path[proto] && Util::ascii_isalpha(static_cast<unsigned char>(path[proto]))) {
|
|
176
183
|
// skip over all alphanumeric characters
|
|
177
|
-
while (path[proto] &&
|
|
184
|
+
while (path[proto] && Util::ascii_isalnum(static_cast<unsigned char>(path[proto++]))) {}
|
|
178
185
|
// then skip over the mandatory colon
|
|
179
186
|
if (proto && path[proto] == ':') ++ proto;
|
|
180
187
|
}
|
|
@@ -183,7 +190,7 @@ namespace Sass {
|
|
|
183
190
|
while (path[proto++] == '/') {}
|
|
184
191
|
|
|
185
192
|
pos = proto; // collapse multiple delimiters into a single one
|
|
186
|
-
while((pos = path.find("//", pos)) !=
|
|
193
|
+
while((pos = path.find("//", pos)) != sass::string::npos) path.erase(pos, 1);
|
|
187
194
|
|
|
188
195
|
return path;
|
|
189
196
|
|
|
@@ -191,7 +198,7 @@ namespace Sass {
|
|
|
191
198
|
|
|
192
199
|
// join two path segments cleanly together
|
|
193
200
|
// but only if right side is not absolute yet
|
|
194
|
-
|
|
201
|
+
sass::string join_paths(sass::string l, sass::string r)
|
|
195
202
|
{
|
|
196
203
|
|
|
197
204
|
#ifdef _WIN32
|
|
@@ -218,16 +225,16 @@ namespace Sass {
|
|
|
218
225
|
bool is_slash = pos + 2 == L && (l[pos+1] == '/' || l[pos+1] == '\\');
|
|
219
226
|
bool is_self = pos + 3 == L && (l[pos+1] == '.');
|
|
220
227
|
if (!is_self && !is_slash) r = r.substr(3);
|
|
221
|
-
else if (pos ==
|
|
222
|
-
l = l.substr(0, pos ==
|
|
228
|
+
else if (pos == sass::string::npos) break;
|
|
229
|
+
l = l.substr(0, pos == sass::string::npos ? pos : pos + 1);
|
|
223
230
|
}
|
|
224
231
|
|
|
225
232
|
return l + r;
|
|
226
233
|
}
|
|
227
234
|
|
|
228
|
-
|
|
235
|
+
sass::string path_for_console(const sass::string& rel_path, const sass::string& abs_path, const sass::string& orig_path)
|
|
229
236
|
{
|
|
230
|
-
// magic
|
|
237
|
+
// magic algorithm goes here!!
|
|
231
238
|
|
|
232
239
|
// if the file is outside this directory show the absolute path
|
|
233
240
|
if (rel_path.substr(0, 3) == "../") {
|
|
@@ -238,24 +245,32 @@ namespace Sass {
|
|
|
238
245
|
}
|
|
239
246
|
|
|
240
247
|
// create an absolute path by resolving relative paths with cwd
|
|
241
|
-
|
|
248
|
+
sass::string rel2abs(const sass::string& path, const sass::string& base, const sass::string& cwd)
|
|
242
249
|
{
|
|
243
|
-
|
|
250
|
+
sass::string rv = make_canonical_path(join_paths(join_paths(cwd + "/", base + "/"), path));
|
|
251
|
+
#ifdef _WIN32
|
|
252
|
+
// On windows we may get an absolute path without directory
|
|
253
|
+
// In that case we should prepend the directory from the root
|
|
254
|
+
if (rv[0] == '/' && rv[1] != '/') {
|
|
255
|
+
rv.insert(0, cwd, 0, 2);
|
|
256
|
+
}
|
|
257
|
+
#endif
|
|
258
|
+
return rv;
|
|
244
259
|
}
|
|
245
260
|
|
|
246
261
|
// create a path that is relative to the given base directory
|
|
247
262
|
// path and base will first be resolved against cwd to make them absolute
|
|
248
|
-
|
|
263
|
+
sass::string abs2rel(const sass::string& path, const sass::string& base, const sass::string& cwd)
|
|
249
264
|
{
|
|
250
265
|
|
|
251
|
-
|
|
252
|
-
|
|
266
|
+
sass::string abs_path = rel2abs(path, cwd);
|
|
267
|
+
sass::string abs_base = rel2abs(base, cwd);
|
|
253
268
|
|
|
254
269
|
size_t proto = 0;
|
|
255
270
|
// check if we have a protocol
|
|
256
|
-
if (path[proto] &&
|
|
271
|
+
if (path[proto] && Util::ascii_isalpha(static_cast<unsigned char>(path[proto]))) {
|
|
257
272
|
// skip over all alphanumeric characters
|
|
258
|
-
while (path[proto] &&
|
|
273
|
+
while (path[proto] && Util::ascii_isalnum(static_cast<unsigned char>(path[proto++]))) {}
|
|
259
274
|
// then skip over the mandatory colon
|
|
260
275
|
if (proto && path[proto] == ':') ++ proto;
|
|
261
276
|
}
|
|
@@ -270,8 +285,8 @@ namespace Sass {
|
|
|
270
285
|
if (abs_base[0] != abs_path[0]) return abs_path;
|
|
271
286
|
#endif
|
|
272
287
|
|
|
273
|
-
|
|
274
|
-
|
|
288
|
+
sass::string stripped_uri = "";
|
|
289
|
+
sass::string stripped_base = "";
|
|
275
290
|
|
|
276
291
|
size_t index = 0;
|
|
277
292
|
size_t minSize = std::min(abs_path.size(), abs_base.size());
|
|
@@ -281,7 +296,8 @@ namespace Sass {
|
|
|
281
296
|
#else
|
|
282
297
|
// compare the charactes in a case insensitive manner
|
|
283
298
|
// windows fs is only case insensitive in ascii ranges
|
|
284
|
-
if (
|
|
299
|
+
if (Util::ascii_tolower(static_cast<unsigned char>(abs_path[i])) !=
|
|
300
|
+
Util::ascii_tolower(static_cast<unsigned char>(abs_base[i]))) break;
|
|
285
301
|
#endif
|
|
286
302
|
if (abs_path[i] == '/') index = i + 1;
|
|
287
303
|
}
|
|
@@ -309,7 +325,7 @@ namespace Sass {
|
|
|
309
325
|
}
|
|
310
326
|
}
|
|
311
327
|
|
|
312
|
-
|
|
328
|
+
sass::string result = "";
|
|
313
329
|
for (size_t i = 0; i < directories; ++i) {
|
|
314
330
|
result += "../";
|
|
315
331
|
}
|
|
@@ -323,16 +339,18 @@ namespace Sass {
|
|
|
323
339
|
// (2) underscore + given
|
|
324
340
|
// (3) underscore + given + extension
|
|
325
341
|
// (4) given + extension
|
|
326
|
-
|
|
342
|
+
// (5) given + _index.scss
|
|
343
|
+
// (6) given + _index.sass
|
|
344
|
+
sass::vector<Include> resolve_includes(const sass::string& root, const sass::string& file, const sass::vector<sass::string>& exts)
|
|
327
345
|
{
|
|
328
|
-
|
|
346
|
+
sass::string filename = join_paths(root, file);
|
|
329
347
|
// split the filename
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
348
|
+
sass::string base(dir_name(file));
|
|
349
|
+
sass::string name(base_name(file));
|
|
350
|
+
sass::vector<Include> includes;
|
|
333
351
|
// create full path (maybe relative)
|
|
334
|
-
|
|
335
|
-
|
|
352
|
+
sass::string rel_path(join_paths(base, name));
|
|
353
|
+
sass::string abs_path(join_paths(root, rel_path));
|
|
336
354
|
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
|
337
355
|
// next test variation with underscore
|
|
338
356
|
rel_path = join_paths(base, "_" + name);
|
|
@@ -350,28 +368,47 @@ namespace Sass {
|
|
|
350
368
|
abs_path = join_paths(root, rel_path);
|
|
351
369
|
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
|
352
370
|
}
|
|
371
|
+
// index files
|
|
372
|
+
if (includes.size() == 0) {
|
|
373
|
+
// ignore directories that look like @import'able filename
|
|
374
|
+
for(auto ext : exts) {
|
|
375
|
+
if (ends_with(name, ext)) return includes;
|
|
376
|
+
}
|
|
377
|
+
// next test underscore index exts
|
|
378
|
+
for(auto ext : exts) {
|
|
379
|
+
rel_path = join_paths(base, join_paths(name, "_index" + ext));
|
|
380
|
+
abs_path = join_paths(root, rel_path);
|
|
381
|
+
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
|
382
|
+
}
|
|
383
|
+
// next test plain index exts
|
|
384
|
+
for(auto ext : exts) {
|
|
385
|
+
rel_path = join_paths(base, join_paths(name, "index" + ext));
|
|
386
|
+
abs_path = join_paths(root, rel_path);
|
|
387
|
+
if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });
|
|
388
|
+
}
|
|
389
|
+
}
|
|
353
390
|
// nothing found
|
|
354
391
|
return includes;
|
|
355
392
|
}
|
|
356
393
|
|
|
357
|
-
|
|
394
|
+
sass::vector<sass::string> find_files(const sass::string& file, const sass::vector<sass::string> paths)
|
|
358
395
|
{
|
|
359
|
-
|
|
360
|
-
for (
|
|
361
|
-
|
|
396
|
+
sass::vector<sass::string> includes;
|
|
397
|
+
for (sass::string path : paths) {
|
|
398
|
+
sass::string abs_path(join_paths(path, file));
|
|
362
399
|
if (file_exists(abs_path)) includes.push_back(abs_path);
|
|
363
400
|
}
|
|
364
401
|
return includes;
|
|
365
402
|
}
|
|
366
403
|
|
|
367
|
-
|
|
404
|
+
sass::vector<sass::string> find_files(const sass::string& file, struct Sass_Compiler* compiler)
|
|
368
405
|
{
|
|
369
406
|
// get the last import entry to get current base directory
|
|
370
407
|
// struct Sass_Options* options = sass_compiler_get_options(compiler);
|
|
371
408
|
Sass_Import_Entry import = sass_compiler_get_last_import(compiler);
|
|
372
|
-
const
|
|
409
|
+
const sass::vector<sass::string>& incs = compiler->cpp_ctx->include_paths;
|
|
373
410
|
// create the vector with paths to lookup
|
|
374
|
-
|
|
411
|
+
sass::vector<sass::string> paths(1 + incs.size());
|
|
375
412
|
paths.push_back(dir_name(import->abs_path));
|
|
376
413
|
paths.insert(paths.end(), incs.begin(), incs.end());
|
|
377
414
|
// dispatch to find files in paths
|
|
@@ -380,7 +417,7 @@ namespace Sass {
|
|
|
380
417
|
|
|
381
418
|
// helper function to search one file in all include paths
|
|
382
419
|
// this is normally not used internally by libsass (C-API sugar)
|
|
383
|
-
|
|
420
|
+
sass::string find_file(const sass::string& file, const sass::vector<sass::string> paths)
|
|
384
421
|
{
|
|
385
422
|
if (file.empty()) return file;
|
|
386
423
|
auto res = find_files(file, paths);
|
|
@@ -388,30 +425,33 @@ namespace Sass {
|
|
|
388
425
|
}
|
|
389
426
|
|
|
390
427
|
// helper function to resolve a filename
|
|
391
|
-
|
|
428
|
+
sass::string find_include(const sass::string& file, const sass::vector<sass::string> paths)
|
|
392
429
|
{
|
|
393
430
|
// search in every include path for a match
|
|
394
431
|
for (size_t i = 0, S = paths.size(); i < S; ++i)
|
|
395
432
|
{
|
|
396
|
-
|
|
433
|
+
sass::vector<Include> resolved(resolve_includes(paths[i], file));
|
|
397
434
|
if (resolved.size()) return resolved[0].abs_path;
|
|
398
435
|
}
|
|
399
436
|
// nothing found
|
|
400
|
-
return
|
|
437
|
+
return sass::string("");
|
|
401
438
|
}
|
|
402
439
|
|
|
403
440
|
// try to load the given filename
|
|
404
441
|
// returned memory must be freed
|
|
405
442
|
// will auto convert .sass files
|
|
406
|
-
char* read_file(const
|
|
443
|
+
char* read_file(const sass::string& path)
|
|
407
444
|
{
|
|
408
445
|
#ifdef _WIN32
|
|
409
446
|
BYTE* pBuffer;
|
|
410
447
|
DWORD dwBytes;
|
|
411
448
|
wchar_t resolved[32768];
|
|
412
449
|
// windows unicode filepaths are encoded in utf16
|
|
413
|
-
|
|
414
|
-
|
|
450
|
+
sass::string abspath(join_paths(get_cwd(), path));
|
|
451
|
+
if (!(abspath[0] == '/' && abspath[1] == '/')) {
|
|
452
|
+
abspath = "//?/" + abspath;
|
|
453
|
+
}
|
|
454
|
+
std::wstring wpath(UTF_8::convert_to_utf16(abspath));
|
|
415
455
|
std::replace(wpath.begin(), wpath.end(), '/', '\\');
|
|
416
456
|
DWORD rv = GetFullPathNameW(wpath.c_str(), 32767, resolved, NULL);
|
|
417
457
|
if (rv > 32767) throw Exception::OperationError("Path is too long");
|
|
@@ -430,28 +470,34 @@ namespace Sass {
|
|
|
430
470
|
// just convert from unsigned char*
|
|
431
471
|
char* contents = (char*) pBuffer;
|
|
432
472
|
#else
|
|
473
|
+
// Read the file using `<cstdio>` instead of `<fstream>` for better portability.
|
|
474
|
+
// The `<fstream>` header initializes `<locale>` and this buggy in GCC4/5 with static linking.
|
|
475
|
+
// See:
|
|
476
|
+
// https://www.spinics.net/lists/gcchelp/msg46851.html
|
|
477
|
+
// https://github.com/sass/sassc-ruby/issues/128
|
|
433
478
|
struct stat st;
|
|
434
479
|
if (stat(path.c_str(), &st) == -1 || S_ISDIR(st.st_mode)) return 0;
|
|
435
|
-
std::
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
contents
|
|
446
|
-
|
|
480
|
+
FILE* fd = std::fopen(path.c_str(), "rb");
|
|
481
|
+
if (fd == nullptr) return nullptr;
|
|
482
|
+
const std::size_t size = st.st_size;
|
|
483
|
+
char* contents = static_cast<char*>(malloc(st.st_size + 2 * sizeof(char)));
|
|
484
|
+
if (std::fread(static_cast<void*>(contents), 1, size, fd) != size) {
|
|
485
|
+
free(contents);
|
|
486
|
+
std::fclose(fd);
|
|
487
|
+
return nullptr;
|
|
488
|
+
}
|
|
489
|
+
if (std::fclose(fd) != 0) {
|
|
490
|
+
free(contents);
|
|
491
|
+
return nullptr;
|
|
447
492
|
}
|
|
493
|
+
contents[size] = '\0';
|
|
494
|
+
contents[size + 1] = '\0';
|
|
448
495
|
#endif
|
|
449
|
-
|
|
496
|
+
sass::string extension;
|
|
450
497
|
if (path.length() > 5) {
|
|
451
498
|
extension = path.substr(path.length() - 5, 5);
|
|
452
499
|
}
|
|
453
|
-
|
|
454
|
-
extension[i] = tolower(extension[i]);
|
|
500
|
+
Util::ascii_str_tolower(&extension);
|
|
455
501
|
if (extension == ".sass" && contents != 0) {
|
|
456
502
|
char * converted = sass2scss(contents, SASS2SCSS_PRETTIFY_1 | SASS2SCSS_KEEP_COMMENT);
|
|
457
503
|
free(contents); // free the indented contents
|
|
@@ -462,21 +508,21 @@ namespace Sass {
|
|
|
462
508
|
}
|
|
463
509
|
|
|
464
510
|
// split a path string delimited by semicolons or colons (OS dependent)
|
|
465
|
-
|
|
511
|
+
sass::vector<sass::string> split_path_list(const char* str)
|
|
466
512
|
{
|
|
467
|
-
|
|
513
|
+
sass::vector<sass::string> paths;
|
|
468
514
|
if (str == NULL) return paths;
|
|
469
515
|
// find delimiter via prelexer (return zero at end)
|
|
470
516
|
const char* end = Prelexer::find_first<PATH_SEP>(str);
|
|
471
517
|
// search until null delimiter
|
|
472
518
|
while (end) {
|
|
473
519
|
// add path from current position to delimiter
|
|
474
|
-
paths.push_back(
|
|
520
|
+
paths.push_back(sass::string(str, end - str));
|
|
475
521
|
str = end + 1; // skip delimiter
|
|
476
522
|
end = Prelexer::find_first<PATH_SEP>(str);
|
|
477
523
|
}
|
|
478
524
|
// add path from current position to end
|
|
479
|
-
paths.push_back(
|
|
525
|
+
paths.push_back(sass::string(str));
|
|
480
526
|
// return back
|
|
481
527
|
return paths;
|
|
482
528
|
}
|