diff --git a/include/sass/base.h b/include/sass/base.h index 83b990e7c6..c1f030ae33 100644 --- a/include/sass/base.h +++ b/include/sass/base.h @@ -56,7 +56,9 @@ enum Sass_Output_Style { SASS_STYLE_NESTED, SASS_STYLE_EXPANDED, SASS_STYLE_COMPACT, - SASS_STYLE_COMPRESSED + SASS_STYLE_COMPRESSED, + // only used internal + SASS_STYLE_INSPECT }; // Some convenient string helper function diff --git a/src/ast.cpp b/src/ast.cpp index e6c7b4d6a3..0f47d6fde1 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -280,7 +280,7 @@ namespace Sass { Compound_Selector* Simple_Selector::unify_with(Compound_Selector* rhs, Context& ctx) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); for (size_t i = 0, L = rhs->length(); i < L; ++i) { if (perform(&to_string) == (*rhs)[i]->perform(&to_string)) return rhs; } @@ -1375,7 +1375,7 @@ namespace Sass { Compound_Selector* Compound_Selector::minus(Compound_Selector* rhs, Context& ctx) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); Compound_Selector* result = SASS_MEMORY_NEW(ctx.mem, Compound_Selector, pstate()); // result->has_parent_reference(has_parent_reference()); @@ -1884,7 +1884,7 @@ namespace Sass { else { return &sass_null; } } - std::string Map::to_string(bool compressed, int precision) const + std::string Map::to_string(Sass_Inspect_Options opt) const { std::string res(""); if (empty()) return res; @@ -1893,24 +1893,26 @@ namespace Sass { for (auto key : keys()) { if (key->is_invisible()) continue; if (at(key)->is_invisible()) continue; + bool compressed = opt.output_style == COMPRESSED; if (items_output) res += compressed ? "," : ", "; Value* v_key = dynamic_cast(key); Value* v_val = dynamic_cast(at(key)); - if (v_key) res += v_key->to_string(compressed, precision); + if (v_key) res += v_key->to_string(opt); res += compressed ? ":" : ": "; - if (v_val) res += v_val->to_string(compressed, precision); + if (v_val) res += v_val->to_string(opt); items_output = true; } return res; } - std::string List::to_string(bool compressed, int precision) const + std::string List::to_string(Sass_Inspect_Options opt) const { std::string res(""); if (empty()) return res; if (is_invisible()) return res; bool items_output = false; std::string sep = separator() == SASS_SPACE ? " " : ","; + bool compressed = opt.output_style == COMPRESSED; if (!compressed && sep == ",") sep += " "; for (size_t i = 0, L = size(); i < L; ++i) { if (separator_ == SASS_HASH) @@ -1919,37 +1921,38 @@ namespace Sass { if (item->is_invisible()) continue; if (items_output) res += sep; if (Expression* ex = dynamic_cast(item)) - { res += ex->to_string(compressed, precision); } + { res += ex->to_string(opt); } // else if (Function_Call* v_fn = dynamic_cast(item)) - // { res += v_fn->to_string(compressed, precision); } + // { res += v_fn->to_string(opt); } else { res += "[unknown type]"; } items_output = true; } return res; } - std::string Function_Call::to_string(bool compressed, int precision) const + std::string Function_Call::to_string(Sass_Inspect_Options opt) const { std::string str(name()); str += "("; - str += arguments()->to_string(compressed, precision); + str += arguments()->to_string(opt); str += ")"; return str; } - std::string Arguments::to_string(bool compressed, int precision) const + std::string Arguments::to_string(Sass_Inspect_Options opt) const { std::string str(""); + bool compressed = opt.output_style == COMPRESSED; for(auto arg : elements()) { if (str != "") str += compressed ? "," : ", "; - str += arg->to_string(compressed, precision); + str += arg->to_string(opt); } return str; } - std::string Argument::to_string(bool compressed, int precision) const + std::string Argument::to_string(Sass_Inspect_Options opt) const { - return value()->to_string(compressed, precision); + return value()->to_string(opt); } bool Binary_Expression::is_left_interpolant(void) const @@ -1961,36 +1964,17 @@ namespace Sass { return is_interpolant() || (right() && right()->is_right_interpolant()); } - std::string Binary_Expression::to_string(bool compressed, int precision) const + std::string Binary_Expression::to_string(Sass_Inspect_Options opt) const { - std::string str(""); - str += left()->to_string(compressed, precision); - if (!compressed) str += " "; - switch (type()) { - case Sass_OP::AND: str += "and"; break; - case Sass_OP::OR: str += "or"; break; - case Sass_OP::EQ: str += "=="; break; - case Sass_OP::NEQ: str += "!="; break; - case Sass_OP::GT: str += ">"; break; - case Sass_OP::GTE: str += ">="; break; - case Sass_OP::LT: str += "<"; break; - case Sass_OP::LTE: str += "<="; break; - case Sass_OP::ADD: str += "+"; break; - case Sass_OP::SUB: str += "-"; break; - case Sass_OP::MUL: str += "*"; break; - case Sass_OP::DIV: str += "/"; break; - case Sass_OP::MOD: str += "%"; break; - default: break; // shouldn't get here - } - if (!compressed) str += " "; - str += right()->to_string(compressed, precision); - return str; + To_String to_string(opt); + Binary_Expression ex(*this); + return ex.perform(&to_string); } - std::string Textual::to_string(bool compressed, int precision) const + std::string Textual::to_string(Sass_Inspect_Options opt) const { return value(); } - std::string Variable::to_string(bool compressed, int precision) const + std::string Variable::to_string(Sass_Inspect_Options opt) const { return name(); } @@ -1998,53 +1982,67 @@ namespace Sass { // For now it seems easiest to just implement these, since we need it to // ie. report the values as is for error reporting (like duplicate keys). // We cannot use inspect since we do not always have a context object. - std::string Unary_Expression::to_string(bool compressed, int precision) const + std::string Unary_Expression::to_string(Sass_Inspect_Options opt) const { - return "[Unary_Expression.to_string not implemented]"; + To_String to_string(opt); + Unary_Expression ex(*this); + return ex.perform(&to_string); } - std::string Function_Call_Schema::to_string(bool compressed, int precision) const + std::string Function_Call_Schema::to_string(Sass_Inspect_Options opt) const { - return "[Function_Call_Schema.to_string not implemented]"; + To_String to_string(opt); + Function_Call_Schema ex(*this); + return ex.perform(&to_string); } - std::string Media_Query::to_string(bool compressed, int precision) const + std::string Media_Query::to_string(Sass_Inspect_Options opt) const { - return "[Media_Query.to_string not implemented]"; + To_String to_string(opt); + Media_Query ex(*this); + return ex.perform(&to_string); } - std::string Media_Query_Expression::to_string(bool compressed, int precision) const + std::string Media_Query_Expression::to_string(Sass_Inspect_Options opt) const { - return "[Media_Query_Expression.to_string not implemented]"; + To_String to_string(opt); + Media_Query_Expression ex(*this); + return ex.perform(&to_string); } - std::string Supports_Condition::to_string(bool compressed, int precision) const + std::string Supports_Condition::to_string(Sass_Inspect_Options opt) const { - return "[Supports_Condition.to_string not implemented]"; + To_String to_string(opt); + Supports_Condition ex(*this); + return ex.perform(&to_string); } - std::string At_Root_Expression::to_string(bool compressed, int precision) const + std::string At_Root_Expression::to_string(Sass_Inspect_Options opt) const { - return "[At_Root_Expression.to_string not implemented]"; + To_String to_string(opt); + At_Root_Expression ex(*this); + return ex.perform(&to_string); } - std::string Thunk::to_string(bool compressed, int precision) const + std::string Thunk::to_string(Sass_Inspect_Options opt) const { - return "[Thunk.to_string not implemented]"; + To_String to_string(opt); + Thunk ex(*this); + return ex.perform(&to_string); } - std::string String_Schema::to_string(bool compressed, int precision) const + std::string String_Schema::to_string(Sass_Inspect_Options opt) const { std::string res(""); for (size_t i = 0, L = length(); i < L; ++i) { if ((*this)[i]->is_interpolant()) res += "#{"; if (Value* val = dynamic_cast((*this)[i])) - { res += val->to_string(compressed, precision); } + { res += val->to_string(opt); } if ((*this)[i]->is_interpolant()) res += "}"; } return res; } - std::string Null::to_string(bool compressed, int precision) const + std::string Null::to_string(Sass_Inspect_Options opt) const { return "null"; } - std::string Boolean::to_string(bool compressed, int precision) const + std::string Boolean::to_string(Sass_Inspect_Options opt) const { return value_ ? "true" : "false"; } @@ -2057,7 +2055,7 @@ namespace Sass { else return c; } - std::string Color::to_hex(bool compressed, int precision) const + std::string Color::to_hex(Sass_Inspect_Options opt) const { std::stringstream ss; @@ -2069,6 +2067,8 @@ namespace Sass { // resolved color std::string res_name = name; + bool compressed = opt.output_style == COMPRESSED; + double r = Sass::round(cap_channel<0xff>(r_)); double g = Sass::round(cap_channel<0xff>(g_)); double b = Sass::round(cap_channel<0xff>(b_)); @@ -2105,7 +2105,7 @@ namespace Sass { return hexlet.str(); } - std::string Color::to_string(bool compressed, int precision) const + std::string Color::to_string(Sass_Inspect_Options opt) const { std::stringstream ss; @@ -2116,17 +2116,17 @@ namespace Sass { // resolved color std::string res_name = name; - double r = Sass::round(cap_channel<0xff>(r_), precision); - double g = Sass::round(cap_channel<0xff>(g_), precision); - double b = Sass::round(cap_channel<0xff>(b_), precision); + double r = Sass::round(cap_channel<0xff>(r_), opt.precision); + double g = Sass::round(cap_channel<0xff>(g_), opt.precision); + double b = Sass::round(cap_channel<0xff>(b_), opt.precision); double a = cap_channel<1> (a_); // get color from given name (if one was given at all) if (name != "" && name_to_color(name)) { const Color* n = name_to_color(name); - r = Sass::round(cap_channel<0xff>(n->r()), precision); - g = Sass::round(cap_channel<0xff>(n->g()), precision); - b = Sass::round(cap_channel<0xff>(n->b()), precision); + r = Sass::round(cap_channel<0xff>(n->r()), opt.precision); + g = Sass::round(cap_channel<0xff>(n->g()), opt.precision); + b = Sass::round(cap_channel<0xff>(n->b()), opt.precision); a = cap_channel<1> (n->a()); } // otherwise get the possible resolved color name @@ -2137,6 +2137,7 @@ namespace Sass { } std::stringstream hexlet; + 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 if (compressed && is_color_doublet(r, g, b) && a == 1) { @@ -2185,7 +2186,7 @@ namespace Sass { } - std::string Number::to_string(bool compressed, int precision) const + std::string Number::to_string(Sass_Inspect_Options opt) const { std::string res; @@ -2206,7 +2207,7 @@ namespace Sass { // check if we got scientific notation in result if (ss.str().find_first_of("e") != std::string::npos) { ss.clear(); ss.str(std::string()); - ss.precision(std::max(12, precision)); + ss.precision(std::max(12, opt.precision)); ss << std::fixed << value_; } @@ -2230,10 +2231,10 @@ namespace Sass { else { // do we have have too much precision? - if (pos_fract < precision + pos_point) - { precision = (int)(pos_fract - pos_point); } + if (pos_fract < opt.precision + pos_point) + { ss.precision((int)(pos_fract - pos_point)); } + else { ss.precision(opt.precision); } // round value again - ss.precision(precision); ss << std::fixed << value_; res = std::string(ss.str()); // maybe we truncated up to decimal point @@ -2255,7 +2256,7 @@ namespace Sass { else if (res == "") res = "0"; else if (res == "-0") res = "0"; else if (res == "-0.0") res = "0"; - else if (compressed) + else if (opt.output_style == COMPRESSED) { // check if handling negative nr size_t off = res[0] == '-' ? 1 : 0; @@ -2276,7 +2277,7 @@ namespace Sass { return quote(value_, '*', true); } - std::string String_Quoted::to_string(bool compressed, int precision) const + std::string String_Quoted::to_string(Sass_Inspect_Options opt) const { return quote_mark_ ? quote(value_, quote_mark_, true) : value_; } @@ -2286,54 +2287,56 @@ namespace Sass { return quote(value_, '*', true); } - std::string String_Constant::to_string(bool compressed, int precision) const + std::string String_Constant::to_string(Sass_Inspect_Options opt) const { return quote_mark_ ? quote(value_, quote_mark_, true) : value_; } - std::string Custom_Error::to_string(bool compressed, int precision) const + std::string Custom_Error::to_string(Sass_Inspect_Options opt) const { return message(); } - std::string Custom_Warning::to_string(bool compressed, int precision) const + std::string Custom_Warning::to_string(Sass_Inspect_Options opt) const { return message(); } - std::string Selector_List::to_string(bool compressed, int precision) const + std::string Selector_List::to_string(Sass_Inspect_Options opt) const { std::string str(""); auto end = this->end(); auto start = this->begin(); + bool compressed = opt.output_style == COMPRESSED; std::string sep(compressed ? "," : ", "); while (start < end && *start) { Complex_Selector* sel = *start; if (!str.empty()) str += sep; - str += sel->to_string(compressed, precision); + str += sel->to_string(opt); ++ start; } return str; } - std::string Compound_Selector::to_string(bool compressed, int precision) const + std::string Compound_Selector::to_string(Sass_Inspect_Options opt) const { std::string str(""); auto end = this->end(); auto start = this->begin(); while (start < end && *start) { Simple_Selector* sel = *start; - str += sel->to_string(compressed, precision); + str += sel->to_string(opt); ++ start; } return str; } - std::string Complex_Selector::to_string(bool compressed, int precision) const + std::string Complex_Selector::to_string(Sass_Inspect_Options opt) const { // first render head and tail if they are available - std::string str_head(head() ? head()->to_string(compressed, precision) : ""); - std::string str_tail(tail() ? tail()->to_string(compressed, precision) : ""); - std::string str_ref(reference() ? reference()->to_string(compressed, precision) : ""); + std::string str_head(head() ? head()->to_string(opt) : ""); + std::string str_tail(tail() ? tail()->to_string(opt) : ""); + std::string str_ref(reference() ? reference()->to_string(opt) : ""); + bool compressed = opt.output_style == COMPRESSED; // combinator in between std::string str_op(""); // use a switch statement @@ -2368,27 +2371,27 @@ namespace Sass { return str_head + str_op + str_tail; } - std::string Selector_Schema::to_string(bool compressed, int precision) const + std::string Selector_Schema::to_string(Sass_Inspect_Options opt) const { - return contents()->to_string(compressed, precision); + return contents()->to_string(opt); } - std::string Parent_Selector::to_string(bool compressed, int precision) const + std::string Parent_Selector::to_string(Sass_Inspect_Options opt) const { return "&"; } - std::string Attribute_Selector::to_string(bool compressed, int precision) const + std::string Attribute_Selector::to_string(Sass_Inspect_Options opt) const { - std::string val(value() ? value()->to_string(compressed, precision) : ""); + std::string val(value() ? value()->to_string(opt) : ""); return "[" + this->ns_name() + this->matcher() + val + "]"; } - std::string Wrapped_Selector::to_string(bool compressed, int precision) const + std::string Wrapped_Selector::to_string(Sass_Inspect_Options opt) const { // first render the - std::string main(this->Simple_Selector::to_string(compressed, precision)); - std::string wrapped(selector() ? selector()->to_string(compressed, precision) : ""); + std::string main(this->Simple_Selector::to_string(opt)); + std::string wrapped(selector() ? selector()->to_string(opt) : ""); // now build the final result return main + "(" + wrapped + ")"; } diff --git a/src/ast.hpp b/src/ast.hpp index 261f1b3825..060fa922e7 100644 --- a/src/ast.hpp +++ b/src/ast.hpp @@ -148,8 +148,8 @@ namespace Sass { virtual bool has_interpolant() const { return is_interpolant(); } virtual bool is_left_interpolant() const { return is_interpolant(); } virtual bool is_right_interpolant() const { return is_interpolant(); } - virtual std::string inspect() const { return to_string(); } // defaults to to_string - virtual std::string to_string(bool compressed = false, int precision = 5) const = 0; + virtual std::string inspect() const { return to_string({ NESTED, 5 }); } + virtual std::string to_string(Sass_Inspect_Options opt) const = 0; virtual size_t hash() { return 0; } }; @@ -162,7 +162,7 @@ namespace Sass { bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE) : Expression(pstate, d, e, i, ct) { } - virtual std::string to_string(bool compressed = false, int precision = 5) const = 0; + virtual std::string to_string(Sass_Inspect_Options opt) const = 0; virtual ~PreValue() { } }; @@ -176,7 +176,7 @@ namespace Sass { : Expression(pstate, d, e, i, ct) { } virtual bool operator== (const Expression& rhs) const = 0; - virtual std::string to_string(bool compressed = false, int precision = 5) const = 0; + virtual std::string to_string(Sass_Inspect_Options opt) const = 0; }; } @@ -890,7 +890,7 @@ namespace Sass { } virtual bool operator== (const Expression& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -923,7 +923,7 @@ namespace Sass { } virtual bool operator== (const Expression& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1043,7 +1043,7 @@ namespace Sass { } return hash_; } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; enum Sass_OP type() const { return op_.operand; } ATTACH_OPERATIONS() }; @@ -1093,7 +1093,7 @@ namespace Sass { }; return hash_; } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1139,7 +1139,7 @@ namespace Sass { return hash_; } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1162,7 +1162,7 @@ namespace Sass { has_rest_argument_(false), has_keyword_argument_(false) { } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; Argument* get_rest_argument(); Argument* get_keyword_argument(); @@ -1214,7 +1214,7 @@ namespace Sass { return hash_; } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1228,7 +1228,7 @@ namespace Sass { Function_Call_Schema(ParserState pstate, String* n, Arguments* args) : Expression(pstate), name_(n), arguments_(args) { concrete_type(STRING); } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1260,7 +1260,7 @@ namespace Sass { { return std::hash()(name()); } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1304,7 +1304,7 @@ namespace Sass { } return hash_; } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1349,7 +1349,7 @@ namespace Sass { virtual bool operator< (const Number& rhs) const; virtual bool operator== (const Expression& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1384,8 +1384,8 @@ namespace Sass { } virtual bool operator== (const Expression& rhs) const; - virtual std::string to_hex(bool compressed = false, int precision = 5) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_hex(Sass_Inspect_Options opt) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1400,7 +1400,7 @@ namespace Sass { : Value(pstate), message_(msg) { concrete_type(C_ERROR); } virtual bool operator== (const Expression& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1414,7 +1414,7 @@ namespace Sass { : Value(pstate), message_(msg) { concrete_type(C_WARNING); } virtual bool operator== (const Expression& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1443,7 +1443,7 @@ namespace Sass { } virtual bool operator== (const Expression& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1461,7 +1461,7 @@ namespace Sass { static std::string type_name() { return "string"; } virtual ~String() = 0; virtual bool operator==(const Expression& rhs) const = 0; - virtual std::string to_string(bool compressed = false, int precision = 5) const = 0; + virtual std::string to_string(Sass_Inspect_Options opt) const = 0; ATTACH_OPERATIONS() }; inline String::~String() { }; @@ -1500,7 +1500,7 @@ namespace Sass { } virtual bool operator==(const Expression& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1540,7 +1540,7 @@ namespace Sass { virtual bool operator==(const Expression& rhs) const; virtual std::string inspect() const; // quotes are forced on inspection - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; // static char auto_quote() { return '*'; } static char double_quote() { return '"'; } @@ -1562,7 +1562,7 @@ namespace Sass { } virtual bool operator==(const Expression& rhs) const; virtual std::string inspect() const; // quotes are forced on inspection - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1580,7 +1580,7 @@ namespace Sass { : Expression(pstate), Vectorized(s), media_type_(t), is_negated_(n), is_restricted_(r) { } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1596,7 +1596,7 @@ namespace Sass { Expression* f, Expression* v, bool i = false) : Expression(pstate), feature_(f), value_(v), is_interpolated_(i) { } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1623,7 +1623,7 @@ namespace Sass { : Expression(pstate) { } virtual bool needs_parens(Supports_Condition* cond) const { return false; } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1728,7 +1728,7 @@ namespace Sass { return false; } } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1787,7 +1787,7 @@ namespace Sass { } virtual bool operator== (const Expression& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -1802,7 +1802,7 @@ namespace Sass { Thunk(ParserState pstate, Expression* exp, Env* env = 0) : Expression(pstate), expression_(exp), environment_(env) { } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; }; ///////////////////////////////////////////////////////// @@ -1901,7 +1901,7 @@ namespace Sass { virtual unsigned long specificity() { return Constants::Specificity_Universal; } - virtual std::string to_string(bool compressed = false, int precision = 5) const = 0; + virtual std::string to_string(Sass_Inspect_Options opt) const = 0; }; inline Selector::~Selector() { } @@ -1922,7 +1922,7 @@ namespace Sass { } return hash_; } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -2001,7 +2001,7 @@ namespace Sass { bool operator<(const Simple_Selector& rhs) const; // default implementation should work for most of the simple selectors (otherwise overload) - virtual std::string to_string(bool compressed = false, int precision = 5) const { return this->ns_name(); }; + virtual std::string to_string(Sass_Inspect_Options opt) const { return this->ns_name(); }; ATTACH_OPERATIONS(); }; inline Simple_Selector::~Simple_Selector() { } @@ -2025,7 +2025,7 @@ namespace Sass { } std::string type() { return "selector"; } static std::string type_name() { return "selector"; } - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -2106,7 +2106,7 @@ namespace Sass { bool operator==(const Attribute_Selector& rhs) const; bool operator<(const Simple_Selector& rhs) const; bool operator<(const Attribute_Selector& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -2205,7 +2205,7 @@ namespace Sass { bool operator==(const Wrapped_Selector& rhs) const; bool operator<(const Simple_Selector& rhs) const; bool operator<(const Wrapped_Selector& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -2302,7 +2302,7 @@ namespace Sass { Compound_Selector* clone(Context&) const; // does not clone the Simple_Selector*s Compound_Selector* minus(Compound_Selector* rhs, Context& ctx); - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -2461,7 +2461,7 @@ namespace Sass { Complex_Selector* clone(Context&) const; // does not clone Compound_Selector*s Complex_Selector* cloneFully(Context&) const; // clones Compound_Selector*s // std::vector to_vector(); - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; @@ -2516,7 +2516,7 @@ namespace Sass { virtual bool operator==(const Selector_List& rhs) const; // Selector Lists can be compared to comma lists virtual bool operator==(const Expression& rhs) const; - virtual std::string to_string(bool compressed = false, int precision = 5) const; + virtual std::string to_string(Sass_Inspect_Options opt) const; ATTACH_OPERATIONS() }; diff --git a/src/bind.cpp b/src/bind.cpp index 44edb2e083..c2534d0db5 100644 --- a/src/bind.cpp +++ b/src/bind.cpp @@ -14,7 +14,7 @@ namespace Sass { { std::string callee(type + " " + name); - Listize listize(*ctx); + Listize listize(ctx->mem); std::map param_map; for (size_t i = 0, L = as->length(); i < L; ++i) { @@ -259,7 +259,7 @@ namespace Sass { // That's only okay if they have default values, or were already bound by // named arguments, or if it's a single rest-param. for (size_t i = ip; i < LP; ++i) { - To_String to_string(ctx); + To_String to_string(ctx->c_options); Parameter* leftover = (*ps)[i]; // cerr << "env for default params:" << endl; // env->print(); diff --git a/src/bind.hpp b/src/bind.hpp index 2ccf941be1..b523192c1e 100644 --- a/src/bind.hpp +++ b/src/bind.hpp @@ -2,6 +2,7 @@ #define SASS_BIND_H #include +#include "listize.hpp" #include "environment.hpp" namespace Sass { diff --git a/src/context.cpp b/src/context.cpp index 15e59df210..b382545f35 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -58,13 +58,14 @@ namespace Sass { return safe_path == "" ? "stdout" : safe_path; } - Context::Context(struct Sass_Context* c_ctx) + Context::Context(struct Sass_Context& c_ctx) : CWD(File::get_cwd()), + c_options(c_ctx), entry_path(""), head_imports(0), mem(Memory_Manager()), plugins(), - emitter(this), + emitter(c_options), strings(), resources(), @@ -72,19 +73,17 @@ namespace Sass { subset_map(), import_stack(), - c_options (c_ctx), - c_headers (std::vector()), c_importers (std::vector()), c_functions (std::vector()), - indent (safe_str(c_options->indent, " ")), - linefeed (safe_str(c_options->linefeed, "\n")), + indent (safe_str(c_options.indent, " ")), + linefeed (safe_str(c_options.linefeed, "\n")), - input_path (make_canonical_path(safe_input(c_options->input_path))), - output_path (make_canonical_path(safe_output(c_options->output_path, input_path))), - source_map_file (make_canonical_path(safe_str(c_options->source_map_file, ""))), - source_map_root (make_canonical_path(safe_str(c_options->source_map_root, ""))) + input_path (make_canonical_path(safe_input(c_options.input_path))), + output_path (make_canonical_path(safe_output(c_options.output_path, input_path))), + source_map_file (make_canonical_path(safe_str(c_options.source_map_file, ""))), + source_map_root (make_canonical_path(safe_str(c_options.source_map_root, ""))) { @@ -92,10 +91,10 @@ namespace Sass { include_paths.push_back(CWD); // collect more paths from different options - collect_include_paths(sass_option_get_include_path(c_options)); - // collect_include_paths(initializers.include_paths_array()); - collect_plugin_paths(sass_option_get_plugin_path(c_options)); - // collect_plugin_paths(initializers.plugin_paths_array()); + collect_include_paths(c_options.include_path); + // collect_include_paths(c_options.include_paths); + collect_plugin_paths(c_options.plugin_path); + // collect_plugin_paths(c_options.plugin_paths); // load plugins and register custom behaviors for(auto plug : plugin_paths) plugins.load_plugins(plug); @@ -505,9 +504,9 @@ namespace Sass { // get the resulting buffer from stream OutputBuffer emitted = emitter.get_buffer(); // should we append a source map url? - if (!c_options->omit_source_map_url) { + if (!c_options.omit_source_map_url) { // generate an embeded source map - if (c_options->source_map_embed) { + if (c_options.source_map_embed) { emitted.buffer += linefeed; emitted.buffer += format_embedded_source_map(); } @@ -592,7 +591,7 @@ namespace Sass { if (!source_c_str) return 0; // convert indented sass syntax - if(c_options->is_indented_syntax_src) { + if(c_options.is_indented_syntax_src) { // call sass2scss to convert the string char * converted = sass2scss(source_c_str, // preserve the structure as much as possible diff --git a/src/context.hpp b/src/context.hpp index 1628d5c675..964f431028 100644 --- a/src/context.hpp +++ b/src/context.hpp @@ -38,6 +38,7 @@ namespace Sass { public: const std::string CWD; + struct Sass_Options& c_options; std::string entry_path; size_t head_imports; Memory_Manager mem; @@ -53,7 +54,6 @@ namespace Sass { std::vector import_stack; struct Sass_Compiler* c_compiler; - struct Sass_Options* c_options; // absolute paths to includes std::vector included_files; @@ -86,7 +86,7 @@ namespace Sass { const std::string source_map_root; // path for sourceRoot property (pass-through) virtual ~Context(); - Context(struct Sass_Context*); + Context(struct Sass_Context&); virtual Block* parse() = 0; virtual Block* compile(); virtual char* render(Block* root); @@ -96,7 +96,7 @@ namespace Sass { std::vector find_includes(const Importer& import); Include load_import(const Importer&, ParserState pstate); - Sass_Output_Style output_style() { return c_options->output_style; }; + Sass_Output_Style output_style() { return c_options.output_style; }; std::vector get_included_files(bool skip = false, size_t headers = 0); private: @@ -119,7 +119,7 @@ namespace Sass { class File_Context : public Context { public: - File_Context(struct Sass_File_Context* ctx) + File_Context(struct Sass_File_Context& ctx) : Context(ctx) { } virtual ~File_Context(); @@ -130,13 +130,13 @@ namespace Sass { public: char* source_c_str; char* srcmap_c_str; - Data_Context(struct Sass_Data_Context* ctx) + Data_Context(struct Sass_Data_Context& ctx) : Context(ctx) { - source_c_str = ctx->source_string; - srcmap_c_str = ctx->srcmap_string; - ctx->source_string = 0; // passed away - ctx->srcmap_string = 0; // passed away + source_c_str = ctx.source_string; + srcmap_c_str = ctx.srcmap_string; + ctx.source_string = 0; // passed away + ctx.srcmap_string = 0; // passed away } virtual ~Data_Context(); virtual Block* parse(); diff --git a/src/cssize.cpp b/src/cssize.cpp index 72a9cae7f8..20d2bdb710 100644 --- a/src/cssize.cpp +++ b/src/cssize.cpp @@ -518,7 +518,7 @@ namespace Sass { Media_Query* Cssize::merge_media_query(Media_Query* mq1, Media_Query* mq2) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); std::string type; std::string mod; diff --git a/src/emitter.cpp b/src/emitter.cpp index 4c8b70aaf9..84e6753457 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -7,9 +7,9 @@ namespace Sass { - Emitter::Emitter(Context* ctx) + Emitter::Emitter(struct Sass_Output_Options& opt) : wbuf(), - ctx(ctx), + opt(opt), indentation(0), scheduled_space(0), scheduled_linefeed(0), @@ -20,8 +20,7 @@ namespace Sass { in_media_block(false), in_declaration(false), in_space_array(false), - in_comma_array(false), - in_debug(false) + in_comma_array(false) { } // return buffer as string @@ -30,9 +29,9 @@ namespace Sass { return wbuf.buffer; } - Sass_Output_Style Emitter::output_style(void) + Sass_Output_Style Emitter::output_style(void) const { - return ctx ? ctx->output_style() : SASS_STYLE_COMPRESSED; + return opt.output_style; } // PROXY METHODS FOR SOURCE MAPS @@ -46,11 +45,11 @@ namespace Sass { void Emitter::set_filename(const std::string& str) { wbuf.smap.file = str; } - void Emitter::schedule_mapping(AST_Node* node) + void Emitter::schedule_mapping(const AST_Node* node) { scheduled_mapping = node; } - void Emitter::add_open_mapping(AST_Node* node) + void Emitter::add_open_mapping(const AST_Node* node) { wbuf.smap.add_open_mapping(node); } - void Emitter::add_close_mapping(AST_Node* node) + void Emitter::add_close_mapping(const AST_Node* node) { wbuf.smap.add_close_mapping(node); } ParserState Emitter::remap(const ParserState& pstate) { return wbuf.smap.remap(pstate); } @@ -76,7 +75,7 @@ namespace Sass { std::string linefeeds = ""; for (size_t i = 0; i < scheduled_linefeed; i++) - linefeeds += ctx ? ctx->linefeed : "\n"; + linefeeds += opt.linefeed; scheduled_space = 0; scheduled_linefeed = 0; append_string(linefeeds); @@ -113,7 +112,7 @@ namespace Sass { // write space/lf flush_schedules(); - if (in_comment && output_style() == SASS_STYLE_COMPACT) { + if (in_comment && output_style() == COMPACT) { // unescape comment nodes std::string out = comment_to_string(text); // add to buffer @@ -140,7 +139,7 @@ namespace Sass { // append some text or token to the buffer // this adds source-mappings for node start and end - void Emitter::append_token(const std::string& text, AST_Node* node) + void Emitter::append_token(const std::string& text, const AST_Node* node) { flush_schedules(); add_open_mapping(node); @@ -158,27 +157,27 @@ namespace Sass { void Emitter::append_indentation() { - if (output_style() == SASS_STYLE_COMPRESSED) return; - if (output_style() == SASS_STYLE_COMPACT) return; + if (output_style() == COMPRESSED) return; + if (output_style() == COMPACT) return; if (in_declaration && in_comma_array) return; if (scheduled_linefeed && indentation) scheduled_linefeed = 1; std::string indent = ""; for (size_t i = 0; i < indentation; i++) - indent += ctx ? ctx->indent : " "; + indent += opt.indent; append_string(indent); } void Emitter::append_delimiter() { scheduled_delimiter = true; - if (output_style() == SASS_STYLE_COMPACT) { + if (output_style() == COMPACT) { if (indentation == 0) { append_mandatory_linefeed(); } else { append_mandatory_space(); } - } else if (output_style() != SASS_STYLE_COMPRESSED) { + } else if (output_style() != COMPRESSED) { append_optional_linefeed(); } } @@ -204,7 +203,7 @@ namespace Sass { void Emitter::append_optional_space() { - if ((output_style() != SASS_STYLE_COMPRESSED || in_debug) && buffer().size()) { + if ((output_style() != COMPRESSED) && buffer().size()) { char lst = buffer().at(buffer().length() - 1); if (!isspace(lst) || scheduled_delimiter) { append_mandatory_space(); @@ -214,17 +213,17 @@ namespace Sass { void Emitter::append_special_linefeed() { - if (output_style() == SASS_STYLE_COMPACT) { + if (output_style() == COMPACT) { append_mandatory_linefeed(); for (size_t p = 0; p < indentation; p++) - append_string(ctx ? ctx->indent : " "); + append_string(opt.indent); } } void Emitter::append_optional_linefeed() { if (in_declaration && in_comma_array) return; - if (output_style() == SASS_STYLE_COMPACT) { + if (output_style() == COMPACT) { append_mandatory_space(); } else { append_mandatory_linefeed(); @@ -233,7 +232,7 @@ namespace Sass { void Emitter::append_mandatory_linefeed() { - if (output_style() != SASS_STYLE_COMPRESSED) { + if (output_style() != COMPRESSED) { scheduled_linefeed = 1; scheduled_space = 0; // flush_schedules(); @@ -255,9 +254,9 @@ namespace Sass { { -- indentation; scheduled_linefeed = 0; - if (output_style() == SASS_STYLE_COMPRESSED) + if (output_style() == COMPRESSED) scheduled_delimiter = false; - if (output_style() == SASS_STYLE_EXPANDED) { + if (output_style() == EXPANDED) { append_optional_linefeed(); append_indentation(); } else { @@ -267,7 +266,7 @@ namespace Sass { if (node) add_close_mapping(node); append_optional_linefeed(); if (indentation != 0) return; - if (output_style() != SASS_STYLE_COMPRESSED) + if (output_style() != COMPRESSED) scheduled_linefeed = 2; } diff --git a/src/emitter.hpp b/src/emitter.hpp index 764044b181..dfaa28a0de 100644 --- a/src/emitter.hpp +++ b/src/emitter.hpp @@ -2,6 +2,7 @@ #define SASS_EMITTER_H #include +#include "sass.hpp" #include "sass/base.h" #include "source_map.hpp" #include "ast_fwd_decl.hpp" @@ -12,7 +13,7 @@ namespace Sass { class Emitter { public: - Emitter(Context* ctx); + Emitter(struct Sass_Output_Options& opt); virtual ~Emitter() { } protected: @@ -24,19 +25,19 @@ namespace Sass { // proxy methods for source maps void add_source_index(size_t idx); void set_filename(const std::string& str); - void add_open_mapping(AST_Node* node); - void add_close_mapping(AST_Node* node); - void schedule_mapping(AST_Node* node); + void add_open_mapping(const AST_Node* node); + void add_close_mapping(const AST_Node* node); + void schedule_mapping(const AST_Node* node); std::string render_srcmap(Context &ctx); ParserState remap(const ParserState& pstate); public: - Context* ctx; + struct Sass_Output_Options& opt; size_t indentation; size_t scheduled_space; size_t scheduled_linefeed; bool scheduled_delimiter; - AST_Node* scheduled_mapping; + const AST_Node* scheduled_mapping; public: // output strings different in comments @@ -50,14 +51,12 @@ namespace Sass { // nested lists need parentheses bool in_space_array; bool in_comma_array; - // list separators don't get compressed in @debug - bool in_debug; public: // return buffer as std::string std::string get_buffer(void); // flush scheduled space/linefeed - Sass_Output_Style output_style(void); + Sass_Output_Style output_style(void) const; // add outstanding linefeed void finalize(bool final = true); // flush scheduled space/linefeed @@ -71,7 +70,7 @@ namespace Sass { void append_wspace(const std::string& text); // append some text or token to the buffer // this adds source-mappings for node start and end - void append_token(const std::string& text, AST_Node* node); + void append_token(const std::string& text, const AST_Node* node); public: // syntax sugar void append_indentation(); diff --git a/src/error_handling.cpp b/src/error_handling.cpp index ec222db68f..86cdada41d 100644 --- a/src/error_handling.cpp +++ b/src/error_handling.cpp @@ -26,9 +26,9 @@ namespace Sass { : Base(selector->pstate()), parent(parent), selector(selector) { msg = "Invalid parent selector for \""; - msg += selector->to_string(false); + msg += selector->to_string(Sass_Inspect_Options()); msg += "\": \""; - msg += parent->to_string(false);; + msg += parent->to_string(Sass_Inspect_Options()); msg += "\""; } @@ -36,7 +36,7 @@ namespace Sass { : Base(pstate), fn(fn), arg(arg), type(type), value(value) { msg = arg + ": \""; - msg += value->to_string(true, 5); + msg += value->to_string(Sass_Inspect_Options()); msg += "\" is not a " + type; msg += " for `" + fn + "'"; } @@ -50,13 +50,13 @@ namespace Sass { { msg = def_op_msg + ": \""; if (const Value* l = dynamic_cast(lhs)) { - msg += l->to_string(); + msg += l->to_string({ NESTED, 5 }); } else if (lhs) { msg += "[EXPRESSION]"; } msg += " " + op + " "; if (const Value* r = dynamic_cast(rhs)) { - msg += r->to_string(); + msg += r->to_string({ NESTED, 5 }); } else if (rhs) { msg += "[EXPRESSION]"; } @@ -102,13 +102,13 @@ namespace Sass { { msg = "Alpha channels must be equal: "; if (const Value* l = dynamic_cast(lhs)) { - msg += l->to_string(); + msg += l->to_string({ NESTED, 5 }); } else if (lhs) { msg += "[EXPRESSION]"; } msg += " " + op + " "; if (const Value* r = dynamic_cast(rhs)) { - msg += r->to_string(); + msg += r->to_string({ NESTED, 5 }); } else if (rhs) { msg += "[EXPRESSION]"; } diff --git a/src/eval.cpp b/src/eval.cpp index fa42c42650..2258e6a2b9 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -42,8 +42,7 @@ namespace Sass { Eval::Eval(Expand& exp) : exp(exp), - ctx(exp.ctx), - listize(exp.ctx) + ctx(exp.ctx) { } Eval::~Eval() { } @@ -314,8 +313,10 @@ namespace Sass { Expression* Eval::operator()(Warning* w) { + Sass_Output_Style outstyle = ctx.c_options.output_style; + ctx.c_options.output_style = NESTED; Expression* message = w->message()->perform(this); - To_String to_string(&ctx); + To_String to_string(ctx.c_options); Env* env = exp.environment(); // try to use generic function @@ -331,6 +332,7 @@ namespace Sass { union Sass_Value* c_args = sass_make_list(1, SASS_COMMA); sass_list_set_value(c_args, 0, message->perform(&to_c)); union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler); + ctx.c_options.output_style = outstyle; sass_delete_value(c_args); sass_delete_value(c_val); return 0; @@ -340,15 +342,18 @@ namespace Sass { std::string result(unquote(message->perform(&to_string))); Backtrace top(backtrace(), w->pstate(), ""); std::cerr << "WARNING: " << result; - std::cerr << top.to_string(true); + std::cerr << top.to_string(); std::cerr << std::endl << std::endl; + ctx.c_options.output_style = outstyle; return 0; } Expression* Eval::operator()(Error* e) { + Sass_Output_Style outstyle = ctx.c_options.output_style; + ctx.c_options.output_style = NESTED; Expression* message = e->message()->perform(this); - To_String to_string(&ctx); + To_String to_string(ctx.c_options); Env* env = exp.environment(); // try to use generic function @@ -364,6 +369,7 @@ namespace Sass { union Sass_Value* c_args = sass_make_list(1, SASS_COMMA); sass_list_set_value(c_args, 0, message->perform(&to_c)); union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler); + ctx.c_options.output_style = outstyle; sass_delete_value(c_args); sass_delete_value(c_val); return 0; @@ -371,14 +377,17 @@ namespace Sass { } std::string result(unquote(message->perform(&to_string))); + ctx.c_options.output_style = outstyle; error(result, e->pstate()); return 0; } Expression* Eval::operator()(Debug* d) { + Sass_Output_Style outstyle = ctx.c_options.output_style; + ctx.c_options.output_style = NESTED; Expression* message = d->value()->perform(this); - To_String to_string(&ctx, false, true); + To_String to_string(ctx.c_options, false); Env* env = exp.environment(); // try to use generic function @@ -394,6 +403,7 @@ namespace Sass { union Sass_Value* c_args = sass_make_list(1, SASS_COMMA); sass_list_set_value(c_args, 0, message->perform(&to_c)); union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler); + ctx.c_options.output_style = outstyle; sass_delete_value(c_args); sass_delete_value(c_val); return 0; @@ -405,6 +415,7 @@ namespace Sass { std::string abs_path(Sass::File::rel2abs(d->pstate().path, cwd, cwd)); std::string rel_path(Sass::File::abs2rel(d->pstate().path, cwd, cwd)); std::string output_path(Sass::File::path_for_console(rel_path, abs_path, d->pstate().path)); + ctx.c_options.output_style = outstyle; std::cerr << output_path << ":" << d->pstate().line+1 << " DEBUG: " << result; std::cerr << std::endl; @@ -427,11 +438,11 @@ namespace Sass { *lm << std::make_pair(key, val); } if (lm->has_duplicate_key()) { - To_String to_string(&ctx); + To_String to_string({ INSPECT, 5 }, true); if (Color* col = dynamic_cast(lm->get_duplicate_key())) { - error("Duplicate key " + col->to_hex() + " in map (" + l->to_string() + ").", lm->pstate()); + error("Duplicate key " + col->to_hex({ INSPECT, 5 }) + " in map (" + l->to_string({ INSPECT, 5 }) + ").", lm->pstate()); } else { - error("Duplicate key \"" + lm->get_duplicate_key()->perform(&to_string) + "\" in map (" + l->to_string() + ").", lm->pstate()); + error("Duplicate key \"" + lm->get_duplicate_key()->perform(&to_string) + "\" in map (" + l->perform(&to_string) + ").", lm->pstate()); } } @@ -461,7 +472,7 @@ namespace Sass { // make sure we're not starting with duplicate keys. // the duplicate key state will have been set in the parser phase. if (m->has_duplicate_key()) { - To_String to_string(&ctx); + To_String to_string({ INSPECT, 5 }, false); error("Duplicate key \"" + m->get_duplicate_key()->perform(&to_string) + "\" in map " + m->perform(&to_string) + ".", m->pstate()); } @@ -476,7 +487,7 @@ namespace Sass { // check the evaluated keys aren't duplicates. if (mm->has_duplicate_key()) { - To_String to_string(&ctx); + To_String to_string({ INSPECT, 5 }, false); error("Duplicate key \"" + mm->get_duplicate_key()->perform(&to_string) + "\" in map " + m->perform(&to_string) + ".", mm->pstate()); } @@ -639,9 +650,6 @@ namespace Sass { Binary_Expression* b1 = dynamic_cast(b->left()); Binary_Expression* b2 = dynamic_cast(b->right()); - int precision = (int)ctx.c_options->precision; - bool compressed = ctx.output_style() == SASS_STYLE_COMPRESSED; - bool schema_op = false; bool force_delay = (s2 && s2->is_left_interpolant()) || @@ -689,11 +697,11 @@ namespace Sass { if (force_delay) { std::string str(""); - str += v_l->to_string(compressed, precision); + str += v_l->to_string(ctx.c_options); if (b->op().ws_before) str += " "; str += b->separator(); if (b->op().ws_after) str += " "; - str += v_r->to_string(compressed, precision); + str += v_r->to_string(ctx.c_options); String_Constant* val = SASS_MEMORY_NEW(ctx.mem, String_Constant, lhs->pstate(), str); val->is_interpolant(b->left()->has_interpolant()); return val; @@ -729,22 +737,22 @@ namespace Sass { if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) { const Number* l_n = dynamic_cast(lhs); const Number* r_n = dynamic_cast(rhs); - rv = op_numbers(ctx.mem, op_type, *l_n, *r_n, compressed, precision, &pstate); + rv = op_numbers(ctx.mem, op_type, *l_n, *r_n, ctx.c_options, &pstate); } else if (l_type == Expression::NUMBER && r_type == Expression::COLOR) { const Number* l_n = dynamic_cast(lhs); const Color* r_c = dynamic_cast(rhs); - rv = op_number_color(ctx.mem, op_type, *l_n, *r_c, compressed, precision, &pstate); + rv = op_number_color(ctx.mem, op_type, *l_n, *r_c, ctx.c_options, &pstate); } else if (l_type == Expression::COLOR && r_type == Expression::NUMBER) { const Color* l_c = dynamic_cast(lhs); const Number* r_n = dynamic_cast(rhs); - rv = op_color_number(ctx.mem, op_type, *l_c, *r_n, compressed, precision, &pstate); + rv = op_color_number(ctx.mem, op_type, *l_c, *r_n, ctx.c_options, &pstate); } else if (l_type == Expression::COLOR && r_type == Expression::COLOR) { const Color* l_c = dynamic_cast(lhs); const Color* r_c = dynamic_cast(rhs); - rv = op_colors(ctx.mem, op_type, *l_c, *r_c, compressed, precision, &pstate); + rv = op_colors(ctx.mem, op_type, *l_c, *r_c, ctx.c_options, &pstate); } else { To_Value to_value(ctx, ctx.mem); @@ -755,7 +763,7 @@ namespace Sass { b->is_interpolant(); if (op_type == Sass_OP::SUB) interpolant = false; // if (op_type == Sass_OP::DIV) interpolant = true; - Value* ex = op_strings(ctx.mem, b->op(), *v_l, *v_r, compressed, precision, &pstate, !interpolant); // pass true to compress + Value* ex = op_strings(ctx.mem, b->op(), *v_l, *v_r, ctx.c_options, &pstate, !interpolant); // pass true to compress if (String_Constant* str = dynamic_cast(ex)) { if (str->concrete_type() == Expression::STRING) @@ -804,7 +812,7 @@ namespace Sass { return result; } else { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); // Special cases: +/- variables which evaluate to null ouput just +/-, // but +/- null itself outputs the string if (operand->concrete_type() == Expression::NULL_VAL && dynamic_cast(u->operand())) { @@ -842,7 +850,7 @@ namespace Sass { c->pstate(), c->name(), args); - To_String to_string(&ctx); + To_String to_string(ctx.c_options); if (args->has_named_arguments()) { error("Function " + c->name() + " doesn't support keyword arguments", c->pstate()); } @@ -953,7 +961,7 @@ namespace Sass { Expression* Eval::operator()(Variable* v) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); std::string name(v->name()); Expression* value = 0; Env* env = environment(); @@ -1094,8 +1102,6 @@ namespace Sass { } void Eval::interpolation(Context& ctx, std::string& res, Expression* ex, bool into_quotes, bool was_itpl) { - int precision = (int)ctx.c_options->precision; - bool compressed = ctx.output_style() == SASS_STYLE_COMPRESSED; bool needs_closing_brace = false; if (Arguments* args = dynamic_cast(ex)) { @@ -1129,44 +1135,44 @@ namespace Sass { std::string rl(""); interpolation(ctx, rl, item, into_quotes, l->is_interpolant()); if (rl != "") *ll << SASS_MEMORY_NEW(ctx.mem, String_Quoted, item->pstate(), rl); } - To_String to_string(&ctx); - res += (ll->to_string(compressed, precision)); + To_String to_string(ctx.c_options); + res += (ll->to_string(ctx.c_options)); ll->is_interpolant(l->is_interpolant()); } else if (String_Quoted* val = dynamic_cast(ex)) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); if (into_quotes && val->is_interpolant()) { - res += evacuate_escapes(val->to_string(compressed, precision)); + res += evacuate_escapes(val->to_string(ctx.c_options)); // res += evacuate_escapes(val ? val->perform(&to_string) : ""); } else { - res += val->to_string(compressed, precision); + res += val->to_string(ctx.c_options); // res += val ? val->perform(&to_string) : ""; } } else if (String_Constant* val = dynamic_cast(ex)) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); if (into_quotes && val->is_interpolant()) { - res += evacuate_escapes(val->to_string(compressed, precision)); + res += evacuate_escapes(val->to_string(ctx.c_options)); // res += evacuate_escapes(val ? val->perform(&to_string) : ""); } else { val->quote_mark(0); - res += val->to_string(compressed, precision); + res += val->to_string(ctx.c_options); // res += val ? val->perform(&to_string) : ""; } } else if (Value* val = dynamic_cast(ex)) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); if (into_quotes && val->is_interpolant()) { - res += evacuate_escapes(val->to_string(compressed, precision)); + res += evacuate_escapes(val->to_string(ctx.c_options)); // res += evacuate_escapes(val ? val->perform(&to_string) : ""); } else { - res += val->to_string(compressed, precision); + res += val->to_string(ctx.c_options); // res += val ? val->perform(&to_string) : ""; } } else if (Textual* val = dynamic_cast(ex)) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); if (into_quotes && val->is_interpolant()) { res += evacuate_escapes(val ? val->perform(&to_string) : ""); @@ -1175,7 +1181,7 @@ namespace Sass { } } else if (Binary_Expression* val = dynamic_cast(ex)) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); if (into_quotes && val->is_interpolant()) { res += evacuate_escapes(val ? val->perform(&to_string) : ""); @@ -1185,7 +1191,7 @@ namespace Sass { } else if (Parent_Selector* pr = dynamic_cast(ex)) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); Expression* sel = pr->perform(this); if (into_quotes && sel->is_interpolant()) { res += evacuate_escapes(sel ? sel->perform(&to_string) : ""); @@ -1196,9 +1202,9 @@ namespace Sass { else if (Selector_List* sl = dynamic_cast(ex)) { if (into_quotes) { - res += evacuate_escapes(sl->to_string(compressed, precision)); + res += evacuate_escapes(sl->to_string(ctx.c_options)); } else { - res += sl->to_string(compressed, precision); + res += sl->to_string(ctx.c_options); } } else if (dynamic_cast(ex)) { @@ -1324,7 +1330,7 @@ namespace Sass { Expression* Eval::operator()(Media_Query* q) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); String* t = q->media_type(); t = static_cast(t ? t->perform(this) : 0); Media_Query* qq = SASS_MEMORY_NEW(ctx.mem, Media_Query, @@ -1478,7 +1484,7 @@ namespace Sass { return *l < *r; } - Value* Eval::op_numbers(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Number& r, bool compressed, int precision, ParserState* pstate) + Value* Eval::op_numbers(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Number& r, struct Sass_Inspect_Options opt, ParserState* pstate) { double lv = l.value(); double rv = r.value(); @@ -1529,7 +1535,7 @@ namespace Sass { return v; } - Value* Eval::op_number_color(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Color& rh, bool compressed, int precision, ParserState* pstate) + Value* Eval::op_number_color(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Color& rh, struct Sass_Inspect_Options opt, ParserState* pstate) { Color r(rh); double lv = l.value(); @@ -1546,10 +1552,10 @@ namespace Sass { case Sass_OP::SUB: case Sass_OP::DIV: { std::string sep(op == Sass_OP::SUB ? "-" : "/"); - std::string color(r.to_string(compressed, precision)); + std::string color(r.to_string(opt)); return SASS_MEMORY_NEW(mem, String_Quoted, pstate ? *pstate : l.pstate(), - l.to_string(compressed, precision) + l.to_string(opt) + sep + color); } break; @@ -1562,7 +1568,7 @@ namespace Sass { return SASS_MEMORY_NEW(mem, Color, rh); } - Value* Eval::op_color_number(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Number& r, bool compressed, int precision, ParserState* pstate) + Value* Eval::op_color_number(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Number& r, struct Sass_Inspect_Options opt, ParserState* pstate) { double rv = r.value(); if (op == Sass_OP::DIV && !rv) { @@ -1577,7 +1583,7 @@ namespace Sass { l.a()); } - Value* Eval::op_colors(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Color& r, bool compressed, int precision, ParserState* pstate) + Value* Eval::op_colors(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Color& r, struct Sass_Inspect_Options opt, ParserState* pstate) { if (l.a() != r.a()) { throw Exception::AlphaChannelsNotEqual(&l, &r, "+"); @@ -1594,7 +1600,7 @@ namespace Sass { l.a()); } - Value* Eval::op_strings(Memory_Manager& mem, Sass::Operand operand, Value& lhs, Value& rhs, bool compressed, int precision, ParserState* pstate, bool delayed) + Value* Eval::op_strings(Memory_Manager& mem, Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, ParserState* pstate, bool delayed) { Expression::Concrete_Type ltype = lhs.concrete_type(); Expression::Concrete_Type rtype = rhs.concrete_type(); @@ -1603,8 +1609,8 @@ namespace Sass { String_Quoted* lqstr = dynamic_cast(&lhs); String_Quoted* rqstr = dynamic_cast(&rhs); - std::string lstr(lqstr ? lqstr->value() : lhs.to_string(compressed, precision)); - std::string rstr(rqstr ? rqstr->value() : rhs.to_string(compressed, precision)); + std::string lstr(lqstr ? lqstr->value() : lhs.to_string(opt)); + std::string rstr(rqstr ? rqstr->value() : rhs.to_string(opt)); bool l_str_quoted = ((Sass::String*)&lhs) && ((Sass::String*)&lhs)->sass_fix_1291(); bool r_str_quoted = ((Sass::String*)&rhs) && ((Sass::String*)&rhs)->sass_fix_1291(); @@ -1614,27 +1620,27 @@ namespace Sass { if (l_str_color && r_str_color) { const Color* c_l = name_to_color(lstr); const Color* c_r = name_to_color(rstr); - return op_colors(mem, op,*c_l, *c_r, compressed, precision); + return op_colors(mem, op,*c_l, *c_r, opt); } else if (l_str_color && rtype == Expression::COLOR) { const Color* c_l = name_to_color(lstr); const Color* c_r = dynamic_cast(&rhs); - return op_colors(mem, op, *c_l, *c_r, compressed, precision); + return op_colors(mem, op, *c_l, *c_r, opt); } else if (ltype == Expression::COLOR && r_str_color) { const Color* c_l = dynamic_cast(&lhs); const Color* c_r = name_to_color(rstr); - return op_colors(mem, op, *c_l, *c_r, compressed, precision); + return op_colors(mem, op, *c_l, *c_r, opt); } else if (l_str_color && rtype == Expression::NUMBER) { const Color* c_l = name_to_color(lstr); const Number* n_r = dynamic_cast(&rhs); - return op_color_number(mem, op, *c_l, *n_r, compressed, precision); + return op_color_number(mem, op, *c_l, *n_r, opt); } else if (ltype == Expression::NUMBER && r_str_color) { const Number* n_l = dynamic_cast(&lhs); const Color* c_r = name_to_color(rstr); - return op_number_color(mem, op, *n_l, *c_r, compressed, precision); + return op_number_color(mem, op, *n_l, *c_r, opt); } if (ltype == Expression::NULL_VAL) throw Exception::InvalidNullOperation(&lhs, &rhs, sass_op_to_name(op)); if (rtype == Expression::NULL_VAL) throw Exception::InvalidNullOperation(&lhs, &rhs, sass_op_to_name(op)); diff --git a/src/eval.hpp b/src/eval.hpp index 614bac99df..08b8724a70 100644 --- a/src/eval.hpp +++ b/src/eval.hpp @@ -1,15 +1,15 @@ #ifndef SASS_EVAL_H #define SASS_EVAL_H +#include "ast.hpp" #include "context.hpp" -#include "listize.hpp" #include "operation.hpp" +#include "environment.hpp" namespace Sass { class Expand; class Context; - class Listize; class Eval : public Operation_CRTP { @@ -19,7 +19,6 @@ namespace Sass { public: Expand& exp; Context& ctx; - Listize listize; Eval(Expand& exp); ~Eval(); @@ -89,11 +88,11 @@ namespace Sass { static bool eq(Expression*, Expression*); static bool lt(Expression*, Expression*, std::string op); // -- arithmetic on the combinations that matter - static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, bool compressed = false, int precision = 5, ParserState* pstate = 0); - static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, bool compressed = false, int precision = 5, ParserState* pstate = 0); - static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, bool compressed = false, int precision = 5, ParserState* pstate = 0); - static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, bool compressed = false, int precision = 5, ParserState* pstate = 0); - static Value* op_strings(Memory_Manager&, Sass::Operand, Value&, Value&, bool compressed = false, int precision = 5, ParserState* pstate = 0, bool interpolant = false); + static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0); + static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0); + static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0); + static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0); + static Value* op_strings(Memory_Manager&, Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, ParserState* pstate = 0, bool interpolant = false); private: void interpolation(Context& ctx, std::string& res, Expression* ex, bool into_quotes, bool was_itpl = false); diff --git a/src/expand.cpp b/src/expand.cpp index e87dbaabec..16a89dcbd1 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -105,7 +105,7 @@ namespace Sass { while (tail) { if (tail->head()) for (Simple_Selector* header : tail->head()->elements()) { if (dynamic_cast(header) == NULL) continue; // skip all others - To_String to_string(&ctx); std::string sel_str(complex_selector->perform(&to_string)); + To_String to_string(ctx.c_options); std::string sel_str(complex_selector->perform(&to_string)); error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), backtrace()); } tail = tail->tail(); @@ -185,7 +185,7 @@ namespace Sass { Statement* Expand::operator()(Media_Block* m) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); Expression* mq = m->media_queries()->perform(&eval); mq = Parser::from_c_str(mq->perform(&to_string).c_str(), ctx, mq->pstate()).parse_media_queries(); Media_Block* mm = SASS_MEMORY_NEW(ctx.mem, Media_Block, @@ -558,7 +558,7 @@ namespace Sass { while (tail) { if (tail->head()) for (Simple_Selector* header : tail->head()->elements()) { if (dynamic_cast(header) == NULL) continue; // skip all others - To_String to_string(&ctx); std::string sel_str(complex_selector->perform(&to_string)); + To_String to_string(ctx.c_options); std::string sel_str(complex_selector->perform(&to_string)); error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), backtrace()); } tail = tail->tail(); @@ -572,7 +572,7 @@ namespace Sass { for (auto complex_sel : contextualized->elements()) { Complex_Selector* c = complex_sel; if (!c->head() || c->tail()) { - To_String to_string(&ctx); std::string sel_str(contextualized->perform(&to_string)); + To_String to_string(ctx.c_options); std::string sel_str(contextualized->perform(&to_string)); error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), backtrace()); } Compound_Selector* placeholder = c->head(); diff --git a/src/extend.cpp b/src/extend.cpp index 78184680a0..09d5d00aa2 100644 --- a/src/extend.cpp +++ b/src/extend.cpp @@ -1749,7 +1749,7 @@ namespace Sass { for (ExtensionPair ext : entries) { // check if both selectors have the same media block parent if (ext.first->media_block() == pComplexSelector->media_block()) continue; - To_String to_string(&ctx); + To_String to_string(ctx.c_options); if (ext.second->media_block() == 0) continue; if (pComplexSelector->media_block() && ext.second->media_block()->media_queries() && @@ -1918,7 +1918,7 @@ namespace Sass { */ Selector_List* Extend::extendSelectorList(Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool& extendedSomething) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); Selector_List* pNewSelectors = SASS_MEMORY_NEW(ctx.mem, Selector_List, pSelectorList->pstate(), pSelectorList->length()); @@ -2011,7 +2011,7 @@ namespace Sass { // Extend a ruleset by extending the selectors and updating them on the ruleset. The block's rules don't need to change. template static void extendObjectWithSelectorAndBlock(ObjectType* pObject, Context& ctx, ExtensionSubsetMap& subset_map) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); DEBUG_PRINTLN(EXTEND_OBJECT, "FOUND SELECTOR: " << static_cast(pObject->selector())->perform(&to_string)) @@ -2054,8 +2054,8 @@ namespace Sass { Complex_Selector* sel = it.first ? it.first->first() : NULL; Compound_Selector* ext = it.second ? it.second : NULL; if (ext && (ext->extended() || ext->is_optional())) continue; - std::string str_sel(sel->to_string()); - std::string str_ext(ext->to_string()); + std::string str_sel(sel->to_string({ NESTED, 5 })); + std::string str_ext(ext->to_string({ NESTED, 5 })); // debug_ast(sel, "sel: "); // debug_ast(ext, "ext: "); error("\"" + str_sel + "\" failed to @extend \"" + str_ext + "\".\n" diff --git a/src/functions.cpp b/src/functions.cpp index 6e1088c74c..4cd7cf5365 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -157,7 +157,7 @@ namespace Sass { template <> Selector_List* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) { - To_String to_string(&ctx, false); + To_String to_string(ctx.c_options, false); Expression* exp = ARG(argname, Expression); if (exp->concrete_type() == Expression::NULL_VAL) { std::stringstream msg; @@ -171,7 +171,7 @@ namespace Sass { template <> Complex_Selector* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) { - To_String to_string(&ctx, false); + To_String to_string(ctx.c_options, false); Expression* exp = ARG(argname, Expression); if (exp->concrete_type() == Expression::NULL_VAL) { std::stringstream msg; @@ -186,7 +186,7 @@ namespace Sass { template <> Compound_Selector* get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) { - To_String to_string(&ctx, false); + To_String to_string(ctx.c_options, false); Expression* exp = ARG(argname, Expression); if (exp->concrete_type() == Expression::NULL_VAL) { std::stringstream msg; @@ -313,9 +313,9 @@ namespace Sass { return SASS_MEMORY_NEW(ctx.mem, Color, pstate, - Sass::round(w1*color1->r() + w2*color2->r(), ctx.c_options->precision), - Sass::round(w1*color1->g() + w2*color2->g(), ctx.c_options->precision), - Sass::round(w1*color1->b() + w2*color2->b(), ctx.c_options->precision), + Sass::round(w1*color1->r() + w2*color2->r(), ctx.c_options.precision), + Sass::round(w1*color1->g() + w2*color2->g(), ctx.c_options.precision), + Sass::round(w1*color1->b() + w2*color2->b(), ctx.c_options.precision), color1->a()*p + color2->a()*(1-p)); } @@ -512,7 +512,7 @@ namespace Sass { // CSS3 filter function overload: pass literal through directly Number* amount = dynamic_cast(env["$amount"]); if (!amount) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "saturate(" + env["$color"]->perform(&to_string) + ")"); } @@ -573,7 +573,7 @@ namespace Sass { // CSS3 filter function overload: pass literal through directly Number* amount = dynamic_cast(env["$color"]); if (amount) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "grayscale(" + amount->perform(&to_string) + ")"); } @@ -610,7 +610,7 @@ namespace Sass { // CSS3 filter function overload: pass literal through directly Number* amount = dynamic_cast(env["$color"]); if (amount) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "invert(" + amount->perform(&to_string) + ")"); } @@ -638,7 +638,7 @@ namespace Sass { // CSS3 filter function overload: pass literal through directly Number* amount = dynamic_cast(env["$color"]); if (amount) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, "opacity(" + amount->perform(&to_string) + ")"); } @@ -856,10 +856,10 @@ namespace Sass { std::stringstream ss; ss << '#' << std::setw(2) << std::setfill('0'); - ss << std::hex << std::setw(2) << static_cast(Sass::round(a, ctx.c_options->precision)); - ss << std::hex << std::setw(2) << static_cast(Sass::round(r, ctx.c_options->precision)); - ss << std::hex << std::setw(2) << static_cast(Sass::round(g, ctx.c_options->precision)); - ss << std::hex << std::setw(2) << static_cast(Sass::round(b, ctx.c_options->precision)); + ss << std::hex << std::setw(2) << static_cast(Sass::round(a, ctx.c_options.precision)); + ss << std::hex << std::setw(2) << static_cast(Sass::round(r, ctx.c_options.precision)); + ss << std::hex << std::setw(2) << static_cast(Sass::round(g, ctx.c_options.precision)); + ss << std::hex << std::setw(2) << static_cast(Sass::round(b, ctx.c_options.precision)); std::string result(ss.str()); for (size_t i = 0, L = result.length(); i < L; ++i) { @@ -886,9 +886,12 @@ namespace Sass { return (Expression*) arg; } else { - To_String to_string(&ctx, false, true); + Sass_Output_Style oldstyle = ctx.c_options.output_style; + ctx.c_options.output_style = SASS_STYLE_NESTED; + To_String to_string(ctx.c_options, false); std::string val(arg->perform(&to_string)); val = dynamic_cast(arg) ? "null" : val; + ctx.c_options.output_style = oldstyle; deprecated_function("Passing " + val + ", a non-string value, to unquote()", pstate); return (Expression*) arg; @@ -898,7 +901,7 @@ namespace Sass { Signature quote_sig = "quote($string)"; BUILT_IN(sass_quote) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); AST_Node* arg = env["$string"]; std::string str(quote(arg->perform(&to_string), String_Constant::double_quote())); String_Quoted* result = SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, str); @@ -1090,7 +1093,7 @@ namespace Sass { Number* n = ARG("$number", Number); Number* r = SASS_MEMORY_NEW(ctx.mem, Number, *n); r->pstate(pstate); - r->value(Sass::round(r->value(), ctx.c_options->precision)); + r->value(Sass::round(r->value(), ctx.c_options.precision)); return r; } @@ -1127,7 +1130,7 @@ namespace Sass { Signature min_sig = "min($numbers...)"; BUILT_IN(min) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); List* arglist = ARG("$numbers", List); Number* least = 0; for (size_t i = 0, L = arglist->length(); i < L; ++i) { @@ -1146,7 +1149,7 @@ namespace Sass { Signature max_sig = "max($numbers...)"; BUILT_IN(max) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); List* arglist = ARG("$numbers", List); Number* greatest = 0; for (size_t i = 0, L = arglist->length(); i < L; ++i) { @@ -1241,7 +1244,7 @@ namespace Sass { double index = std::floor(n->value() < 0 ? len + n->value() : n->value() - 1); if (index < 0 || index > len - 1) error("index out of bounds for `" + std::string(sig) + "`", pstate); // return (*sl)[static_cast(index)]; - Listize listize(ctx); + Listize listize(ctx.mem); return (*sl)[static_cast(index)]->perform(&listize); } List* l = dynamic_cast(env["$list"]); @@ -1336,7 +1339,7 @@ namespace Sass { List* l = dynamic_cast(env["$list"]); Expression* v = ARG("$val", Expression); if (Selector_List* sl = dynamic_cast(env["$list"])) { - Listize listize(ctx); + Listize listize(ctx.mem); l = dynamic_cast(sl->perform(&listize)); } String_Constant* sep = ARG("$separator", String_Constant); @@ -1686,12 +1689,12 @@ namespace Sass { bool parentheses = v->concrete_type() == Expression::MAP || v->concrete_type() == Expression::LIST; Sass_Output_Style old_style; - old_style = ctx.c_options->output_style; - ctx.c_options->output_style = SASS_STYLE_NESTED; - To_String to_string(&ctx, false); + old_style = ctx.c_options.output_style; + ctx.c_options.output_style = NESTED; + To_String to_string(ctx.c_options, false); std::string inspect = v->perform(&to_string); if (inspect.empty() && parentheses) inspect = "()"; - ctx.c_options->output_style = old_style; + ctx.c_options.output_style = old_style; return SASS_MEMORY_NEW(ctx.mem, String_Quoted, pstate, inspect); } // return v; @@ -1699,7 +1702,7 @@ namespace Sass { Signature selector_nest_sig = "selector-nest($selectors...)"; BUILT_IN(selector_nest) { - To_String to_string(&ctx, false); + To_String to_string(ctx.c_options, false); List* arglist = ARG("$selectors", List); // Not enough parameters @@ -1741,7 +1744,7 @@ namespace Sass { result->elements(exploded); } - Listize listize(ctx); + Listize listize(ctx.mem); return result->perform(&listize); } @@ -1833,7 +1836,7 @@ namespace Sass { result->elements(newElements); } - Listize listize(ctx); + Listize listize(ctx.mem); return result->perform(&listize); } @@ -1844,7 +1847,7 @@ namespace Sass { Selector_List* selector2 = ARGSEL("$selector2", Selector_List, p_contextualize); Selector_List* result = selector1->unify_with(selector2, ctx); - Listize listize(ctx); + Listize listize(ctx.mem); return result->perform(&listize); } @@ -1879,7 +1882,7 @@ namespace Sass { bool extendedSomething; Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, false, extendedSomething); - Listize listize(ctx); + Listize listize(ctx.mem); return result->perform(&listize); } @@ -1896,7 +1899,7 @@ namespace Sass { bool extendedSomething; Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, true, extendedSomething); - Listize listize(ctx); + Listize listize(ctx.mem); return result->perform(&listize); } @@ -1905,14 +1908,14 @@ namespace Sass { { Selector_List* sel = ARGSEL("$selector", Selector_List, p_contextualize); - Listize listize(ctx); + Listize listize(ctx.mem); return sel->perform(&listize); } Signature is_superselector_sig = "is-superselector($super, $sub)"; BUILT_IN(is_superselector) { - To_String to_string(&ctx, false); + To_String to_string(ctx.c_options, false); Selector_List* sel_sup = ARGSEL("$super", Selector_List, p_contextualize); Selector_List* sel_sub = ARGSEL("$sub", Selector_List, p_contextualize); bool result = sel_sup->is_superselector_of(sel_sub); diff --git a/src/functions.hpp b/src/functions.hpp index a0b78341d1..66c6b7bca0 100644 --- a/src/functions.hpp +++ b/src/functions.hpp @@ -1,6 +1,7 @@ #ifndef SASS_FUNCTIONS_H #define SASS_FUNCTIONS_H +#include "listize.hpp" #include "position.hpp" #include "environment.hpp" #include "sass/functions.h" diff --git a/src/inspect.cpp b/src/inspect.cpp index 628731468f..f82e70c990 100644 --- a/src/inspect.cpp +++ b/src/inspect.cpp @@ -27,11 +27,11 @@ namespace Sass { add_open_mapping(block); append_scope_opener(); } - if (output_style() == SASS_STYLE_NESTED) indentation += block->tabs(); + if (output_style() == NESTED) indentation += block->tabs(); for (size_t i = 0, L = block->length(); i < L; ++i) { (*block)[i]->perform(this); } - if (output_style() == SASS_STYLE_NESTED) indentation -= block->tabs(); + if (output_style() == NESTED) indentation -= block->tabs(); if (!block->is_root()) { append_scope_closer(); add_close_mapping(block); @@ -124,14 +124,15 @@ namespace Sass { if (dec->value()->concrete_type() == Expression::NULL_VAL) return; bool was_decl = in_declaration; in_declaration = true; - if (output_style() == SASS_STYLE_NESTED) + if (output_style() == NESTED) indentation += dec->tabs(); append_indentation(); dec->property()->perform(this); append_colon_separator(); if (dec->value()->concrete_type() == Expression::SELECTOR) { - Listize listize(*ctx); + Memory_Manager mem; + Listize listize(mem); dec->value()->perform(&listize)->perform(this); } else { dec->value()->perform(this); @@ -142,7 +143,7 @@ namespace Sass { append_string("!important"); } append_delimiter(); - if (output_style() == SASS_STYLE_NESTED) + if (output_style() == NESTED) indentation -= dec->tabs(); in_declaration = was_decl; } @@ -364,7 +365,7 @@ namespace Sass { void Inspect::operator()(List* list) { std::string sep(list->separator() == SASS_SPACE ? " " : ","); - if ((output_style() != SASS_STYLE_COMPRESSED || in_debug) && sep == ",") sep += " "; + if ((output_style() != COMPRESSED) && sep == ",") sep += " "; else if (in_media_block && sep != " ") sep += " "; // verified if (list->empty()) return; bool items_output = false; @@ -411,7 +412,8 @@ namespace Sass { void Inspect::operator()(Binary_Expression* expr) { expr->left()->perform(this); - if ( in_media_block || ( + if ( in_media_block || + (output_style() == INSPECT) || ( expr->op().ws_before && (!expr->is_interpolant()) && (!expr->is_delayed() || @@ -436,7 +438,8 @@ namespace Sass { case Sass_OP::MOD: append_string("%"); break; default: break; // shouldn't get here } - if ( in_media_block || ( + if ( in_media_block || + (output_style() == INSPECT) || ( expr->op().ws_after && (!expr->is_interpolant()) && (!expr->is_delayed() @@ -478,29 +481,20 @@ namespace Sass { void Inspect::operator()(Number* n) { - // use values to_string facility - bool compressed = ctx->output_style() == SASS_STYLE_COMPRESSED; - std::string res(n->to_string(compressed, (int)ctx->c_options->precision)); // output the final token - append_token(res, n); + append_token(n->to_string(opt), n); } void Inspect::operator()(Color* c) { - // use values to_string facility - bool compressed = ctx->output_style() == SASS_STYLE_COMPRESSED; - std::string res(c->to_string(compressed, (int)ctx->c_options->precision)); // output the final token - append_token(res, c); + append_token(c->to_string(opt), c); } void Inspect::operator()(Boolean* b) { - // use values to_string facility - bool compressed = ctx->output_style() == SASS_STYLE_COMPRESSED; - std::string res(b->to_string(compressed, (int)ctx->c_options->precision)); // output the final token - append_token(res, b); + append_token(b->to_string(opt), b); } void Inspect::operator()(String_Schema* ss) @@ -516,24 +510,14 @@ namespace Sass { void Inspect::operator()(String_Constant* s) { - // get options from optional? context - int precision = ctx ? (int)ctx->c_options->precision : 5; - bool compressed = ctx ? ctx->output_style() == SASS_STYLE_COMPRESSED : false; - // use values to_string facility - std::string res(s->to_string(compressed, precision)); // output the final token - append_token(res, s); + append_token(s->to_string(opt), s); } void Inspect::operator()(String_Quoted* s) { - // get options from optional? context - int precision = ctx ? (int)ctx->c_options->precision : 5; - bool compressed = ctx ? ctx->output_style() == SASS_STYLE_COMPRESSED : false; - // use values to_string facility - std::string res(s->to_string(compressed, precision)); // output the final token - append_token(res, s); + append_token(s->to_string(opt), s); } void Inspect::operator()(Supports_Operator* so) { @@ -631,11 +615,8 @@ namespace Sass { void Inspect::operator()(Null* n) { - // use values to_string facility - bool compressed = output_style() == SASS_STYLE_COMPRESSED; - std::string res(n->to_string(compressed, (int)ctx->c_options->precision)); // output the final token - append_token(res, n); + append_token(n->to_string(opt), n); } // parameters and arguments @@ -772,7 +753,7 @@ namespace Sass { (*s)[i]->perform(this); } if (s->has_line_break()) { - if (output_style() != SASS_STYLE_COMPACT) { + if (output_style() != COMPACT) { append_optional_linefeed(); } } @@ -794,7 +775,7 @@ namespace Sass { if (head && head->length() != 0) head->perform(this); bool is_empty = !head || head->length() == 0 || head->is_empty_reference(); bool is_tail = head && !head->is_empty_reference() && tail; - if (output_style() == SASS_STYLE_COMPRESSED && comb != Complex_Selector::ANCESTOR_OF) scheduled_space = 0; + if (output_style() == COMPRESSED && comb != Complex_Selector::ANCESTOR_OF) scheduled_space = 0; switch (comb) { case Complex_Selector::ANCESTOR_OF: @@ -830,7 +811,7 @@ namespace Sass { } if (tail) tail->perform(this); if (!tail && c->has_line_break()) { - if (output_style() == SASS_STYLE_COMPACT) { + if (output_style() == COMPACT) { append_mandatory_space(); } } diff --git a/src/listize.cpp b/src/listize.cpp index 8459c4d164..e6fae67a1c 100644 --- a/src/listize.cpp +++ b/src/listize.cpp @@ -11,19 +11,19 @@ namespace Sass { - Listize::Listize(Context& ctx) - : ctx(ctx) + Listize::Listize(Memory_Manager& mem) + : mem(mem) { } Expression* Listize::operator()(Selector_List* sel) { - List* l = SASS_MEMORY_NEW(ctx.mem, List, sel->pstate(), sel->length(), SASS_COMMA); + List* l = SASS_MEMORY_NEW(mem, List, sel->pstate(), sel->length(), SASS_COMMA); for (size_t i = 0, L = sel->length(); i < L; ++i) { if (!(*sel)[i]) continue; *l << (*sel)[i]->perform(this); } if (l->length()) return l; - return SASS_MEMORY_NEW(ctx.mem, Null, l->pstate()); + return SASS_MEMORY_NEW(mem, Null, l->pstate()); } Expression* Listize::operator()(Compound_Selector* sel) @@ -34,12 +34,12 @@ namespace Sass { Expression* e = (*sel)[i]->perform(this); if (e) str += e->perform(&to_string); } - return SASS_MEMORY_NEW(ctx.mem, String_Quoted, sel->pstate(), str); + return SASS_MEMORY_NEW(mem, String_Quoted, sel->pstate(), str); } Expression* Listize::operator()(Complex_Selector* sel) { - List* l = SASS_MEMORY_NEW(ctx.mem, List, sel->pstate(), 2); + List* l = SASS_MEMORY_NEW(mem, List, sel->pstate(), 2); Compound_Selector* head = sel->head(); if (head && !head->is_empty_reference()) @@ -54,16 +54,16 @@ namespace Sass { switch(sel->combinator()) { case Complex_Selector::PARENT_OF: - *l << SASS_MEMORY_NEW(ctx.mem, String_Quoted, sel->pstate(), ">"); + *l << SASS_MEMORY_NEW(mem, String_Quoted, sel->pstate(), ">"); break; case Complex_Selector::ADJACENT_TO: - *l << SASS_MEMORY_NEW(ctx.mem, String_Quoted, sel->pstate(), "+"); + *l << SASS_MEMORY_NEW(mem, String_Quoted, sel->pstate(), "+"); break; case Complex_Selector::REFERENCE: - *l << SASS_MEMORY_NEW(ctx.mem, String_Quoted, sel->pstate(), "/" + reference + "/"); + *l << SASS_MEMORY_NEW(mem, String_Quoted, sel->pstate(), "/" + reference + "/"); break; case Complex_Selector::PRECEDES: - *l << SASS_MEMORY_NEW(ctx.mem, String_Quoted, sel->pstate(), "~"); + *l << SASS_MEMORY_NEW(mem, String_Quoted, sel->pstate(), "~"); break; case Complex_Selector::ANCESTOR_OF: break; diff --git a/src/listize.hpp b/src/listize.hpp index 4a34e9b306..cd6ef54207 100644 --- a/src/listize.hpp +++ b/src/listize.hpp @@ -16,12 +16,12 @@ namespace Sass { class Listize : public Operation_CRTP { - Context& ctx; + Memory_Manager& mem; Expression* fallback_impl(AST_Node* n); public: - Listize(Context&); + Listize(Memory_Manager&); ~Listize() { } Expression* operator()(Selector_List*); diff --git a/src/output.cpp b/src/output.cpp index 1c071d0e3d..dbbb3d8b8d 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -5,8 +5,8 @@ namespace Sass { - Output::Output(Context* ctx) - : Inspect(Emitter(ctx)), + Output::Output(Sass_Output_Options& opt) + : Inspect(Emitter(opt)), charset(""), top_nodes(0) {} @@ -21,7 +21,7 @@ namespace Sass { void Output::operator()(Number* n) { // use values to_string facility - To_String to_string(ctx); + To_String to_string(opt); std::string res = n->perform(&to_string); // check for a valid unit here // includes result for reporting @@ -43,7 +43,7 @@ namespace Sass { void Output::operator()(Map* m) { - To_String to_string(ctx); + To_String to_string(opt); std::string dbg(m->perform(&to_string)); error(dbg + " isn't a valid CSS value.", m->pstate()); } @@ -51,7 +51,7 @@ namespace Sass { OutputBuffer Output::get_buffer(void) { - Emitter emitter(ctx); + Emitter emitter(opt); Inspect inspect(emitter); size_t size_nodes = top_nodes.size(); @@ -66,9 +66,9 @@ namespace Sass { // prepend buffer on top prepend_output(inspect.output()); // make sure we end with a linefeed - if (!ends_with(wbuf.buffer, ctx->linefeed)) { + if (!ends_with(wbuf.buffer, opt.linefeed)) { // if the output is not completely empty - if (!wbuf.buffer.empty()) append_string(ctx->linefeed); + if (!wbuf.buffer.empty()) append_string(opt.linefeed); } // search for unicode char @@ -76,9 +76,9 @@ namespace Sass { // skip all ascii chars if (chr >= 0) continue; // declare the charset - if (output_style() != SASS_STYLE_COMPRESSED) + if (output_style() != COMPRESSED) charset = "@charset \"UTF-8\";" - + ctx->linefeed; + + std::string(opt.linefeed); else charset = "\xEF\xBB\xBF"; // abort search break; @@ -93,11 +93,11 @@ namespace Sass { void Output::operator()(Comment* c) { - To_String to_string(ctx); + To_String to_string(opt); std::string txt = c->text()->perform(&to_string); // if (indentation && txt == "/**/") return; bool important = c->is_important(); - if (output_style() != SASS_STYLE_COMPRESSED || important) { + if (output_style() != COMPRESSED || important) { if (buffer().size() == 0) { top_nodes.push_back(c); } else { @@ -133,8 +133,8 @@ namespace Sass { if (b->has_non_hoistable()) { decls = true; - if (output_style() == SASS_STYLE_NESTED) indentation += r->tabs(); - if (ctx && ctx->c_options->source_comments) { + if (output_style() == NESTED) indentation += r->tabs(); + if (opt.source_comments) { std::stringstream ss; append_indentation(); ss << "/* line " << r->pstate().line + 1 << ", " << r->pstate().path << " */"; @@ -173,7 +173,7 @@ namespace Sass { stm->perform(this); } } - if (output_style() == SASS_STYLE_NESTED) indentation -= r->tabs(); + if (output_style() == NESTED) indentation -= r->tabs(); append_scope_closer(b); } @@ -240,7 +240,7 @@ namespace Sass { return; } - if (output_style() == SASS_STYLE_NESTED) indentation += f->tabs(); + if (output_style() == NESTED) indentation += f->tabs(); append_indentation(); append_token("@supports", f); append_mandatory_space(); @@ -276,7 +276,7 @@ namespace Sass { } } - if (output_style() == SASS_STYLE_NESTED) indentation -= f->tabs(); + if (output_style() == NESTED) indentation -= f->tabs(); append_scope_closer(); @@ -299,7 +299,7 @@ namespace Sass { } return; } - if (output_style() == SASS_STYLE_NESTED) indentation += m->tabs(); + if (output_style() == NESTED) indentation += m->tabs(); append_indentation(); append_token("@media", m); append_mandatory_space(); @@ -313,7 +313,7 @@ namespace Sass { if (i < L - 1) append_special_linefeed(); } - if (output_style() == SASS_STYLE_NESTED) indentation -= m->tabs(); + if (output_style() == NESTED) indentation -= m->tabs(); append_scope_closer(); } @@ -383,7 +383,7 @@ namespace Sass { void Output::operator()(String_Constant* s) { std::string value(s->value()); - if (s->can_compress_whitespace() && output_style() == SASS_STYLE_COMPRESSED) { + if (s->can_compress_whitespace() && output_style() == COMPRESSED) { value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end()); } if (!in_comment) { diff --git a/src/output.hpp b/src/output.hpp index 7163e8ea54..8dd150b59d 100644 --- a/src/output.hpp +++ b/src/output.hpp @@ -23,8 +23,7 @@ namespace Sass { using Inspect::operator(); public: - // change to Emitter - Output(Context* ctx); + Output(Sass_Output_Options& opt); virtual ~Output(); protected: diff --git a/src/parser.cpp b/src/parser.cpp index d918ae92c4..71b0f4d889 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -591,7 +591,7 @@ namespace Sass { bool reloop = true; bool had_linefeed = false; Complex_Selector* sel = 0; - To_String to_string(&ctx); + To_String to_string(ctx.c_options); Selector_List* group = SASS_MEMORY_NEW(ctx.mem, Selector_List, pstate); group->media_block(last_media_block); @@ -753,8 +753,8 @@ namespace Sass { ParserState state(pstate); Simple_Selector* cur = (*seq)[seq->length()-1]; Simple_Selector* prev = (*seq)[seq->length()-2]; - std::string sel(prev->to_string(false, 5)); - std::string found(cur->to_string(false, 5)); + std::string sel(prev->to_string({ NESTED, 5 })); + std::string found(cur->to_string({ NESTED, 5 })); if (lex < identifier >()) { found += std::string(lexed); } error("Invalid CSS after \"" + sel + "\": expected \"{\", was \"" + found + "\"\n\n" "\"" + found + "\" may only be used at the beginning of a compound selector.", state); @@ -1777,7 +1777,7 @@ namespace Sass { (*res) << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, suffix); return res; } else { - std::string res = prefix + url_string->to_string() + suffix; + std::string res = prefix + url_string->to_string({ NESTED, 5 }) + suffix; return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, res); } } diff --git a/src/sass.hpp b/src/sass.hpp index 44eff9ac8d..7d5b063724 100644 --- a/src/sass.hpp +++ b/src/sass.hpp @@ -41,4 +41,88 @@ # endif #endif + +// include C-API header +#include "sass/base.h" + +// output behaviours +namespace Sass { + + // create some C++ aliases for the most used options + const static Sass_Output_Style NESTED = SASS_STYLE_NESTED; + const static Sass_Output_Style COMPACT = SASS_STYLE_COMPACT; + const static Sass_Output_Style EXPANDED = SASS_STYLE_EXPANDED; + const static Sass_Output_Style COMPRESSED = SASS_STYLE_COMPRESSED; + // only used internal to trigger ruby inspect behavior + const static Sass_Output_Style INSPECT = SASS_STYLE_INSPECT; + +}; + +// input behaviours +enum Sass_Input_Style { + SASS_CONTEXT_NULL, + SASS_CONTEXT_FILE, + SASS_CONTEXT_DATA, + SASS_CONTEXT_FOLDER +}; + +// simple linked list +struct string_list { + string_list* next; + char* string; +}; + +// sass config options structure +struct Sass_Inspect_Options { + + // Output style for the generated css code + // A value from above SASS_STYLE_* constants + enum Sass_Output_Style output_style; + + // Precision for fractional numbers + int precision; + + // initialization list (constructor with defaults) + Sass_Inspect_Options(Sass_Output_Style style = Sass::NESTED, + int precision = 5) + : output_style(style), precision(precision) + { } + +}; + +// sass config options structure +struct Sass_Output_Options : Sass_Inspect_Options { + + // String to be used for indentation + const char* indent; + // String to be used to for line feeds + const char* linefeed; + + // Emit comments in the generated CSS indicating + // the corresponding source line. + bool source_comments; + + // initialization list (constructor with defaults) + Sass_Output_Options(struct Sass_Inspect_Options opt, + const char* indent = " ", + const char* linefeed = "\n", + bool source_comments = false) + : Sass_Inspect_Options(opt), + indent(indent), linefeed(linefeed), + source_comments(source_comments) + { } + + // initialization list (constructor with defaults) + Sass_Output_Options(Sass_Output_Style style = Sass::NESTED, + int precision = 5, + const char* indent = " ", + const char* linefeed = "\n", + bool source_comments = false) + : Sass_Inspect_Options(style, precision), + indent(indent), linefeed(linefeed), + source_comments(source_comments) + { } + +}; + #endif diff --git a/src/sass_context.cpp b/src/sass_context.cpp index 26527fb932..84b63928d4 100644 --- a/src/sass_context.cpp +++ b/src/sass_context.cpp @@ -410,14 +410,14 @@ extern "C" { struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx) { if (data_ctx == 0) return 0; - Context* cpp_ctx = new Data_Context(data_ctx); + Context* cpp_ctx = new Data_Context(*data_ctx); return sass_prepare_context(data_ctx, cpp_ctx); } struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_Context* file_ctx) { if (file_ctx == 0) return 0; - Context* cpp_ctx = new File_Context(file_ctx); + Context* cpp_ctx = new File_Context(*file_ctx); return sass_prepare_context(file_ctx, cpp_ctx); } @@ -432,7 +432,7 @@ extern "C" { // if (*data_ctx->source_string == 0) { throw(std::runtime_error("Data context has empty source string")); } } catch (...) { return handle_errors(data_ctx) | 1; } - Context* cpp_ctx = new Data_Context(data_ctx); + Context* cpp_ctx = new Data_Context(*data_ctx); return sass_compile_context(data_ctx, cpp_ctx); } @@ -446,7 +446,7 @@ extern "C" { if (*file_ctx->input_path == 0) { throw(std::runtime_error("File context has empty input path")); } } catch (...) { return handle_errors(file_ctx) | 1; } - Context* cpp_ctx = new File_Context(file_ctx); + Context* cpp_ctx = new File_Context(*file_ctx); return sass_compile_context(file_ctx, cpp_ctx); } diff --git a/src/sass_context.hpp b/src/sass_context.hpp index a09086639e..fcbb764b47 100644 --- a/src/sass_context.hpp +++ b/src/sass_context.hpp @@ -2,36 +2,12 @@ #define SASS_SASS_CONTEXT_H #include "sass.h" +#include "sass.hpp" #include "context.hpp" #include "ast_fwd_decl.hpp" -// Input behaviours -enum Sass_Input_Style { - SASS_CONTEXT_NULL, - SASS_CONTEXT_FILE, - SASS_CONTEXT_DATA, - SASS_CONTEXT_FOLDER -}; - -// simple linked list -struct string_list { - string_list* next; - char* string; -}; - // sass config options structure -struct Sass_Options { - - // Precision for fractional numbers - int precision; - - // Output style for the generated css code - // A value from above SASS_STYLE_* constants - enum Sass_Output_Style output_style; - - // Emit comments in the generated CSS indicating - // the corresponding source line. - bool source_comments; +struct Sass_Options : Sass_Output_Options { // embed sourceMappingUrl as data uri bool source_map_embed; @@ -59,11 +35,6 @@ struct Sass_Options { // information in source-maps etc. char* output_path; - // String to be used for indentation - const char* indent; - // String to be used to for line feeds - const char* linefeed; - // Colon-separated list of paths // Semicolon-separated on Windows // Maybe use array interface instead? diff --git a/src/sass_interface.cpp b/src/sass_interface.cpp index 1de738a308..f5f44a1284 100644 --- a/src/sass_interface.cpp +++ b/src/sass_interface.cpp @@ -70,9 +70,8 @@ extern "C" { else { output_path = c_ctx->output_path; } - Data_Context cpp_ctx( - (Sass_Data_Context*) 0 - ); + struct Sass_Data_Context opt; + Data_Context cpp_ctx(opt); if (c_ctx->c_functions) { Sass_Function_List this_func_data = c_ctx->c_functions; while ((this_func_data) && (*this_func_data)) { @@ -146,9 +145,8 @@ extern "C" { else { output_path = c_ctx->output_path; } - File_Context cpp_ctx( - (Sass_File_Context*) 0 - ); + struct Sass_File_Context opt; + File_Context cpp_ctx(opt); if (c_ctx->c_functions) { Sass_Function_List this_func_data = c_ctx->c_functions; while ((this_func_data) && (*this_func_data)) { diff --git a/src/sass_util.cpp b/src/sass_util.cpp index 5a770effb8..a9277a80fc 100644 --- a/src/sass_util.cpp +++ b/src/sass_util.cpp @@ -39,7 +39,7 @@ namespace Sass { end */ Node paths(const Node& arrs, Context& ctx) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); Node loopStart = Node::createCollection(); loopStart.collection()->push_back(Node::createCollection()); diff --git a/src/sass_values.cpp b/src/sass_values.cpp index be30615b37..e5430a008d 100644 --- a/src/sass_values.cpp +++ b/src/sass_values.cpp @@ -277,7 +277,8 @@ extern "C" { { Memory_Manager mem; Value* val = sass_value_to_ast_node(mem, v); - std::string str(val->to_string(compressed, precision)); + Sass_Inspect_Options options(compressed ? COMPRESSED : NESTED, precision); + std::string str(val->to_string(options)); return sass_make_qstring(str.c_str()); } @@ -291,6 +292,7 @@ extern "C" { Value* lhs = sass_value_to_ast_node(mem, a); Value* rhs = sass_value_to_ast_node(mem, b); + struct Sass_Inspect_Options options(NESTED, 5); // see if it's a relational expression switch(op) { @@ -306,27 +308,27 @@ extern "C" { if (sass_value_is_number(a) && sass_value_is_number(b)) { const Number* l_n = dynamic_cast(lhs); const Number* r_n = dynamic_cast(rhs); - rv = Eval::op_numbers(mem, op, *l_n, *r_n); + rv = Eval::op_numbers(mem, op, *l_n, *r_n, options); } else if (sass_value_is_number(a) && sass_value_is_color(a)) { const Number* l_n = dynamic_cast(lhs); const Color* r_c = dynamic_cast(rhs); - rv = Eval::op_number_color(mem, op, *l_n, *r_c); + rv = Eval::op_number_color(mem, op, *l_n, *r_c, options); } else if (sass_value_is_color(a) && sass_value_is_number(b)) { const Color* l_c = dynamic_cast(lhs); const Number* r_n = dynamic_cast(rhs); - rv = Eval::op_color_number(mem, op, *l_c, *r_n); + rv = Eval::op_color_number(mem, op, *l_c, *r_n, options); } else if (sass_value_is_color(a) && sass_value_is_color(b)) { const Color* l_c = dynamic_cast(lhs); const Color* r_c = dynamic_cast(rhs); - rv = Eval::op_colors(mem, op, *l_c, *r_c); + rv = Eval::op_colors(mem, op, *l_c, *r_c, options); } else /* convert other stuff to string and apply operation */ { Value* l_v = dynamic_cast(lhs); Value* r_v = dynamic_cast(rhs); - rv = Eval::op_strings(mem, op, *l_v, *r_v); + rv = Eval::op_strings(mem, op, *l_v, *r_v, options); } // ToDo: maybe we should should return null value? diff --git a/src/source_map.cpp b/src/source_map.cpp index 44f8defe01..b5f7abbc7e 100644 --- a/src/source_map.cpp +++ b/src/source_map.cpp @@ -17,7 +17,7 @@ namespace Sass { std::string SourceMap::render_srcmap(Context &ctx) { - const bool include_sources = ctx.c_options->source_map_contents; + const bool include_sources = ctx.c_options.source_map_contents; const std::vector links = ctx.srcmap_links; const std::vector& sources(ctx.resources); @@ -160,12 +160,12 @@ namespace Sass { current_position += offset; } - void SourceMap::add_open_mapping(AST_Node* node) + void SourceMap::add_open_mapping(const AST_Node* node) { mappings.push_back(Mapping(node->pstate(), current_position)); } - void SourceMap::add_close_mapping(AST_Node* node) + void SourceMap::add_close_mapping(const AST_Node* node) { mappings.push_back(Mapping(node->pstate() + node->pstate().offset, current_position)); } diff --git a/src/source_map.hpp b/src/source_map.hpp index 5776e712e5..d6379aa0dd 100644 --- a/src/source_map.hpp +++ b/src/source_map.hpp @@ -28,8 +28,8 @@ namespace Sass { void prepend(const Offset& offset); void append(const OutputBuffer& out); void prepend(const OutputBuffer& out); - void add_open_mapping(AST_Node* node); - void add_close_mapping(AST_Node* node); + void add_open_mapping(const AST_Node* node); + void add_close_mapping(const AST_Node* node); std::string render_srcmap(Context &ctx); ParserState remap(const ParserState& pstate); diff --git a/src/to_string.cpp b/src/to_string.cpp index 69b4c3dfbc..4e5f62bec9 100644 --- a/src/to_string.cpp +++ b/src/to_string.cpp @@ -11,16 +11,16 @@ namespace Sass { - To_String::To_String(Context* ctx, bool in_declaration, bool in_debug) - : ctx(ctx), in_declaration(in_declaration), in_debug(in_debug) { } + To_String::To_String(struct Sass_Output_Options opt, bool in_declaration) + : opt(opt), in_declaration(in_declaration) { } + To_String::~To_String() { } inline std::string To_String::fallback_impl(AST_Node* n) { - Emitter emitter(ctx); + Emitter emitter(opt); Inspect i(emitter); i.in_declaration = in_declaration; - i.in_debug = in_debug; if (n) n->perform(&i); return i.get_buffer(); } @@ -44,6 +44,4 @@ namespace Sass { return s->value(); } - inline std::string To_String::operator()(Null* n) - { return in_debug ? "null" : ""; } } diff --git a/src/to_string.hpp b/src/to_string.hpp index 3ee45e8b49..85e6063daa 100644 --- a/src/to_string.hpp +++ b/src/to_string.hpp @@ -11,20 +11,19 @@ namespace Sass { class Null; class To_String : public Operation_CRTP { - + // import all the class-specific methods and override as desired + using Operation::operator(); // override this to define a catch-all std::string fallback_impl(AST_Node* n); - Context* ctx; + struct Sass_Output_Options opt; bool in_declaration; - bool in_debug; public: - To_String(Context* ctx = 0, bool in_declaration = true, bool in_debug = false); - ~To_String(); + To_String(struct Sass_Output_Options opt = Sass_Output_Options(), bool in_declaration = true); + virtual ~To_String(); - std::string operator()(Null* n); std::string operator()(String_Schema*); std::string operator()(String_Quoted*); std::string operator()(String_Constant*); diff --git a/src/to_value.cpp b/src/to_value.cpp index c6635fa85e..2b6812f567 100644 --- a/src/to_value.cpp +++ b/src/to_value.cpp @@ -92,7 +92,7 @@ namespace Sass { // Selector_List is converted to a string Value* To_Value::operator()(Selector_List* s) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); return SASS_MEMORY_NEW(mem, String_Quoted, s->pstate(), s->perform(&to_string)); @@ -101,7 +101,7 @@ namespace Sass { // Binary_Expression is converted to a string Value* To_Value::operator()(Binary_Expression* s) { - To_String to_string(&ctx); + To_String to_string(ctx.c_options); return SASS_MEMORY_NEW(mem, String_Quoted, s->pstate(), s->perform(&to_string)); diff --git a/src/util.cpp b/src/util.cpp index ed161a2be5..6b24f3f035 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -474,7 +474,7 @@ namespace Sass { } } else if (Comment* c = dynamic_cast(stm)) { // keep for uncompressed - if (style != SASS_STYLE_COMPRESSED) { + if (style != COMPRESSED) { hasDeclarations = true; } // output style compressed @@ -579,7 +579,7 @@ namespace Sass { else if (typeid(*stm) == typeid(Comment)) { Comment* c = (Comment*) stm; // keep for uncompressed - if (style != SASS_STYLE_COMPRESSED) { + if (style != COMPRESSED) { return true; } // output style compressed diff --git a/src/util.hpp b/src/util.hpp index cdd1b335c0..06c3d99827 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -4,6 +4,7 @@ #include #include #include +#include "sass.hpp" #include "sass/base.h" #include "ast_fwd_decl.hpp" @@ -42,13 +43,13 @@ namespace Sass { std::string vecJoin(const std::vector& vec, const std::string& sep); bool containsAnyPrintableStatements(Block* b); - bool isPrintable(Ruleset* r, Sass_Output_Style style = SASS_STYLE_NESTED); - bool isPrintable(Supports_Block* r, Sass_Output_Style style = SASS_STYLE_NESTED); - bool isPrintable(Media_Block* r, Sass_Output_Style style = SASS_STYLE_NESTED); - bool isPrintable(Block* b, Sass_Output_Style style = SASS_STYLE_NESTED); - bool isPrintable(String_Constant* s, Sass_Output_Style style = SASS_STYLE_NESTED); - bool isPrintable(String_Quoted* s, Sass_Output_Style style = SASS_STYLE_NESTED); - bool isPrintable(Declaration* d, Sass_Output_Style style = SASS_STYLE_NESTED); + bool isPrintable(Ruleset* r, Sass_Output_Style style = NESTED); + bool isPrintable(Supports_Block* r, Sass_Output_Style style = NESTED); + bool isPrintable(Media_Block* r, Sass_Output_Style style = NESTED); + bool isPrintable(Block* b, Sass_Output_Style style = NESTED); + bool isPrintable(String_Constant* s, Sass_Output_Style style = NESTED); + bool isPrintable(String_Quoted* s, Sass_Output_Style style = NESTED); + bool isPrintable(Declaration* d, Sass_Output_Style style = NESTED); bool isAscii(const char chr); }