Commit e7824065 by Sam Saccone

update libsass

parent 60f66275
#define SASS_BACKTRACE
#include <sstream>
namespace Sass {
using namespace std;
struct Backtrace {
Backtrace* parent;
string path;
size_t line;
string caller;
Backtrace(Backtrace* prn, string pth, size_t ln, string c)
: parent(prn),
path(pth),
line(ln),
caller(c)
{ }
string to_string(bool warning = false)
{
stringstream ss;
Backtrace* this_point = this;
if (!warning) ss << endl << "Backtrace:";
// the first tracepoint (which is parent-less) is an empty placeholder
while (this_point->parent) {
ss << endl
<< "\t"
<< (warning ? " " : "")
<< this_point->path
<< ":"
<< this_point->line
<< this_point->parent->caller;
this_point = this_point->parent;
}
return ss.str();
}
};
}
\ No newline at end of file
...@@ -12,6 +12,7 @@ namespace Sass { ...@@ -12,6 +12,7 @@ namespace Sass {
extern const char function_kwd[] = "@function"; extern const char function_kwd[] = "@function";
extern const char return_kwd[] = "@return"; extern const char return_kwd[] = "@return";
extern const char include_kwd[] = "@include"; extern const char include_kwd[] = "@include";
extern const char content_kwd[] = "@content";
extern const char extend_kwd[] = "@extend"; extern const char extend_kwd[] = "@extend";
extern const char if_kwd[] = "@if"; extern const char if_kwd[] = "@if";
extern const char else_kwd[] = "@else"; extern const char else_kwd[] = "@else";
...@@ -43,6 +44,7 @@ namespace Sass { ...@@ -43,6 +44,7 @@ namespace Sass {
extern const char kHz_kwd[] = "kHz"; extern const char kHz_kwd[] = "kHz";
// css functions and keywords // css functions and keywords
extern const char charset_kwd[] = "@charset";
extern const char media_kwd[] = "@media"; extern const char media_kwd[] = "@media";
extern const char only_kwd[] = "only"; extern const char only_kwd[] = "only";
extern const char rgb_kwd[] = "rgb("; extern const char rgb_kwd[] = "rgb(";
...@@ -83,6 +85,7 @@ namespace Sass { ...@@ -83,6 +85,7 @@ namespace Sass {
extern const char rbrace[] = "}"; extern const char rbrace[] = "}";
extern const char rparen[] = ")"; extern const char rparen[] = ")";
extern const char sign_chars[] = "-+"; extern const char sign_chars[] = "-+";
extern const char hyphen[] = "-";
// type names // type names
extern const char numeric_name[] = "numeric value"; extern const char numeric_name[] = "numeric value";
......
...@@ -12,6 +12,7 @@ namespace Sass { ...@@ -12,6 +12,7 @@ namespace Sass {
extern const char function_kwd[]; extern const char function_kwd[];
extern const char return_kwd[]; extern const char return_kwd[];
extern const char include_kwd[]; extern const char include_kwd[];
extern const char content_kwd[];
extern const char extend_kwd[]; extern const char extend_kwd[];
extern const char if_kwd[]; extern const char if_kwd[];
extern const char else_kwd[]; extern const char else_kwd[];
...@@ -43,6 +44,7 @@ namespace Sass { ...@@ -43,6 +44,7 @@ namespace Sass {
extern const char kHz_kwd[]; extern const char kHz_kwd[];
// css functions and keywords // css functions and keywords
extern const char charset_kwd[];
extern const char media_kwd[]; extern const char media_kwd[];
extern const char only_kwd[]; extern const char only_kwd[];
extern const char rgb_kwd[]; extern const char rgb_kwd[];
...@@ -83,6 +85,7 @@ namespace Sass { ...@@ -83,6 +85,7 @@ namespace Sass {
extern const char rbrace[]; extern const char rbrace[];
extern const char rparen[]; extern const char rparen[];
extern const char sign_chars[]; extern const char sign_chars[];
extern const char hyphen[];
// type names // type names
extern const char numeric_name[]; extern const char numeric_name[];
......
#ifdef _WIN32 #ifdef _WIN32
#include <direct.h> #include <direct.h>
#define getcwd _getcwd #define getcwd _getcwd
#define PATH_SEP ';'
#else #else
#include <unistd.h> #include <unistd.h>
#define PATH_SEP ':'
#endif #endif
#include <cstring> #include <cstring>
...@@ -27,7 +29,7 @@ namespace Sass { ...@@ -27,7 +29,7 @@ namespace Sass {
if (paths_str) { if (paths_str) {
const char* beg = paths_str; const char* beg = paths_str;
const char* end = Prelexer::find_first<':'>(beg); const char* end = Prelexer::find_first<PATH_SEP>(beg);
while (end) { while (end) {
string path(beg, end - beg); string path(beg, end - beg);
...@@ -36,7 +38,7 @@ namespace Sass { ...@@ -36,7 +38,7 @@ namespace Sass {
include_paths.push_back(path); include_paths.push_back(path);
} }
beg = end + 1; beg = end + 1;
end = Prelexer::find_first<':'>(beg); end = Prelexer::find_first<PATH_SEP>(beg);
} }
string path(beg); string path(beg);
...@@ -51,19 +53,20 @@ namespace Sass { ...@@ -51,19 +53,20 @@ namespace Sass {
// } // }
} }
Context::Context(const char* paths_str, const char* img_path_str) Context::Context(const char* paths_str, const char* img_path_str, bool sc)
: global_env(Environment()), : global_env(Environment()),
function_env(map<string, Function>()), function_env(map<string, Function>()),
extensions(multimap<Node, Node>()), extensions(multimap<Node, Node>()),
pending_extensions(vector<pair<Node, Node> >()), pending_extensions(vector<pair<Node, Node> >()),
source_refs(vector<char*>()), source_refs(vector<const char*>()),
include_paths(vector<string>()), include_paths(vector<string>()),
color_names_to_values(map<string, Node>()), color_names_to_values(map<string, Node>()),
color_values_to_names(map<Node, string>()), color_values_to_names(map<Node, string>()),
new_Node(Node_Factory()), new_Node(Node_Factory()),
image_path(0), image_path(0),
ref_count(0), ref_count(0),
has_extensions(false) has_extensions(false),
source_comments(sc)
{ {
register_functions(); register_functions();
collect_include_paths(paths_str); collect_include_paths(paths_str);
...@@ -143,7 +146,8 @@ namespace Sass { ...@@ -143,7 +146,8 @@ namespace Sass {
// Other Color Functions // Other Color Functions
register_function(adjust_color_sig, adjust_color); register_function(adjust_color_sig, adjust_color);
register_function(scale_color_sig, scale_color); register_function(scale_color_sig, scale_color);
register_function(change_color_sig, change_color); register_function(change_color_sig, change_color);
register_function(ie_hex_str_sig, ie_hex_str);
// String Functions // String Functions
register_function(unquote_sig, unquote); register_function(unquote_sig, unquote);
register_function(quote_sig, quote); register_function(quote_sig, quote);
......
...@@ -23,7 +23,7 @@ namespace Sass { ...@@ -23,7 +23,7 @@ namespace Sass {
map<string, Function> function_env; map<string, Function> function_env;
multimap<Node, Node> extensions; multimap<Node, Node> extensions;
vector<pair<Node, Node> > pending_extensions; vector<pair<Node, Node> > pending_extensions;
vector<char*> source_refs; // all the source c-strings vector<const char*> source_refs; // all the source c-strings
vector<string> include_paths; vector<string> include_paths;
map<string, Node> color_names_to_values; map<string, Node> color_names_to_values;
map<Node, string> color_values_to_names; map<Node, string> color_values_to_names;
...@@ -33,9 +33,10 @@ namespace Sass { ...@@ -33,9 +33,10 @@ namespace Sass {
// string sass_path; // string sass_path;
// string css_path; // string css_path;
bool has_extensions; bool has_extensions;
bool source_comments;
void collect_include_paths(const char* paths_str); void collect_include_paths(const char* paths_str);
Context(const char* paths_str = 0, const char* img_path_str = 0); Context(const char* paths_str = 0, const char* img_path_str = 0, bool sc = false);
~Context(); ~Context();
void register_function(Signature sig, Primitive ip); void register_function(Signature sig, Primitive ip);
......
...@@ -37,23 +37,39 @@ namespace Sass { ...@@ -37,23 +37,39 @@ namespace Sass {
const char* path_str = path.c_str(); const char* path_str = path.c_str();
struct stat st; struct stat st;
string tmp; string tmp;
// Resolution order for ambiguous imports:
// (1) filename as given
// (2) underscore + given
// (3) underscore + given + extension
// (4) given + extension
// if the file as given isn't found ...
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) { if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) {
tmp = path + ".scss"; // then try "_" + given
const char *full_path_str = path.c_str();
const char *file_name_str = Prelexer::folders(full_path_str);
string folder(Token::make(full_path_str, file_name_str).to_string());
string partial_filename("_" + string(file_name_str));
tmp = folder + partial_filename;
path_str = tmp.c_str();
// if "_" + given isn't found ...
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) {
// then try "_" + given + ".scss"
tmp += ".scss";
path_str = tmp.c_str(); path_str = tmp.c_str();
// if "_" + given + ".scss" isn't found ...
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) { if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) {
const char *full_path_str = path.c_str(); // then try given + ".scss"
const char *file_name_str = Prelexer::folders(full_path_str); string non_partial_filename(string(file_name_str) + ".scss");
tmp = Token::make(full_path_str, file_name_str).to_string() + tmp = folder + non_partial_filename;
"_" + path_str = tmp.c_str();
string(file_name_str); // if we still can't find the file, then throw an error
path_str = tmp.c_str(); if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) {
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) { throw path;
tmp = tmp + ".scss"; }
path_str = tmp.c_str();
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode))
throw path;
}
} }
}
} }
f = std::fopen(path_str, "rb"); f = std::fopen(path_str, "rb");
size_t len = st.st_size; size_t len = st.st_size;
...@@ -70,7 +86,7 @@ namespace Sass { ...@@ -70,7 +86,7 @@ namespace Sass {
string include_path(path_str, file_name_str - path_str); string include_path(path_str, file_name_str - path_str);
Document doc(ctx); Document doc(ctx);
doc.path = path; doc.path = path_str;
doc.line = 1; doc.line = 1;
doc.root = ctx.new_Node(Node::root, path, 1, 0); doc.root = ctx.new_Node(Node::root, path, 1, 0);
doc.lexed = Token::make(); doc.lexed = Token::make();
...@@ -79,14 +95,11 @@ namespace Sass { ...@@ -79,14 +95,11 @@ namespace Sass {
doc.end = end; doc.end = end;
doc.position = source; doc.position = source;
doc.context.source_refs.push_back(source); doc.context.source_refs.push_back(source);
if (!include_path.empty()) {
doc.context.include_paths.push_back(include_path);
}
return doc; return doc;
} }
Document Document::make_from_source_chars(Context& ctx, char* src, string path, bool own_source) Document Document::make_from_source_chars(Context& ctx, const char* src, string path, bool own_source)
{ {
Document doc(ctx); Document doc(ctx);
doc.path = path; doc.path = path;
...@@ -110,7 +123,7 @@ namespace Sass { ...@@ -110,7 +123,7 @@ namespace Sass {
doc.root = ctx.new_Node(Node::root, path, 1, 0); doc.root = ctx.new_Node(Node::root, path, 1, 0);
doc.lexed = Token::make(); doc.lexed = Token::make();
doc.own_source = false; doc.own_source = false;
doc.source = const_cast<char*>(t.begin); doc.source = t.begin;
doc.end = t.end; doc.end = t.end;
doc.position = doc.source; doc.position = doc.source;
...@@ -134,11 +147,14 @@ namespace Sass { ...@@ -134,11 +147,14 @@ namespace Sass {
root.echo(output); root.echo(output);
break; break;
case nested: case nested:
root.emit_nested_css(output, 0, true); root.emit_nested_css(output, 0, true, false, context.source_comments);
break; break;
case expanded: case expanded:
root.emit_expanded_css(output, ""); root.emit_expanded_css(output, "");
break; break;
case compressed:
root.emit_compressed_css(output);
break;
default: default:
break; break;
} }
......
...@@ -29,7 +29,7 @@ namespace Sass { ...@@ -29,7 +29,7 @@ namespace Sass {
enum CSS_Style { nested, expanded, compact, compressed, echo }; enum CSS_Style { nested, expanded, compact, compressed, echo };
string path; string path;
char* source; const char* source;
const char* position; const char* position;
const char* end; const char* end;
size_t line; size_t line;
...@@ -48,7 +48,7 @@ namespace Sass { ...@@ -48,7 +48,7 @@ namespace Sass {
~Document(); ~Document();
static Document make_from_file(Context& ctx, string path); static Document make_from_file(Context& ctx, string path);
static Document make_from_source_chars(Context& ctx, char* src, string path = "", bool own_source = false); static Document make_from_source_chars(Context& ctx, const char* src, string path = "", bool own_source = false);
static Document make_from_token(Context& ctx, Token t, string path = "", size_t line_number = 1); static Document make_from_token(Context& ctx, Token t, string path = "", size_t line_number = 1);
template <prelexer mx> template <prelexer mx>
...@@ -133,7 +133,7 @@ namespace Sass { ...@@ -133,7 +133,7 @@ namespace Sass {
Node parse_function_definition(); Node parse_function_definition();
Node parse_parameters(); Node parse_parameters();
Node parse_parameter(Node::Type); Node parse_parameter(Node::Type);
Node parse_mixin_call(); Node parse_mixin_call(Node::Type inside_of = Node::none);
Node parse_arguments(); Node parse_arguments();
Node parse_argument(Node::Type); Node parse_argument(Node::Type);
Node parse_assignment(); Node parse_assignment();
...@@ -183,4 +183,4 @@ namespace Sass { ...@@ -183,4 +183,4 @@ namespace Sass {
string emit_css(CSS_Style style); string emit_css(CSS_Style style);
}; };
} }
\ No newline at end of file
...@@ -10,19 +10,23 @@ ...@@ -10,19 +10,23 @@
#include "context.hpp" #include "context.hpp"
#endif #endif
#ifndef SASS_BACKTRACE
#include "backtrace.hpp"
#endif
namespace Sass { namespace Sass {
using std::map; using std::map;
void expand(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool function_name = false); void expand(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool function_name = false, const Node content = Node());
Node eval(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool function_name = false); void re_expand(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool function_name, const Node content);
Node eval_arguments(Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx); Node eval(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool function_name = false);
Node eval_function(string name, Node stm, Environment& bindings, Node_Factory& new_Node, Context& ctx, bool toplevel = false); Node eval_arguments(Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt);
Node reduce(Node list, size_t head, Node acc, Node_Factory& new_Node); Node eval_function(string name, Node stm, Environment& bindings, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool toplevel = false);
Node accumulate(Node::Type op, Node acc, Node rhs, Node_Factory& new_Node); Node reduce(Node list, size_t head, Node acc, Node_Factory& new_Node, Backtrace& bt);
double operate(Node op, double lhs, double rhs); double operate(Node op, double lhs, double rhs, Backtrace& bt);
Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool dynamic_scope = false); Node apply_mixin(Node mixin, const Node args, const Node content, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool dynamic_scope = false);
Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, string& path, size_t line); Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt, string& path, size_t line);
Node expand_selector(Node sel, Node pre, Node_Factory& new_Node); Node expand_selector(Node sel, Node pre, Node_Factory& new_Node);
Node expand_backref(Node sel, Node pre); Node expand_backref(Node sel, Node pre);
void extend(Node expr, multimap<Node, Node>& extension_requests, Node_Factory& new_Node); void extend(Node expr, multimap<Node, Node>& extension_requests, Node_Factory& new_Node);
......
...@@ -19,6 +19,7 @@ namespace Sass { ...@@ -19,6 +19,7 @@ namespace Sass {
{ {
case block: case block:
case mixin_call: case mixin_call:
case mixin_content:
case root: case root:
case if_directive: case if_directive:
case for_through_directive: case for_through_directive:
...@@ -35,6 +36,7 @@ namespace Sass { ...@@ -35,6 +36,7 @@ namespace Sass {
switch (at(i).type()) switch (at(i).type())
{ {
case mixin_call: case mixin_call:
case mixin_content:
case block: case block:
case if_directive: case if_directive:
case for_through_directive: case for_through_directive:
...@@ -44,6 +46,7 @@ namespace Sass { ...@@ -44,6 +46,7 @@ namespace Sass {
Node expn(at(i)); Node expn(at(i));
if (expn.has_expansions()) expn.flatten(); if (expn.has_expansions()) expn.flatten();
ip_->has_statements |= expn.has_statements(); ip_->has_statements |= expn.has_statements();
ip_->has_comments |= expn.has_comments();
ip_->has_blocks |= expn.has_blocks(); ip_->has_blocks |= expn.has_blocks();
ip_->has_expansions |= expn.has_expansions(); ip_->has_expansions |= expn.has_expansions();
// TO DO: make this more efficient -- replace with a dummy node instead of erasing // TO DO: make this more efficient -- replace with a dummy node instead of erasing
......
...@@ -142,6 +142,7 @@ namespace Sass { ...@@ -142,6 +142,7 @@ namespace Sass {
numeric_percentage, numeric_percentage,
numeric_dimension, numeric_dimension,
numeric_color, numeric_color,
ie_hex_str,
boolean, boolean,
important, important,
...@@ -154,6 +155,7 @@ namespace Sass { ...@@ -154,6 +155,7 @@ namespace Sass {
function_call, function_call,
mixin, mixin,
mixin_call, mixin_call,
mixin_content,
parameters, parameters,
arguments, arguments,
...@@ -183,6 +185,7 @@ namespace Sass { ...@@ -183,6 +185,7 @@ namespace Sass {
bool has_children() const; bool has_children() const;
bool has_statements() const; bool has_statements() const;
bool has_comments() const;
bool has_blocks() const; bool has_blocks() const;
bool has_expansions() const; bool has_expansions() const;
bool has_backref() const; bool has_backref() const;
...@@ -237,11 +240,12 @@ namespace Sass { ...@@ -237,11 +240,12 @@ namespace Sass {
bool operator>(Node rhs) const; bool operator>(Node rhs) const;
bool operator>=(Node rhs) const; bool operator>=(Node rhs) const;
string to_string(Type inside_of = none) const; string to_string(Type inside_of = none, const string space = " ") const;
void emit_nested_css(stringstream& buf, size_t depth, bool at_toplevel = false, bool in_media_query = false); void emit_nested_css(stringstream& buf, size_t depth, bool at_toplevel = false, bool in_media_query = false, bool source_comments = false);
void emit_propset(stringstream& buf, size_t depth, const string& prefix); void emit_propset(stringstream& buf, size_t depth, const string& prefix, const bool compressed = false);
void echo(stringstream& buf, size_t depth = 0); void echo(stringstream& buf, size_t depth = 0);
void emit_expanded_css(stringstream& buf, const string& prefix); void emit_expanded_css(stringstream& buf, const string& prefix);
void emit_compressed_css(stringstream& buf);
}; };
...@@ -264,6 +268,7 @@ namespace Sass { ...@@ -264,6 +268,7 @@ namespace Sass {
bool has_children; bool has_children;
bool has_statements; bool has_statements;
bool has_comments;
bool has_blocks; bool has_blocks;
bool has_expansions; bool has_expansions;
bool has_backref; bool has_backref;
...@@ -281,6 +286,7 @@ namespace Sass { ...@@ -281,6 +286,7 @@ namespace Sass {
type(Node::none), */ type(Node::none), */
has_children(false), has_children(false),
has_statements(false), has_statements(false),
has_comments(false),
has_blocks(false), has_blocks(false),
has_expansions(false), has_expansions(false),
has_backref(false), has_backref(false),
...@@ -349,9 +355,13 @@ namespace Sass { ...@@ -349,9 +355,13 @@ namespace Sass {
{ {
children.push_back(n); children.push_back(n);
has_children = true; has_children = true;
if (n.is_null()) return;
switch (n.type()) switch (n.type())
{ {
case Node::comment: case Node::comment: {
has_comments = true;
} break;
case Node::css_import: case Node::css_import:
case Node::rule: case Node::rule:
case Node::propset: case Node::propset:
...@@ -372,7 +382,8 @@ namespace Sass { ...@@ -372,7 +382,8 @@ namespace Sass {
case Node::for_to_directive: case Node::for_to_directive:
case Node::each_directive: case Node::each_directive:
case Node::while_directive: case Node::while_directive:
case Node::mixin_call: { case Node::mixin_call:
case Node::mixin_content: {
has_expansions = true; has_expansions = true;
} break; } break;
...@@ -391,24 +402,26 @@ namespace Sass { ...@@ -391,24 +402,26 @@ namespace Sass {
has_children = true; has_children = true;
switch (n.type()) switch (n.type())
{ {
case Node::comment: case Node::comment: has_comments = true; break;
case Node::css_import: case Node::css_import:
case Node::rule: case Node::rule:
case Node::propset: has_statements = true; break; case Node::propset: has_statements = true; break;
case Node::media_query: case Node::media_query:
case Node::ruleset: has_blocks = true; break; case Node::ruleset: has_blocks = true; break;
case Node::if_directive: case Node::if_directive:
case Node::for_through_directive: case Node::for_through_directive:
case Node::for_to_directive: case Node::for_to_directive:
case Node::each_directive: case Node::each_directive:
case Node::while_directive: case Node::while_directive:
case Node::mixin_call: has_expansions = true; break; case Node::mixin_call:
case Node::mixin_content: has_expansions = true; break;
case Node::backref: has_backref = true; break; case Node::backref: has_backref = true; break;
default: break; default: break;
} }
if (n.has_backref()) has_backref = true; if (n.has_backref()) has_backref = true;
} }
...@@ -440,6 +453,7 @@ namespace Sass { ...@@ -440,6 +453,7 @@ namespace Sass {
inline bool Node::has_children() const { return ip_->has_children; } inline bool Node::has_children() const { return ip_->has_children; }
inline bool Node::has_statements() const { return ip_->has_statements; } inline bool Node::has_statements() const { return ip_->has_statements; }
inline bool Node::has_comments() const { return ip_->has_comments; }
inline bool Node::has_blocks() const { return ip_->has_blocks; } inline bool Node::has_blocks() const { return ip_->has_blocks; }
inline bool Node::has_expansions() const { return ip_->has_expansions; } inline bool Node::has_expansions() const { return ip_->has_expansions; }
inline bool Node::has_backref() const { return ip_->has_backref; } inline bool Node::has_backref() const { return ip_->has_backref; }
......
...@@ -26,9 +26,7 @@ namespace Sass { ...@@ -26,9 +26,7 @@ namespace Sass {
Node operator()(Node::Type type, string file, size_t line, Token t); Node operator()(Node::Type type, string file, size_t line, Token t);
// for making boolean values or interior nodes that have children // for making boolean values or interior nodes that have children
Node operator()(Node::Type type, string file, size_t line, size_t size); Node operator()(Node::Type type, string file, size_t line, size_t size);
// // for making nodes representing boolean values // for making nodes representing numbers and numeric percentages
// Node operator()(Node::Type type, string file, size_t line, bool b);
// for making nodes representing numbers
Node operator()(string file, size_t line, double v, Node::Type type = Node::number); Node operator()(string file, size_t line, double v, Node::Type type = Node::number);
// for making nodes representing numeric dimensions (e.g. 5px, 3em) // for making nodes representing numeric dimensions (e.g. 5px, 3em)
Node operator()(string file, size_t line, double v, const Token& t); Node operator()(string file, size_t line, double v, const Token& t);
......
...@@ -138,6 +138,10 @@ namespace Sass { ...@@ -138,6 +138,10 @@ namespace Sass {
return exactly<include_kwd>(src); return exactly<include_kwd>(src);
} }
const char* content(const char* src) {
return exactly<content_kwd>(src);
}
const char* extend(const char* src) { const char* extend(const char* src) {
return exactly<extend_kwd>(src); return exactly<extend_kwd>(src);
} }
...@@ -383,5 +387,32 @@ namespace Sass { ...@@ -383,5 +387,32 @@ namespace Sass {
const char* folders(const char* src) { const char* folders(const char* src) {
return zero_plus< folder >(src); return zero_plus< folder >(src);
} }
const char* chunk(const char* src) {
char inside_str = 0;
const char* p = src;
size_t depth = 0;
while (true) {
if (!*p) {
return 0;
}
else if (!inside_str && (*p == '"' || *p == '\'')) {
inside_str = *p;
}
else if (*p == inside_str && *(p-1) != '\\') {
inside_str = 0;
}
else if (*p == '(' && !inside_str) {
++depth;
}
else if (*p == ')' && !inside_str) {
if (depth == 0) return p;
else --depth;
}
++p;
}
// unreachable
return 0;
}
} }
} }
\ No newline at end of file
...@@ -317,6 +317,7 @@ namespace Sass { ...@@ -317,6 +317,7 @@ namespace Sass {
const char* function(const char* src); const char* function(const char* src);
const char* return_directive(const char* src); const char* return_directive(const char* src);
const char* include(const char* src); const char* include(const char* src);
const char* content(const char* src);
const char* extend(const char* src); const char* extend(const char* src);
const char* if_directive(const char* src); const char* if_directive(const char* src);
...@@ -447,5 +448,7 @@ namespace Sass { ...@@ -447,5 +448,7 @@ namespace Sass {
} }
return counter; return counter;
} }
const char* chunk(const char* src);
} }
} }
#ifdef _WIN32 #ifdef _WIN32
#include <io.h> #include <io.h>
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <iostream> #include <iostream>
...@@ -45,13 +45,15 @@ extern "C" { ...@@ -45,13 +45,15 @@ extern "C" {
static char* process_document(Sass::Document& doc, int style) static char* process_document(Sass::Document& doc, int style)
{ {
using namespace Sass; using namespace Sass;
Backtrace root_trace(0, "", 0, "");
doc.parse_scss(); doc.parse_scss();
expand(doc.root, expand(doc.root,
Node(), Node(),
doc.context.global_env, doc.context.global_env,
doc.context.function_env, doc.context.function_env,
doc.context.new_Node, doc.context.new_Node,
doc.context); doc.context,
root_trace);
// extend_selectors(doc.context.pending_extensions, doc.context.extensions, doc.context.new_Node); // extend_selectors(doc.context.pending_extensions, doc.context.extensions, doc.context.new_Node);
if (doc.context.has_extensions) extend(doc.root, doc.context.extensions, doc.context.new_Node); if (doc.context.has_extensions) extend(doc.root, doc.context.extensions, doc.context.new_Node);
string output(doc.emit_css(static_cast<Document::CSS_Style>(style))); string output(doc.emit_css(static_cast<Document::CSS_Style>(style)));
...@@ -64,7 +66,7 @@ extern "C" { ...@@ -64,7 +66,7 @@ extern "C" {
{ {
using namespace Sass; using namespace Sass;
try { try {
Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path); Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path, c_ctx->options.source_comments);
// cpp_ctx.image_path = c_ctx->options.image_path; // cpp_ctx.image_path = c_ctx->options.image_path;
// Document doc(0, c_ctx->input_string, cpp_ctx); // Document doc(0, c_ctx->input_string, cpp_ctx);
Document doc(Document::make_from_source_chars(cpp_ctx, c_ctx->source_string)); Document doc(Document::make_from_source_chars(cpp_ctx, c_ctx->source_string));
...@@ -74,7 +76,7 @@ extern "C" { ...@@ -74,7 +76,7 @@ extern "C" {
} }
catch (Error& e) { catch (Error& e) {
stringstream msg_stream; stringstream msg_stream;
msg_stream << "ERROR -- " << e.path << ", line " << e.line << ": " << e.message << endl; msg_stream << e.path << ":" << e.line << ": error: " << e.message << endl;
string msg(msg_stream.str()); string msg(msg_stream.str());
char* msg_str = (char*) malloc(msg.size() + 1); char* msg_str = (char*) malloc(msg.size() + 1);
strcpy(msg_str, msg.c_str()); strcpy(msg_str, msg.c_str());
...@@ -84,7 +86,7 @@ extern "C" { ...@@ -84,7 +86,7 @@ extern "C" {
} }
catch(bad_alloc& ba) { catch(bad_alloc& ba) {
stringstream msg_stream; stringstream msg_stream;
msg_stream << "ERROR -- unable to allocate memory: " << ba.what() << endl; msg_stream << "Unable to allocate memory: " << ba.what() << endl;
string msg(msg_stream.str()); string msg(msg_stream.str());
char* msg_str = (char*) malloc(msg.size() + 1); char* msg_str = (char*) malloc(msg.size() + 1);
strcpy(msg_str, msg.c_str()); strcpy(msg_str, msg.c_str());
...@@ -99,22 +101,16 @@ extern "C" { ...@@ -99,22 +101,16 @@ extern "C" {
int sass_compile_file(sass_file_context* c_ctx) int sass_compile_file(sass_file_context* c_ctx)
{ {
using namespace Sass; using namespace Sass;
Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path, c_ctx->options.source_comments);
try { try {
Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path);
// Document doc(c_ctx->input_path, 0, cpp_ctx);
// string path_string(c_ctx->options.image_path);
// path_string = "'" + path_string + "/";
// cpp_ctx.image_path = c_ctx->options.image_path;
Document doc(Document::make_from_file(cpp_ctx, string(c_ctx->input_path))); Document doc(Document::make_from_file(cpp_ctx, string(c_ctx->input_path)));
// cerr << "MADE A DOC AND CONTEXT OBJ" << endl;
// cerr << "REGISTRY: " << doc.context.registry.size() << endl;
c_ctx->output_string = process_document(doc, c_ctx->options.output_style); c_ctx->output_string = process_document(doc, c_ctx->options.output_style);
c_ctx->error_message = 0; c_ctx->error_message = 0;
c_ctx->error_status = 0; c_ctx->error_status = 0;
} }
catch (Error& e) { catch (Error& e) {
stringstream msg_stream; stringstream msg_stream;
msg_stream << "ERROR -- " << e.path << ", line " << e.line << ": " << e.message << endl; msg_stream << e.path << ":" << e.line << ": error: " << e.message << endl;
string msg(msg_stream.str()); string msg(msg_stream.str());
char* msg_str = (char*) malloc(msg.size() + 1); char* msg_str = (char*) malloc(msg.size() + 1);
strcpy(msg_str, msg.c_str()); strcpy(msg_str, msg.c_str());
...@@ -124,7 +120,30 @@ extern "C" { ...@@ -124,7 +120,30 @@ extern "C" {
} }
catch(bad_alloc& ba) { catch(bad_alloc& ba) {
stringstream msg_stream; stringstream msg_stream;
msg_stream << "ERROR -- unable to allocate memory: " << ba.what() << endl; msg_stream << "Unable to allocate memory: " << ba.what() << endl;
string msg(msg_stream.str());
char* msg_str = (char*) malloc(msg.size() + 1);
strcpy(msg_str, msg.c_str());
c_ctx->error_status = 1;
c_ctx->output_string = 0;
c_ctx->error_message = msg_str;
}
catch(string& bad_path) {
for (vector<string>::iterator path = cpp_ctx.include_paths.begin(); path < cpp_ctx.include_paths.end(); ++path) {
try {
Document doc(Document::make_from_file(cpp_ctx, *path + string(c_ctx->input_path)));
c_ctx->output_string = process_document(doc, c_ctx->options.output_style);
c_ctx->error_message = 0;
c_ctx->error_status = 0;
return 0;
}
catch (string& bad_path) {
// continue looping
}
}
// couldn't find the specified file in the include paths; report an error
stringstream msg_stream;
msg_stream << "error reading file \"" << bad_path << "\"" << endl;
string msg(msg_stream.str()); string msg(msg_stream.str());
char* msg_str = (char*) malloc(msg.size() + 1); char* msg_str = (char*) malloc(msg.size() + 1);
strcpy(msg_str, msg.c_str()); strcpy(msg_str, msg.c_str());
......
#include <node.h> #define SASS_INTERFACE
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
...@@ -11,18 +11,17 @@ extern "C" { ...@@ -11,18 +11,17 @@ extern "C" {
struct sass_options { struct sass_options {
int output_style; int output_style;
int source_comments; // really want a bool, but C doesn't have them
char* include_paths; char* include_paths;
char* image_path; char* image_path;
}; };
struct sass_context { struct sass_context {
char* source_string; const char* source_string;
char* output_string; char* output_string;
struct sass_options options; struct sass_options options;
int error_status; int error_status;
char* error_message; char* error_message;
uv_work_t request;
v8::Persistent<v8::Function> callback;
}; };
struct sass_file_context { struct sass_file_context {
...@@ -55,4 +54,4 @@ int sass_compile_folder (struct sass_folder_context* ctx); ...@@ -55,4 +54,4 @@ int sass_compile_folder (struct sass_folder_context* ctx);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment