modif comtabilite

This commit is contained in:
2019-01-16 16:23:31 +01:00
parent 6b741a9666
commit 9312edc3ae
1844 changed files with 158848 additions and 55874 deletions
Binary file not shown.
+15 -4
View File
@@ -227,9 +227,16 @@ int GetResult(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = fal
return status;
}
void PerformCall(sass_context_wrapper* ctx_w, Nan::Callback* callback, int argc, v8::Local<v8::Value> argv[]) {
if (ctx_w->is_sync) {
Nan::Call(*callback, argc, argv);
} else {
callback->Call(argc, argv, ctx_w->async_resource);
}
}
void MakeCallback(uv_work_t* req) {
Nan::HandleScope scope;
Nan::AsyncResource async("sass:MakeCallback");
Nan::TryCatch try_catch;
sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
@@ -246,7 +253,7 @@ void MakeCallback(uv_work_t* req) {
if (status == 0 && ctx_w->success_callback) {
// if no error, do callback(null, result)
ctx_w->success_callback->Call(0, 0, &async);
PerformCall(ctx_w, ctx_w->success_callback, 0, 0);
}
else if (ctx_w->error_callback) {
// if error, do callback(error)
@@ -254,7 +261,7 @@ void MakeCallback(uv_work_t* req) {
v8::Local<v8::Value> argv[] = {
Nan::New<v8::String>(err).ToLocalChecked()
};
ctx_w->error_callback->Call(1, argv, &async);
PerformCall(ctx_w, ctx_w->error_callback, 1, argv);
}
if (try_catch.HasCaught()) {
Nan::FatalException(try_catch);
@@ -270,6 +277,8 @@ NAN_METHOD(render) {
struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
sass_context_wrapper* ctx_w = sass_make_context_wrapper();
ctx_w->async_resource = new Nan::AsyncResource("node-sass:sass_context_wrapper:render");
if (ExtractOptions(options, dctx, ctx_w, false, false) >= 0) {
int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
@@ -293,7 +302,7 @@ NAN_METHOD(render_sync) {
}
sass_free_context_wrapper(ctx_w);
info.GetReturnValue().Set(result == 0);
}
@@ -304,6 +313,8 @@ NAN_METHOD(render_file) {
struct Sass_File_Context* fctx = sass_make_file_context(input_path);
sass_context_wrapper* ctx_w = sass_make_context_wrapper();
ctx_w->async_resource = new Nan::AsyncResource("node-sass:sass_context_wrapper:render_file");
if (ExtractOptions(options, fctx, ctx_w, true, false) >= 0) {
int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
+5 -3
View File
@@ -40,6 +40,7 @@ class CallbackBridge {
virtual std::vector<v8::Local<v8::Value>> pre_process_args(std::vector<L>) const =0;
Nan::Callback* callback;
Nan::AsyncResource* async_resource;
bool is_sync;
uv_mutex_t cv_mutex;
@@ -66,6 +67,7 @@ CallbackBridge<T, L>::CallbackBridge(v8::Local<v8::Function> callback, bool is_s
this->async = new uv_async_t;
this->async->data = (void*) this;
uv_async_init(uv_default_loop(), this->async, (uv_async_cb) dispatched_async_uv_callback);
this->async_resource = new Nan::AsyncResource("node-sass:CallbackBridge");
}
v8::Local<v8::Function> func = CallbackBridge<T, L>::get_wrapper_constructor().ToLocalChecked();
@@ -82,6 +84,7 @@ CallbackBridge<T, L>::~CallbackBridge() {
if (!is_sync) {
uv_close((uv_handle_t*)this->async, &async_gone);
delete this->async_resource;
}
}
@@ -107,7 +110,7 @@ T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
argv_v8.push_back(Nan::New(wrapper));
return this->post_process_return_value(
Nan::Call(*callback, argv_v8.size(), &argv_v8[0]).ToLocalChecked()
Nan::Call(*this->callback, argv_v8.size(), &argv_v8[0]).ToLocalChecked()
);
} else {
/*
@@ -151,7 +154,6 @@ void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
* post_process_args().
*/
Nan::HandleScope scope;
Nan::AsyncResource async("sass:CallbackBridge");
Nan::TryCatch try_catch;
std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args(bridge->argv);
@@ -160,7 +162,7 @@ void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
}
argv_v8.push_back(Nan::New(bridge->wrapper));
bridge->callback->Call(argv_v8.size(), &argv_v8[0], &async);
bridge->callback->Call(argv_v8.size(), &argv_v8[0], bridge->async_resource);
if (try_catch.HasCaught()) {
Nan::FatalException(try_catch);
+21 -35
View File
@@ -25,63 +25,49 @@ else
AM_CXXFLAGS += -std=c++0x
endif
TEST_EXTENSIONS = .rb
if ENABLE_TESTS
noinst_PROGRAMS = tester
SASS_SASSC_PATH ?= $(top_srcdir)/sassc
SASS_SPEC_PATH ?= $(top_srcdir)/sass-spec
noinst_PROGRAMS = tester
tester_LDADD = src/libsass.la
tester_SOURCES = $(SASS_SASSC_PATH)/sassc.c
tester_VERSION ?= `cd "$(SASS_SASSC_PATH)" && ./version.sh`
tester_CFLAGS = $(AM_CFLAGS) -DSASSC_VERSION="\"$(tester_VERSION)\""
tester_CXXFLAGS = $(AM_CXXFLAGS) -DSASSC_VERSION="\"$(tester_VERSION)\""
tester_LDFLAGS = $(AM_LDFLAGS)
nodist_tester_SOURCES = $(SASS_SASSC_PATH)/sassc.c
SASS_SASSC_VERSION ?= `cd "$(SASS_SASSC_PATH)" && ./version.sh`
tester_CFLAGS = $(AM_CFLAGS) -DSASSC_VERSION="\"$(SASS_SASSC_VERSION)\""
tester_CXXFLAGS = $(AM_CXXFLAGS) -DSASSC_VERSION="\"$(SASS_SASSC_VERSION)\""
if ENABLE_COVERAGE
nodist_EXTRA_tester_SOURCES = non-existent-file-to-force-CXX-linking.cxx
endif
SASS_SASSC_PATH ?= $(top_srcdir)/sassc
SASS_SPEC_PATH ?= $(top_srcdir)/sass-spec
TESTS = \
$(SASS_SPEC_PATH)/spec/basic \
$(SASS_SPEC_PATH)/spec/css \
$(SASS_SPEC_PATH)/spec/extend-tests \
$(SASS_SPEC_PATH)/spec/extends \
$(SASS_SPEC_PATH)/spec/libsass \
$(SASS_SPEC_PATH)/spec/libsass-closed-issues \
$(SASS_SPEC_PATH)/spec/maps \
$(SASS_SPEC_PATH)/spec/misc \
$(SASS_SPEC_PATH)/spec/regressions \
$(SASS_SPEC_PATH)/spec/scss \
$(SASS_SPEC_PATH)/spec/scss-tests \
$(SASS_SPEC_PATH)/spec/types
TESTS = $(SASS_SPEC_PATH)/sass-spec.rb
RB_LOG_COMPILER = ./script/tap-runner
AM_RB_LOG_FLAGS = $(RUBY)
SASS_TEST_FLAGS = -V 3.5 --impl libsass
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) ./script/tap-driver
AM_LOG_FLAGS = -c ./tester $(LOG_FLAGS)
if USE_TAP
AM_LOG_FLAGS += -t
SASS_TEST_FLAGS += -t | tapout
LOG_COMPILER = ./script/tap-runner $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb
else
LOG_COMPILER = $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb
endif
SASS_TEST_FLAGS += -r $(SASS_SPEC_PATH)
SASS_TEST_FLAGS += -c $(top_srcdir)/tester$(EXEEXT)
AM_TESTS_ENVIRONMENT = TEST_FLAGS='$(SASS_TEST_FLAGS)'
SASS_TESTER = $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb
SASS_TESTER += -c $(top_srcdir)/tester$(EXEEXT)
test:
$(SASS_TESTER) $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
$(SASS_TESTER) $(SASS_TEST_FLAGS)
test_build:
$(SASS_TESTER) $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
$(SASS_TESTER) $(SASS_TEST_FLAGS)
test_full:
$(SASS_TESTER) --run-todo $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
$(SASS_TESTER) --run-todo $(SASS_TEST_FLAGS)
test_probe:
$(SASS_TESTER) --probe-todo $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
$(SASS_TESTER) --probe-todo $(SASS_TEST_FLAGS)
.PHONY: test test_build test_full test_probe
endif
+8 -12
View File
@@ -9,6 +9,7 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([src/config.h])
AC_CONFIG_FILES([include/sass/version.h])
AC_CONFIG_AUX_DIR([script])
# These are flags passed to automake
# Though they look like gcc flags!
AM_INIT_AUTOMAKE([foreign parallel-tests -Wall])
@@ -93,21 +94,16 @@ the --with-sass-spec-dir=<dir> argument.
;;
esac
AC_SUBST(SASS_SPEC_PATH)
# TODO: Remove this when automake requirements are 1.12+
AC_MSG_CHECKING([whether we can use TAP mode])
tmp=`$AWK '/TEST_LOG_DRIVER/' $srcdir/GNUmakefile.in`
if test "x$tmp" != "x"; then
use_tap=yes
else
use_tap=no
fi
AC_MSG_RESULT([$use_tap])
else
# we do not really need these paths for non test build
# but automake may error if we do not define them here
SASS_SPEC_PATH=sass-spec
SASS_SASSC_PATH=sassc
AC_SUBST(SASS_SPEC_PATH)
AC_SUBST(SASS_SASSC_PATH)
fi
AM_CONDITIONAL(ENABLE_TESTS, test "x$enable_tests" = "xyes")
AM_CONDITIONAL(USE_TAP, test "x$use_tap" = "xyes")
AC_ARG_ENABLE([coverage],
[AS_HELP_STRING([--enable-coverage],
@@ -14,16 +14,9 @@ There are several implementations of `libsass` for a variety of languages. Here
* [go_sass](https://github.com/suapapa/go_sass)
* [go-sass](https://github.com/SamWhited/go-sass)
### Lua
* [lua-sass](https://github.com/craigbarnes/lua-sass)
### .NET
* [libsass-net](https://github.com/darrenkopp/libsass-net)
* [NSass](https://github.com/TBAPI-0KA/NSass)
* [Sass.Net](https://github.com/andyalm/Sass.Net)
### node.js
* [node-sass](https://github.com/andrew/node-sass)
### Haskell
* [hLibsass](https://github.com/jakubfijalkowski/hlibsass)
* [hSass](https://github.com/jakubfijalkowski/hsass)
### Java
* [libsass-maven-plugin](https://github.com/warmuuh/libsass-maven-plugin)
@@ -32,6 +25,22 @@ There are several implementations of `libsass` for a variety of languages. Here
### JavaScript
* [sass.js](https://github.com/medialize/sass.js)
### Lua
* [lua-sass](https://github.com/craigbarnes/lua-sass)
### .NET
* [libsass-net](https://github.com/darrenkopp/libsass-net)
* [NSass](https://github.com/TBAPI-0KA/NSass)
* [Sass.Net](https://github.com/andyalm/Sass.Net)
* [SharpScss](https://github.com/xoofx/SharpScss)
* [LibSassHost](https://github.com/Taritsyn/LibSassHost)
### Nim
* [nim-sass](https://github.com/zacharycarter/nim-sass)
### node.js
* [node-sass](https://github.com/sass/node-sass)
### Perl
* [CSS::Sass](https://github.com/caldwell/CSS-Sass)
* [Text::Sass::XS](https://github.com/ysasaki/Text-Sass-XS)
@@ -1,27 +1,33 @@
LibSass currently expects all input to be utf8 encoded (and outputs only utf8), if you actually have any unicode characters at all. We do not support conversion between encodings, even if you declare it with a `@charset` rule. The text below was originally posted as an [issue](https://github.com/sass/libsass/issues/381) on the LibSass tracker.
LibSass currently expects all input to be utf8 encoded (and outputs only utf8), if you actually have any unicode characters at all. We do not support conversion between encodings, even if you declare it with a `@charset` rule. The text below was originally posted as an [issue](https://github.com/sass/libsass/issues/381) on the LibSass tracker. Since then the status is outdated as LibSass now expects your
input to be utf8/ascii compatible, as it has been proven that reading ANSI (e.g. single byte encodings) as utf8 can lead to unexpected
behavior, which can in the worst case lead to buffer overruns/segfaults. Therefore LibSass now checks your input to be valid utf8 encoded!
### [Declaring character encodings in CSS](http://www.w3.org/International/questions/qa-css-charset.en)
This [explains](http://www.w3.org/International/questions/qa-css-charset.en) how the character encoding of a css file is determined. Since we are only dealing with local files, we never have a HTTP header. So the precedence should be 'charset' rule, byte-order mark (BOM) or auto-detection (finally falling back to system default/UTF-8). This may not sound too hard to implement, but what about import rules? The CSS specs do not forbid the mixing of different encodings! I solved that by converting all files to UTF-8 internally. On writing there is an option to tell the tool what encoding it should be (UTF-8 by default). One can also define if it should write a BOM or not and if it should add the charset declaration.
This [explains](http://www.w3.org/International/questions/qa-css-charset.en) how the character encoding of a css file is determined. Since we are only dealing with local files, we never have a HTTP header. So the precedence should be 'charset' rule, byte-order mark (BOM) or auto-detection (finally falling back to system default/UTF-8). This may not sound too hard to implement, but what about import rules? The CSS specs do not forbid the mixing of different encodings! I [solved that](https://github.com/mgreter/webmerge/) by converting all files to UTF-8 internally. On writing there is an option to tell the tool what encoding it should be (UTF-8 by default). One can also define if it should write a BOM or not and if it should add the charset declaration.
Since my tool is written in perl, I have a lot of utilities at hand to deal with different unicode charsets. I'm pretty sure that most OSS uses [libiconv](https://www.gnu.org/software/libiconv/) to convert between different encodings. But I have now idea how easy/hard this would be to integrate platform independent (it seems doable).
Since my [tool]((https://github.com/mgreter/webmerge/)) is written in perl, I have a lot of utilities at hand to deal with different unicode charsets. I'm pretty sure that most OSS uses [ICU](http://site.icu-project.org/) or [libiconv](https://www.gnu.org/software/libiconv/) to convert between different encodings. But I have now idea how easy/hard this would be to integrate platform independent (it seems doable). ANSII (single byte encoding) to utf8 is basically just a conversion table (for every supported code-page).
### Current status on LibSass unicode support
Currently LibSass seems to handle the common UTF-8 case pretty well. I believe it should correctly support all ASCII compatible encodings (like UTF-8 or Latin-1). If all includes use the same encoding, the output should be correct (in the same encoding). It should also handle unicode chars in [selectors, variable names and other identifiers](https://github.com/hcatlin/libsass/issues/244#issuecomment-34681227). This is true for all ASCII compatible encodings. So the main incompatible encodings (I'm aware of) are UTF-16/UTF-32 (which could be converted to UTF-8 with libiconv).
LibSass should/is fully UTF (and therefore plain ASCII) compatible.
~~Currently LibSass seems to handle the common UTF-8 case pretty well. I believe it should correctly support all ASCII compatible encodings (like UTF-8 or Latin-1). If all includes use the same encoding, the output should be correct (in the same encoding). It should also handle unicode chars in [selectors, variable names and other identifiers](https://github.com/hcatlin/libsass/issues/244#issuecomment-34681227). This is true for all ASCII compatible encodings. So the main incompatible encodings (I'm aware of) are UTF-16/UTF-32 (which could be converted to UTF-8 with libiconv).~~
LibSass 3.5 will enforce that your input is either plain ASCII (chars below 127) or utf8. It does not handle anything else, but therefore ensures that the output is in a valid form. Before version 3.5 you were able to mix different code-pages, which yielded unexpected behavior.
### Current encoding auto detection
LibSass currently reads all kind of BOMs and will error out if it finds something it doesn't know how to handle! It seems that it throws away the optional UTF-8 BOM (if any is found). IMO it would be nice if users could configure that (also if a charset rule should be added to the output).
LibSass currently reads all kind of BOMs and will error out if it finds something it doesn't know how to handle! It seems that it throws away the optional UTF-8 BOM (if any is found). IMO it would be nice if users could configure that (also if a charset rule should be added to the output). But it does not really take any `@charset` into account, it always assumes your input is utf8 and ignores any given `@charset`!
### What is currently not supported
- Using non ASCII compatible encodings (like UTF-16)
- Using non ASCII compatible encodings (like UTF-16, Latin-1 etc.)
- Using non ASCII characters in different encodings in different includes
### What is missing to support the above cases
- A way to convert between encodings (like libiconv)
- A way to convert between encodings (like libiconv/ICU)
- Sniffing the charset inside the file (source is available)
- Handling the conversion on import (and export)
- Optional: Make output encoding configurable
@@ -31,9 +37,9 @@ LibSass currently reads all kind of BOMs and will error out if it finds somethin
I guess the current implementation should handle more than 99% of all real world use cases.
A) Unicode characters are still seldomly seen (as they can be written escaped)
B) It will still work if it's UTF-8 or in any of the most common known western ISO codepages.
Although I'm not sure how this applies to asian and other "exotic" codepages!
~~B) It will still work if it's UTF-8 or in any of the most common known western ISO codepages.
Although I'm not sure how this applies to asian and other "exotic" codepages!~~
I guess the biggest Problem is to have libiconv (or some other) library as a dependency. Since it contains a lot of rules for the conversions, I see it as the only way to handle this correctly. Once that is sorted out it should be pretty much straight forward to implement the missing pieces (in parser.cpp - Parser::parse should return encoding and add Parser::sniff_charset, then convert the source byte stream to UTF-8).
I guess the biggest Problem is to have libiconv/ICU (or some other) library as a dependency. Since it contains a lot of rules for the conversions, I see it as the only way to handle this correctly. Once that is sorted out it should be pretty much straight forward to implement the missing pieces (in parser.cpp - Parser::parse should return encoding and add Parser::sniff_charset, then convert the source byte stream to UTF-8).
I hope the statements above all hold true. Unicode is really not the easiest topic to wrap your head around. But since I did all the above recently in Perl, I wanted to document it here. Feel free to extend or criticize.
@@ -53,8 +53,8 @@ if [ "x$PLUGIN" == "xglob" ]; then
${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build ${SASS_SPEC_SPEC_DIR}/basic/input.scss > ${SASS_SPEC_SPEC_DIR}/basic/result.css
${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build ${SASS_SPEC_SPEC_DIR}/basic/input.scss --sourcemap > /dev/null
else
cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic > ${SASS_SPEC_SPEC_DIR}/basic/result.css
cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic --sourcemap > /dev/null
cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --precision 5 --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic > ${SASS_SPEC_SPEC_DIR}/basic/result.css
cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --precision 5 --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic --sourcemap > /dev/null
fi
RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi
@@ -1 +1 @@
$@ | tapout tap
$@ $TEST_FLAGS --tap --silent | tapout tap
@@ -47,7 +47,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
*codechar++ = base64_encode_value(result);
result = (fragment & 0x003) << 4;
#ifndef _MSC_VER
__attribute__ ((fallthrough));
/* fall through */
#endif
case step_B:
if (plainchar == plaintextend)
@@ -61,7 +61,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
*codechar++ = base64_encode_value(result);
result = (fragment & 0x00f) << 2;
#ifndef _MSC_VER
__attribute__ ((fallthrough));
/* fall through */
#endif
case step_C:
if (plainchar == plaintextend)
@@ -559,7 +559,7 @@ namespace Sass {
std::string m1 = std::string(mq1->is_restricted() ? "only" : mq1->is_negated() ? "not" : "");
std::string t1 = mq1->media_type() ? mq1->media_type()->to_string(ctx.c_options) : "";
std::string m2 = std::string(mq2->is_restricted() ? "only" : mq1->is_negated() ? "not" : "");
std::string m2 = std::string(mq2->is_restricted() ? "only" : mq2->is_negated() ? "not" : "");
std::string t2 = mq2->media_type() ? mq2->media_type()->to_string(ctx.c_options) : "";
@@ -627,6 +627,7 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
Number_Ptr expression = Cast<Number>(node);
std::cerr << ind << "Number " << expression;
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [delayed: " << expression->is_delayed() << "] ";
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
std::cerr << " [" << expression->value() << expression->unit() << "]" <<
" [hash: " << expression->hash() << "] " <<
@@ -599,10 +599,6 @@ namespace Sass {
switch (op_type) {
case Sass_OP::EQ: return *l_n == *r_c ? bool_true : bool_false;
case Sass_OP::NEQ: return *l_n == *r_c ? bool_false : bool_true;
case Sass_OP::LT: return *l_n < *r_c ? bool_true : bool_false;
case Sass_OP::GTE: return *l_n < *r_c ? bool_false : bool_true;
case Sass_OP::LTE: return *l_n < *r_c || *l_n == *r_c ? bool_true : bool_false;
case Sass_OP::GT: return *l_n < *r_c || *l_n == *r_c ? bool_false : bool_true;
case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
return Operators::op_number_color(op_type, *l_n, *r_c, ctx.c_options, b_in->pstate());
default: break;
@@ -643,10 +639,6 @@ namespace Sass {
switch (op_type) {
case Sass_OP::EQ: return *l_c == *r_n ? bool_true : bool_false;
case Sass_OP::NEQ: return *l_c == *r_n ? bool_false : bool_true;
case Sass_OP::LT: return *l_c < *r_n ? bool_true : bool_false;
case Sass_OP::GTE: return *l_c < *r_n ? bool_false : bool_true;
case Sass_OP::LTE: return *l_c < *r_n || *l_c == *r_n ? bool_true : bool_false;
case Sass_OP::GT: return *l_c < *r_n || *l_c == *r_n ? bool_false : bool_true;
case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:
return Operators::op_color_number(op_type, *l_c, *r_n, ctx.c_options, b_in->pstate());
default: break;
@@ -1265,13 +1257,6 @@ namespace Sass {
Expression_Ptr Eval::operator()(String_Constant_Ptr s)
{
if (!s->is_delayed() && name_to_color(s->value())) {
Color_Ptr c = SASS_MEMORY_COPY(name_to_color(s->value())); // copy
c->pstate(s->pstate());
c->disp(s->value());
c->is_delayed(true);
return c;
}
return s;
}
@@ -246,7 +246,8 @@ namespace Sass {
std::string str(prop->to_string(ctx.c_options));
new_p = SASS_MEMORY_NEW(String_Constant, old_p->pstate(), str);
}
Expression_Obj value = d->value()->perform(&eval);
Expression_Obj value = d->value();
if (value) value = value->perform(&eval);
Block_Obj bb = ab ? operator()(ab) : NULL;
if (!bb) {
if (!value || (value->is_invisible() && !d->is_important())) return 0;
@@ -467,7 +467,7 @@ namespace Sass {
double s;
double l = (max + min) / 2.0;
if (max == min) {
if (NEAR_EQUAL(max, min)) {
h = s = 0; // achromatic
}
else {
@@ -658,6 +658,9 @@ namespace Sass {
}
std::stringstream hexlet;
// dart sass compressed all colors in regular css always
// ruby sass and libsass does it only when not delayed
// since color math is going to be removed, this can go too
bool compressed = opt.output_style == COMPRESSED;
hexlet << '#' << std::setw(1) << std::setfill('0');
// create a short color hexlet if there is any need for it
@@ -681,9 +684,6 @@ namespace Sass {
if (name != "") {
ss << name;
}
else if (r == 0 && g == 0 && b == 0 && a == 0) {
ss << "transparent";
}
else if (a >= 1) {
if (res_name != "") {
if (compressed && hexlet.str().size() < res_name.size()) {
@@ -1057,7 +1057,7 @@ namespace Sass {
case Complex_Selector::REFERENCE:
append_mandatory_space();
append_string("/");
c->reference()->perform(this);
if (c->reference()) c->reference()->perform(this);
append_string("/");
append_mandatory_space();
break;
@@ -54,6 +54,22 @@ namespace Sass {
bool lte(Expression_Obj lhs, Expression_Obj rhs) { return cmp(lhs, rhs, Sass_OP::LTE) || eq(lhs, rhs); }
bool gte(Expression_Obj lhs, Expression_Obj rhs) { return !cmp(lhs, rhs, Sass_OP::GTE) || eq(lhs, rhs); }
/* colour math deprecation warning */
void op_color_deprecation(enum Sass_OP op, std::string lsh, std::string rhs, const ParserState& pstate)
{
std::string op_str(
op == Sass_OP::ADD ? "plus" :
op == Sass_OP::DIV ? "div" :
op == Sass_OP::SUB ? "minus" :
op == Sass_OP::MUL ? "times" : ""
);
std::string msg("The operation `" + lsh + " " + op_str + " " + rhs + "` is deprecated and will be an error in future versions.");
std::string tail("Consider using Sass's color functions instead.\nhttp://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions");
deprecated(msg, tail, false, pstate);
}
/* static function, throws OperationError, has no traces but optional pstate for returned value */
Value_Ptr op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
{
@@ -107,12 +123,16 @@ namespace Sass {
/* static function, throws OperationError, has no traces but optional pstate for returned value */
Value_Ptr op_colors(enum Sass_OP op, const Color& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
{
if (lhs.a() != rhs.a()) {
throw Exception::AlphaChannelsNotEqual(&lhs, &rhs, op);
}
if (op == Sass_OP::DIV && (!rhs.r() || !rhs.g() || !rhs.b())) {
if ((op == Sass_OP::DIV || op == Sass_OP::MOD) && (!rhs.r() || !rhs.g() || !rhs.b())) {
throw Exception::ZeroDivisionError(lhs, rhs);
}
op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);
return SASS_MEMORY_NEW(Color,
pstate,
ops[op](lhs.r(), rhs.r()),
@@ -127,15 +147,15 @@ namespace Sass {
double lval = lhs.value();
double rval = rhs.value();
if (op == Sass_OP::MOD && rval == 0) {
return SASS_MEMORY_NEW(String_Quoted, pstate, "NaN");
}
if (op == Sass_OP::DIV && rval == 0) {
std::string result(lval ? "Infinity" : "NaN");
return SASS_MEMORY_NEW(String_Quoted, pstate, result);
}
if (op == Sass_OP::MOD && rval == 0) {
throw Exception::ZeroDivisionError(lhs, rhs);
}
size_t l_n_units = lhs.numerators.size();
size_t l_d_units = lhs.numerators.size();
size_t r_n_units = rhs.denominators.size();
@@ -195,9 +215,11 @@ namespace Sass {
Value_Ptr op_number_color(enum Sass_OP op, const Number& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
{
double lval = lhs.value();
switch (op) {
case Sass_OP::ADD:
case Sass_OP::MUL: {
op_color_deprecation(op, lhs.to_string(), rhs.to_string(opt), pstate);
return SASS_MEMORY_NEW(Color,
pstate,
ops[op](lval, rhs.r()),
@@ -208,6 +230,7 @@ namespace Sass {
case Sass_OP::SUB:
case Sass_OP::DIV: {
std::string color(rhs.to_string(opt));
op_color_deprecation(op, lhs.to_string(), color, pstate);
return SASS_MEMORY_NEW(String_Quoted,
pstate,
lhs.to_string(opt)
@@ -223,10 +246,14 @@ namespace Sass {
Value_Ptr op_color_number(enum Sass_OP op, const Color& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
{
double rval = rhs.value();
if (op == Sass_OP::DIV && rval == 0) {
if ((op == Sass_OP::DIV || op == Sass_OP::DIV) && rval == 0) {
// comparison of Fixnum with Float failed?
throw Exception::ZeroDivisionError(lhs, rhs);
}
op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);
return SASS_MEMORY_NEW(Color,
pstate,
ops[op](lhs.r(), rval),
+40 -24
View File
@@ -1578,7 +1578,7 @@ namespace Sass {
return nr;
}
Expression_Ptr Parser::lexed_hex_color(const ParserState& pstate, const std::string& parsed)
Value_Ptr Parser::lexed_hex_color(const ParserState& pstate, const std::string& parsed)
{
Color_Ptr color = NULL;
if (parsed[0] != '#') {
@@ -1598,6 +1598,19 @@ namespace Sass {
1, // alpha channel
parsed);
}
else if (parsed.length() == 5) {
std::string r(2, parsed[1]);
std::string g(2, parsed[2]);
std::string b(2, parsed[3]);
std::string a(2, parsed[4]);
color = SASS_MEMORY_NEW(Color,
pstate,
static_cast<double>(strtol(r.c_str(), NULL, 16)),
static_cast<double>(strtol(g.c_str(), NULL, 16)),
static_cast<double>(strtol(b.c_str(), NULL, 16)),
static_cast<double>(strtol(a.c_str(), NULL, 16)) / 255,
parsed);
}
else if (parsed.length() == 7) {
std::string r(parsed.substr(1,2));
std::string g(parsed.substr(3,2));
@@ -1628,6 +1641,19 @@ namespace Sass {
return color;
}
Value_Ptr Parser::color_or_string(const std::string& lexed) const
{
if (auto color = name_to_color(lexed)) {
auto c = SASS_MEMORY_NEW(Color, color);
c->is_delayed(true);
c->pstate(pstate);
c->disp(lexed);
return c;
} else {
return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
}
}
// parse one value for a list
Expression_Obj Parser::parse_value()
{
@@ -1670,7 +1696,7 @@ namespace Sass {
{ return SASS_MEMORY_NEW(Null, pstate); }
if (lex< identifier >()) {
return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
return color_or_string(lexed);
}
if (lex< percentage >())
@@ -1681,17 +1707,7 @@ namespace Sass {
{ return lexed_hex_color(lexed); }
if (lex< hexa >())
{
std::string s = lexed.to_string();
deprecated(
"The value \""+s+"\" is currently parsed as a string, but it will be parsed as a color in",
"future versions of Sass. Use \"unquote('"+s+"')\" to continue parsing it as a string.",
true, pstate
);
return SASS_MEMORY_NEW(String_Quoted, pstate, lexed);
}
{ return lexed_hex_color(lexed); }
if (lex< sequence < exactly <'#'>, identifier > >())
{ return SASS_MEMORY_NEW(String_Quoted, pstate, lexed); }
@@ -1710,10 +1726,6 @@ namespace Sass {
if (lex< variable >())
{ return SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)); }
// Special case handling for `%` proceeding an interpolant.
if (lex< sequence< exactly<'%'>, optional< percentage > > >())
{ return SASS_MEMORY_NEW(String_Constant, pstate, lexed); }
css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
// unreachable statement
@@ -1841,7 +1853,7 @@ namespace Sass {
return schema->length() > 0 ? schema.detach() : NULL;
}
String_Constant_Obj Parser::parse_static_value()
Value_Obj Parser::parse_static_value()
{
lex< static_value >();
Token str(lexed);
@@ -1852,8 +1864,7 @@ namespace Sass {
--str.end;
--position;
String_Constant_Ptr str_node = SASS_MEMORY_NEW(String_Constant, pstate, str.time_wspace());
return str_node;
return color_or_string(str.time_wspace());;
}
String_Obj Parser::parse_string()
@@ -1962,7 +1973,7 @@ namespace Sass {
if (lex< re_static_expression >()) {
ex = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
} else {
ex = parse_list();
ex = parse_list(true);
}
ex->is_interpolant(true);
schema->append(ex);
@@ -1986,7 +1997,7 @@ namespace Sass {
}
if (peek < exactly < '-' > >()) break;
}
else if (lex< sequence < identifier > >()) {
else if (lex< identifier >()) {
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) {
// need_space = true;
@@ -2155,6 +2166,7 @@ namespace Sass {
while (pp && peek< exactly< hash_lbrace > >(pp)) {
pp = sequence< interpolant, real_uri_value >(pp);
}
if (!pp) return 0;
position = pp;
return parse_interpolated_chunk(Token(p, position));
}
@@ -2691,7 +2703,9 @@ namespace Sass {
if ((rv = lex_interp_string())) return rv;
if ((rv = lex_interp_uri())) return rv;
if ((rv = lex_interpolation())) return rv;
return rv;
if (lex< alternatives< hex, hex0 > >())
{ return lexed_hex_color(lexed); }
return rv;
}
String_Schema_Obj Parser::parse_almost_any_value()
@@ -2777,6 +2791,7 @@ namespace Sass {
>(p)
) {
bool could_be_property = peek< sequence< exactly<'-'>, exactly<'-'> > >(p) != 0;
bool could_be_escaped = false;
while (p < q) {
// did we have interpolations?
if (*p == '#' && *(p+1) == '{') {
@@ -2785,9 +2800,10 @@ namespace Sass {
}
// A property that's ambiguous with a nested selector is interpreted as a
// custom property.
if (*p == ':') {
if (*p == ':' && !could_be_escaped) {
rv.is_custom_property = could_be_property || p+1 == q || peek< space >(p+1);
}
could_be_escaped = *p == '\\';
++ p;
}
// store anyway }
@@ -290,7 +290,7 @@ namespace Sass {
String_Obj parse_url_function_argument();
String_Obj parse_interpolated_chunk(Token, bool constant = false, bool css = true);
String_Obj parse_string();
String_Constant_Obj parse_static_value();
Value_Obj parse_static_value();
String_Schema_Obj parse_css_variable_value(bool top_level = true);
String_Schema_Obj parse_css_variable_value_token(bool top_level = true);
String_Obj parse_ie_property();
@@ -325,6 +325,8 @@ namespace Sass {
Error_Obj parse_error();
Debug_Obj parse_debug();
Value_Ptr color_or_string(const std::string& lexed) const;
// be more like ruby sass
Expression_Obj lex_almost_any_value_token();
Expression_Obj lex_almost_any_value_chars();
@@ -380,12 +382,12 @@ namespace Sass {
static Number_Ptr lexed_number(const ParserState& pstate, const std::string& parsed);
static Number_Ptr lexed_dimension(const ParserState& pstate, const std::string& parsed);
static Number_Ptr lexed_percentage(const ParserState& pstate, const std::string& parsed);
static Expression_Ptr lexed_hex_color(const ParserState& pstate, const std::string& parsed);
static Value_Ptr lexed_hex_color(const ParserState& pstate, const std::string& parsed);
private:
Number_Ptr lexed_number(const std::string& parsed) { return lexed_number(pstate, parsed); };
Number_Ptr lexed_dimension(const std::string& parsed) { return lexed_dimension(pstate, parsed); };
Number_Ptr lexed_percentage(const std::string& parsed) { return lexed_percentage(pstate, parsed); };
Expression_Ptr lexed_hex_color(const std::string& parsed) { return lexed_hex_color(pstate, parsed); };
Value_Ptr lexed_hex_color(const std::string& parsed) { return lexed_hex_color(pstate, parsed); };
static const char* re_attr_sensitive_close(const char* src);
static const char* re_attr_insensitive_close(const char* src);
@@ -1606,7 +1606,7 @@ namespace Sass {
>(src);
}
extern const char css_variable_url_top_level_negates[] = "()[]{}\"'#/;!";
extern const char css_variable_url_top_level_negates[] = "()[]{}\"'#/;";
const char* css_variable_top_level_value(const char* src) {
return sequence<
alternatives<
@@ -33,8 +33,10 @@ extern "C" {
void* ADDCALL sass_alloc_memory(size_t size)
{
void* ptr = malloc(size);
if (ptr == NULL)
out_of_memory();
if (ptr == NULL) {
std::cerr << "Out of memory.\n";
exit(EXIT_FAILURE);
}
return ptr;
}
@@ -12,11 +12,6 @@
namespace Sass {
#define out_of_memory() do { \
std::cerr << "Out of memory.\n"; \
exit(EXIT_FAILURE); \
} while (0)
double round(double val, size_t precision = 0);
double sass_strtod(const char* str);
const char* safe_str(const char *, const char* = "");
@@ -33,6 +33,9 @@ extern "C" {
else if (ctx_w->fctx) {
sass_delete_file_context(ctx_w->fctx);
}
if (ctx_w->async_resource) {
delete ctx_w->async_resource;
}
delete ctx_w->error_callback;
delete ctx_w->success_callback;
@@ -39,6 +39,7 @@ extern "C" {
// v8 and nan related
Nan::Persistent<v8::Object> result;
Nan::AsyncResource* async_resource;
Nan::Callback* error_callback;
Nan::Callback* success_callback;