Commit d58dae2b by Hampton Catlin

Merge branch 'master' of github.com:hcatlin/libsass

parents 19f9e84a b1580330
......@@ -104,6 +104,7 @@ div {
b: hey or ho or false or hoo;
c: false and hey and ho;
d: true and false and (1/0);
e: (()()()()()()()()25()()()()()()()()()()()()()()()()()()()()()()());
/* e: 1 < 3 and 3 < 5;
f: (1 2 3) and (4 5 6);*/
......
......@@ -33,15 +33,16 @@ namespace Sass {
}
}
for (int i = 0; i < include_paths.size(); ++i) {
cerr << include_paths[i] << endl;
}
// for (int i = 0; i < include_paths.size(); ++i) {
// cerr << include_paths[i] << endl;
// }
}
Context::Context(const char* paths_str)
: global_env(Environment()),
function_env(map<pair<string, size_t>, Function>()),
source_refs(vector<char*>()),
registry(vector<vector<Node>*>()),
include_paths(vector<string>()),
ref_count(0)
{
......@@ -51,9 +52,11 @@ namespace Sass {
Context::~Context()
{
for (int i = 0; i < source_refs.size(); ++i) {
int i;
for (i = 0; i < source_refs.size(); ++i) {
delete[] source_refs[i];
}
cerr << "Deallocated " << i << " source string(s)." << endl;
}
inline void Context::register_function(Function_Descriptor d, Implementation ip)
......
......@@ -45,6 +45,7 @@ namespace Sass {
Environment global_env;
map<pair<string, size_t>, Function> function_env;
vector<char*> source_refs; // all the source c-strings
vector<vector<Node>*> registry; // all the child vectors
size_t ref_count;
void collect_include_paths(const char* paths_str);
......
......@@ -2,6 +2,7 @@
#include <cstring>
#include "document.hpp"
#include "eval_apply.hpp"
#include "error.hpp"
#include <iostream>
namespace Sass {
......@@ -11,7 +12,7 @@ namespace Sass {
source(source_str),
line_number(1),
context(ctx),
root(Node(Node::root, 1)),
root(Node(Node::root, context.registry, 1)),
lexed(Token::make())
{
if (source_str) {
......@@ -48,22 +49,24 @@ namespace Sass {
: path(path), source(source),
line_number(1), own_source(false),
context(*(new Context())),
root(Node(Node::root, 1)),
root(Node(Node::root, context.registry, 1)),
lexed(Token::make())
{
if (!source) {
std::FILE *f;
// TO DO: CHECK f AGAINST NULL/0
f = std::fopen(path.c_str(), "rb");
std::fseek(f, 0, SEEK_END);
if (!f) throw path;
if (std::fseek(f, 0, SEEK_END)) throw path;
int len = std::ftell(f);
if (len < 0) throw path;
std::rewind(f);
// TO DO: WRAP THE new[] IN A TRY/CATCH BLOCK
// TO DO: CATCH THE POTENTIAL badalloc EXCEPTION
source = new char[len + 1];
std::fread(source, sizeof(char), len, f);
if (std::ferror(f)) throw path;
source[len] = '\0';
end = source + len;
std::fclose(f);
if (std::fclose(f)) throw path;
own_source = true;
}
position = source;
......@@ -75,35 +78,37 @@ namespace Sass {
: path(path), source(0),
line_number(1), own_source(false),
context(context),
root(Node(Node::root, 1)),
root(Node(Node::root, context.registry, 1)),
lexed(Token::make())
{
std::FILE *f;
// TO DO: CHECK f AGAINST NULL/0
f = std::fopen(path.c_str(), "rb");
std::fseek(f, 0, SEEK_END);
if (!f) throw path;
if (std::fseek(f, 0, SEEK_END)) throw path;
int len = std::ftell(f);
if (len < 0) throw path;
std::rewind(f);
// TO DO: WRAP THE new[] IN A TRY/CATCH BLOCK
// TO DO: CATCH THE POTENTIAL badalloc EXCEPTION
source = new char[len + 1];
std::fread(source, sizeof(char), len, f);
if (std::ferror(f)) throw path;
source[len] = '\0';
end = source + len;
std::fclose(f);
if (std::fclose(f)) throw path;
position = source;
context.source_refs.push_back(source);
++context.ref_count;
}
Document::Document(size_t line_number, Token t, Context& context)
: path(string()),
Document::Document(const string& path, size_t line_number, Token t, Context& context)
: path(path),
source(const_cast<char*>(t.begin)),
position(t.begin),
end(t.end),
line_number(line_number),
own_source(false),
context(context),
root(Node(Node::root, 1)),
root(Node(Node::root, context.registry, 1)),
lexed(Token::make())
{ }
......@@ -112,12 +117,11 @@ namespace Sass {
// if (context.ref_count == 0) delete &context;
}
// void Document::eval_pending()
// {
// for (int i = 0; i < context.pending.size(); ++i) {
// eval(context.pending[i], context.global_env);
// }
// }
void Document::syntax_error(string message, size_t ln)
{ throw Error(Error::syntax, ln ? ln : line_number, path, message); }
void Document::read_error(string message, size_t ln)
{ throw Error(Error::read, ln ? ln : line_number, path, message); }
using std::string;
using std::stringstream;
......
......@@ -30,7 +30,7 @@ namespace Sass {
Document(char* path_str, char* source_str, Context& ctx);
Document(string path, char* source = 0);
Document(string path, Context& context);
Document(size_t line_number, Token t, Context& context);
Document(const string& path, size_t line_number, Token t, Context& context);
~Document();
template <prelexer mx>
......@@ -142,6 +142,7 @@ namespace Sass {
Node parse_identifier();
Node parse_variable();
Node parse_function_call();
Node parse_value_schema();
const char* look_for_rule(const char* start = 0);
const char* look_for_values(const char* start = 0);
......@@ -153,7 +154,9 @@ namespace Sass {
const char* look_for_pseudo(const char* start = 0);
const char* look_for_attrib(const char* start = 0);
void eval_pending();
void syntax_error(string message, size_t ln = 0);
void read_error(string message, size_t ln = 0);
string emit_css(CSS_Style style);
};
......
namespace Sass {
struct Error {
enum Type { read, write, syntax, evaluation };
Type type;
size_t line_number;
string file_name;
string message;
Error(Type type, size_t line_number, string file_name, string message)
: type(type), line_number(line_number), file_name(file_name), message(message)
{ }
};
}
\ No newline at end of file
......@@ -11,10 +11,10 @@
namespace Sass {
using std::map;
Node eval(Node& expr, Environment& env, map<pair<string, size_t>, Function>& f_env);
Node accumulate(Node::Type op, Node& acc, Node& rhs);
Node eval(Node& expr, Environment& env, map<pair<string, size_t>, Function>& f_env, vector<vector<Node>*>& registry);
Node accumulate(Node::Type op, Node& acc, Node& rhs, vector<vector<Node>*>& registry);
double operate(Node::Type op, double lhs, double rhs);
Node apply_mixin(Node& mixin, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env);
Node apply_function(const Function& f, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env);
Node apply_mixin(Node& mixin, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env, vector<vector<Node>*>& registry);
Node apply_function(const Function& f, const Node& args, Environment& env, map<pair<string, size_t>, Function>& f_env, vector<vector<Node>*>& registry);
}
\ No newline at end of file
$x: 1 2 3;
bobo + mogo {
hey: hoo;
}
@mixin moogoo() {
hey: ho;
div {
blah: blah;
bloo: (1/0) + 5;
}
}
:nth-of-type(2) {
foo: bar;
}
div[hux ~= "hello"] {
hux: blux;
foo: boo;
dux: "hello" + "goodbye";
shux: 'hello' + 12;
frux: 12 + 'hello';
blah: blah;
hoo: blah == 12;
//moo: rgba(0,0,0,.5) + rgba(0,0,0,.6);
moo: rgba(0,0,0,.5) + 3;
}
$y: hey;
@mixin foo($x) {
foofoo: $x $y;
}
div {
@include foo();
hoo: rgba(1, 3, 3, .4);
blah: fade_out(#123, 1px);
flah: unquote("hello");
grah: quote(hello);
hrah: quote(mukluk);
mwah: join((), 2, "comma");
gwah: comparable(foo, bar);
}
\ No newline at end of file
......@@ -8,7 +8,7 @@
namespace Sass {
using std::map;
typedef Node (*Implementation)(const vector<Token>&, map<Token, Node>&);
typedef Node (*Implementation)(const vector<Token>&, map<Token, Node>&, vector<vector<Node>*>& registry);
typedef const char* str;
typedef str Function_Descriptor[];
......@@ -37,8 +37,8 @@ namespace Sass {
}
}
Node operator()(map<Token, Node>& bindings) const
{ return implementation(parameters, bindings); }
Node operator()(map<Token, Node>& bindings, vector<vector<Node>*>& registry) const
{ return implementation(parameters, bindings, registry); }
};
......@@ -47,111 +47,111 @@ namespace Sass {
// RGB Functions ///////////////////////////////////////////////////////
extern Function_Descriptor rgb_descriptor;
Node rgb(const vector<Token>& parameters, map<Token, Node>& bindings);
Node rgb(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor rgba_4_descriptor;
Node rgba_4(const vector<Token>& parameters, map<Token, Node>& bindings);
Node rgba_4(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor rgba_2_descriptor;
Node rgba_2(const vector<Token>& parameters, map<Token, Node>& bindings);
Node rgba_2(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor red_descriptor;
Node red(const vector<Token>& parameters, map<Token, Node>& bindings);
Node red(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor green_descriptor;
Node green(const vector<Token>& parameters, map<Token, Node>& bindings);
Node green(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor blue_descriptor;
Node blue(const vector<Token>& parameters, map<Token, Node>& bindings);
Node blue(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor mix_2_descriptor;
Node mix_2(const vector<Token>& parameters, map<Token, Node>& bindings);
Node mix_2(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor mix_3_descriptor;
Node mix_3(const vector<Token>& parameters, map<Token, Node>& bindings);
Node mix_3(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// HSL Functions ///////////////////////////////////////////////////////
extern Function_Descriptor hsla_descriptor;
Node hsla(const vector<Token>& parameters, map<Token, Node>& bindings);
Node hsla(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor hsl_descriptor;
Node hsl(const vector<Token>& parameters, map<Token, Node>& bindings);
Node hsl(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor invert_descriptor;
Node invert(const vector<Token>& parameters, map<Token, Node>& bindings);
Node invert(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// Opacity Functions ///////////////////////////////////////////////////
extern Function_Descriptor alpha_descriptor;
extern Function_Descriptor opacity_descriptor;
Node alpha(const vector<Token>& parameters, map<Token, Node>& bindings);
Node alpha(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor opacify_descriptor;
extern Function_Descriptor fade_in_descriptor;
Node opacify(const vector<Token>& parameters, map<Token, Node>& bindings);
Node opacify(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor transparentize_descriptor;
extern Function_Descriptor fade_out_descriptor;
Node transparentize(const vector<Token>& parameters, map<Token, Node>& bindings);
Node transparentize(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// String Functions ////////////////////////////////////////////////////
extern Function_Descriptor unquote_descriptor;
Node unquote(const vector<Token>& parameters, map<Token, Node>& bindings);
Node unquote(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor quote_descriptor;
Node quote(const vector<Token>& parameters, map<Token, Node>& bindings);
Node quote(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// Number Functions ////////////////////////////////////////////////////
extern Function_Descriptor percentage_descriptor;
Node percentage(const vector<Token>& parameters, map<Token, Node>& bindings);
Node percentage(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor round_descriptor;
Node round(const vector<Token>& parameters, map<Token, Node>& bindings);
Node round(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor ceil_descriptor;
Node ceil(const vector<Token>& parameters, map<Token, Node>& bindings);
Node ceil(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor floor_descriptor;
Node floor(const vector<Token>& parameters, map<Token, Node>& bindings);
Node floor(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor abs_descriptor;
Node abs(const vector<Token>& parameters, map<Token, Node>& bindings);
Node abs(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// List Functions //////////////////////////////////////////////////////
extern Function_Descriptor length_descriptor;
Node length(const vector<Token>& parameters, map<Token, Node>& bindings);
Node length(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor nth_descriptor;
Node nth(const vector<Token>& parameters, map<Token, Node>& bindings);
Node nth(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor join_2_descriptor;
Node join_2(const vector<Token>& parameters, map<Token, Node>& bindings);
Node join_2(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor join_3_descriptor;
Node join_3(const vector<Token>& parameters, map<Token, Node>& bindings);
Node join_3(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// Introspection Functions /////////////////////////////////////////////
extern Function_Descriptor type_of_descriptor;
Node type_of(const vector<Token>& parameters, map<Token, Node>& bindings);
Node type_of(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor unit_descriptor;
Node unit(const vector<Token>& parameters, map<Token, Node>& bindings);
Node unit(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor unitless_descriptor;
Node unitless(const vector<Token>& parameters, map<Token, Node>& bindings);
Node unitless(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
extern Function_Descriptor comparable_descriptor;
Node comparable(const vector<Token>& parameters, map<Token, Node>& bindings);
Node comparable(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
// Boolean Functions ///////////////////////////////////////////////////
extern Function_Descriptor not_descriptor;
Node not_impl(const vector<Token>& parameters, map<Token, Node>& bindings);
Node not_impl(const vector<Token>& parameters, map<Token, Node>& bindings, vector<vector<Node>*>& registry);
}
......
$x: bar;
$blux: inside blux;
div {
a: blah foo#{$x};
b: (1#{2+3}) + 4;
b: (1 (2+3)) + 4;
c: 1#{2 + 3} + 4;
d: type-of(false);
e: type-of(fa#{lse});
e: 12fa#{lse}345;
f: 12+#{3}, 12(#{3});
g: (12)34, 12(34);
h: #fff#{f};
j: $bl#{ux};
}
\ No newline at end of file
#include <stdio.h>
#include "sass_interface.h"
#include <sys/resource.h>
int main(int argc, char** argv)
{
if (argc < 2) {
printf("Hey, I need an input file!\n");
return 0;
}
int who = RUSAGE_SELF;
struct rusage r;
while (1) {
getrusage(who, &r);
printf("Memory usage: %ld\n", r.ru_maxrss);
struct sass_file_context* ctx = sass_new_file_context();
ctx->options.include_paths = "::/blah/bloo/fuzz:/slub/flub/chub::/Users/Aaron/dev/libsass/::::/huzz/buzz:::";
ctx->options.output_style = SASS_STYLE_NESTED;
ctx->input_path = argv[1];
sass_compile_file(ctx);
if (ctx->error_status) {
if (ctx->error_message) printf("%s", ctx->error_message);
else printf("An error occured; no error message available.\n");
sass_free_file_context(ctx);
break;
}
else if (ctx->output_string) {
sass_free_file_context(ctx);
continue;
}
else {
printf("Unknown internal error.\n");
sass_free_file_context(ctx);
break;
}
}
return 0;
}
\ No newline at end of file
......@@ -14,8 +14,9 @@ using std::endl;
namespace Sass {
size_t Node::allocations = 0;
size_t Node::destructed = 0;
Node Node::clone() const
Node Node::clone(vector<vector<Node>*>& registry) const
{
Node n(*this);
if (has_children) {
......@@ -23,8 +24,9 @@ namespace Sass {
++allocations;
n.content.children->reserve(size());
for (int i = 0; i < size(); ++i) {
n << at(i).clone();
n << at(i).clone(registry);
}
registry.push_back(n.content.children);
}
return n;
}
......@@ -270,6 +272,12 @@ namespace Sass {
return "!important";
} break;
case value_schema: {
string result;
for (int i = 0; i < size(); ++i) result += at(i).to_string("");
return result;
} break;
default: {
// return content.token.to_string();
if (!has_children && type != flags) return content.token.to_string();
......
......@@ -76,6 +76,8 @@ namespace Sass {
boolean,
important,
value_schema,
function_call,
mixin,
parameters,
......@@ -110,14 +112,17 @@ namespace Sass {
bool boolean_value;
} content;
const char* file_name;
static size_t allocations;
static size_t destructed;
void clear()
{
type = none; line_number = 0; has_children = false;
has_statements = false; has_blocks = false; has_expansions = false;
has_backref = false; from_variable = false; eval_me = false;
unquoted = false;
type = none; line_number = 0; file_name = 0;
has_children = false; has_statements = false; has_blocks = false;
has_expansions = false; has_backref = false; from_variable = false;
eval_me = false; unquoted = false;
}
size_t size() const
......@@ -135,6 +140,20 @@ namespace Sass {
return *this;
}
bool is_numeric() const
{
switch (type)
{
case number:
case numeric_percentage:
case numeric_dimension:
return true;
break;
default:
return false;
}
}
double numeric_value() const
{
switch (type)
......@@ -174,7 +193,7 @@ namespace Sass {
void emit_nested_css(stringstream& buf, size_t depth);
void emit_expanded_css(stringstream& buf, const string& prefix);
Node clone() const;
Node clone(vector<vector<Node>*>& registry) const;
void flatten();
Node()
......@@ -183,12 +202,13 @@ namespace Sass {
Node(Type t) // flags or booleans
{ clear(); type = t; }
Node(Type t, unsigned int ln, size_t s = 0) // nodes with children
Node(Type t, vector<vector<Node>*>& registry, unsigned int ln, size_t s = 0) // nodes with children
{
clear();
type = t;
line_number = ln;
content.children = new vector<Node>;
registry.push_back(content.children);
content.children->reserve(s);
has_children = true;
++allocations;
......@@ -220,12 +240,13 @@ namespace Sass {
content.dimension.unit = tok.begin;
}
Node(unsigned int ln, double r, double g, double b, double a = 1.0) // colors
Node(vector<vector<Node>*>& registry, unsigned int ln, double r, double g, double b, double a = 1.0) // colors
{
clear();
type = numeric_color;
line_number = ln;
content.children = new vector<Node>;
registry.push_back(content.children);
content.children->reserve(4);
content.children->push_back(Node(ln, r));
content.children->push_back(Node(ln, g));
......@@ -234,5 +255,7 @@ namespace Sass {
has_children = true;
++allocations;
}
~Node() { ++destructed; }
};
}
\ No newline at end of file
......@@ -5,6 +5,7 @@
#include <cstdlib>
#include <cmath>
#include "node.hpp"
#include "error.hpp"
using std::string;
using std::stringstream;
......@@ -31,6 +32,7 @@ namespace Sass {
return true;
} break;
case variable:
case identifier:
case uri:
case textual_percentage:
......@@ -82,11 +84,11 @@ namespace Sass {
return numeric_value() < rhs.numeric_value();
}
else {
// TO DO: throw an exception ("units don't match")
throw Error(Error::evaluation, line_number, file_name, "incompatible units");
}
}
else {
// TO DO: throw an exception ("incomparable types")
throw Error(Error::evaluation, line_number, file_name, "incomparable types");
}
}
......
......@@ -79,6 +79,15 @@ namespace Sass {
exactly<'-'>,
exactly<'_'> > > >(src);
}
// Match interpolant schemas
const char* value_schema(const char* src) {
// follows this pattern: ([xyz]*i[xyz]*)+
return one_plus< sequence< zero_plus< alternatives< identifier, number > >,
interpolant,
zero_plus< alternatives< identifier, number > > > >(src);
}
// Match CSS '@' keywords.
const char* at_keyword(const char* src) {
return sequence<exactly<'@'>, identifier>(src);
......
......@@ -274,6 +274,8 @@ namespace Sass {
// Match a CSS identifier.
const char* identifier(const char* src);
// Match interpolant schemas
const char* value_schema(const char* src);
// Match CSS '@' keywords.
const char* at_keyword(const char* src);
const char* import(const char* src);
......
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <iostream>
#include "document.hpp"
#include "eval_apply.hpp"
#include "error.hpp"
#include "sass_interface.h"
extern "C" {
using namespace std;
sass_context* sass_new_context()
{ return (sass_context*) malloc(sizeof(sass_context)); }
......@@ -34,10 +36,22 @@ extern "C" {
static char* process_document(Sass::Document& doc, int style)
{
using namespace Sass;
doc.parse_scss();
eval(doc.root, doc.context.global_env, doc.context.function_env);
cerr << "PARSED" << endl;
eval(doc.root, doc.context.global_env, doc.context.function_env, doc.context.registry);
cerr << "EVALUATED" << endl;
string output(doc.emit_css(static_cast<Document::CSS_Style>(style)));
cerr << "EMITTED" << endl;
cerr << "Allocations:\t" << Node::allocations << endl;
cerr << "Destructions:\t" << Node::destructed << endl;
cerr << "Registry size:\t" << doc.context.registry.size() << endl;
int i;
for (i = 0; i < doc.context.registry.size(); ++i) {
delete doc.context.registry[i];
}
cerr << "Deallocations:\t" << i << endl;
char* c_output = (char*) malloc(output.size() + 1);
strcpy(c_output, output.c_str());
......@@ -47,22 +61,70 @@ extern "C" {
int sass_compile(sass_context* c_ctx)
{
using namespace Sass;
// TO DO: CATCH ALL EXCEPTIONS
try {
Context cpp_ctx(c_ctx->options.include_paths);
Document doc(0, c_ctx->input_string, cpp_ctx);
c_ctx->output_string = process_document(doc, c_ctx->options.output_style);
c_ctx->error_message = 0;
c_ctx->error_status = 0;
}
catch (Error& e) {
stringstream msg_stream;
msg_stream << "ERROR -- " << e.file_name << ", line " << e.line_number << ": " << e.message << 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(bad_alloc& ba) {
stringstream msg_stream;
msg_stream << "ERROR -- 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;
}
// TO DO: CATCH EVERYTHING ELSE
return 0;
}
int sass_compile_file(sass_file_context* c_ctx)
{
using namespace Sass;
// TO DO: CATCH ALL EXCEPTIONS
try {
Context cpp_ctx(c_ctx->options.include_paths);
Document doc(c_ctx->input_path, 0, cpp_ctx);
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->error_message = 0;
c_ctx->error_status = 0;
}
catch (Error& e) {
stringstream msg_stream;
msg_stream << "ERROR -- " << e.file_name << ", line " << e.line_number << ": " << e.message << 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(bad_alloc& ba) {
stringstream msg_stream;
msg_stream << "ERROR -- 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;
}
// TO DO: CATCH EVERYTHING ELSE
return 0;
}
......
......@@ -16,27 +16,39 @@ struct sass_context {
char* input_string;
char* output_string;
struct sass_options options;
int error_status;
char* error_message;
};
struct sass_folder_context {
char* search_path;
char* output_path;
struct sass_options options;
int error_status;
char* error_message;
};
struct sass_file_context {
char* input_path;
char* output_string;
struct sass_options options;
int error_status;
char* error_message;
};
struct sass_context* sass_new_context ();
struct sass_folder_context* sass_new_folder_context ();
struct sass_file_context* sass_new_file_context ();
void sass_free_context (struct sass_context* ctx);
void sass_free_folder_context (struct sass_folder_context* ctx);
void sass_free_file_context (struct sass_file_context* ctx);
int sass_compile (struct sass_context*);
// int sass_folder_compile (struct sass_folder_context*);
int sass_file_compile (struct sass_file_context*);
//int sass_compile_folder (struct sass_folder_context*);
int sass_compile_file (struct sass_file_context*);
void sass_free_file_context (struct sass_file_context* ctx);
#ifdef __cplusplus
}
......
......@@ -34,7 +34,16 @@ int main(int argc, char** argv)
sass_compile_file(ctx);
if (ctx->error_status) {
if (ctx->error_message) printf("%s", ctx->error_message);
else printf("An error occured; no error message available.\n");
}
else if (ctx->output_string) {
printf("%s", ctx->output_string);
}
else {
printf("Unknown internal error.\n");
}
sass_free_file_context(ctx);
return 0;
......
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