Commit 5c7c3e96 by Andrew Nesbitt

Merge pull request #71 from enriclluelles/canon_libsass

Canon libsass
parents ed5b5dc3 eae642c9
[submodule "libsass"]
path = libsass
url = git://github.com/hcatlin/libsass.git
......@@ -4,20 +4,23 @@
#include <cstring>
#include <iostream>
#include <cstdlib>
#include "libsass/sass_interface.h"
#include "sass_context_wrapper.h"
using namespace v8;
using namespace std;
void WorkOnContext(uv_work_t* req) {
sass_context* ctx = static_cast<sass_context*>(req->data);
sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
sass_context* ctx = static_cast<sass_context*>(ctx_w->ctx);
sass_compile(ctx);
}
void MakeCallback(uv_work_t* req) {
HandleScope scope;
TryCatch try_catch;
sass_context* ctx = static_cast<sass_context*>(req->data);
sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
sass_context* ctx = static_cast<sass_context*>(ctx_w->ctx);
if (ctx->error_status == 0) {
// if no error, do callback(null, result)
......@@ -27,7 +30,7 @@ void MakeCallback(uv_work_t* req) {
Local<Value>::New(String::New(ctx->output_string))
};
ctx->callback->Call(Context::GetCurrent()->Global(), argc, argv);
ctx_w->callback->Call(Context::GetCurrent()->Global(), argc, argv);
} else {
// if error, do callback(error)
const unsigned argc = 1;
......@@ -35,31 +38,35 @@ void MakeCallback(uv_work_t* req) {
Local<Value>::New(String::New(ctx->error_message))
};
ctx->callback->Call(Context::GetCurrent()->Global(), argc, argv);
ctx_w->callback->Call(Context::GetCurrent()->Global(), argc, argv);
}
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
}
sass_free_context(ctx);
sass_free_context_wrapper(ctx_w);
}
Handle<Value> Render(const Arguments& args) {
HandleScope scope;
sass_context* ctx = sass_new_context();
sass_context_wrapper* ctx_w = sass_new_context_wrapper();
char *source;
String::AsciiValue astr(args[0]);
Local<Function> callback = Local<Function>::Cast(args[1]);
String::AsciiValue bstr(args[2]);
ctx->source_string = new char[strlen(*astr)+1];
strcpy(ctx->source_string, *astr);
source = new char[strlen(*astr)+1];
strcpy(source, *astr);
ctx->source_string = source;
ctx->options.include_paths = new char[strlen(*bstr)+1];
strcpy(ctx->options.include_paths, *bstr);
// ctx->options.output_style = SASS_STYLE_NESTED;
ctx->options.output_style = args[3]->Int32Value();
ctx->callback = Persistent<Function>::New(callback);
ctx->request.data = ctx;
ctx_w->ctx = ctx;
ctx_w->callback = Persistent<Function>::New(callback);
ctx_w->request.data = ctx_w;
int status = uv_queue_work(uv_default_loop(), &ctx->request, WorkOnContext, MakeCallback);
int status = uv_queue_work(uv_default_loop(), &ctx_w->request, WorkOnContext, MakeCallback);
assert(status == 0);
return Undefined();
......
......@@ -4,6 +4,7 @@
'target_name': 'binding',
'sources': [
'binding.cpp',
'sass_context_wrapper.cpp',
'libsass/constants.cpp',
'libsass/context.cpp',
'libsass/document.cpp',
......
Subproject commit 9c05850487ecc5ca187d204fcb9b1f443d66f0bf
src/Makefile
.DS_Store
tmp/
.sass-cache
sassc
build/*
*.o
*.a
a.out
bin/*
*.gem
Copyright (C) 2012 by Hampton Catlin
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
The following files in the spec were taken from the original Ruby Sass project which
is copyright Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein and under
the same license.
Copyright (C) 2012 by Hampton Catlin
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
The following files in the spec were taken from the original Ruby Sass project which
is copyright Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein and under
the same license.
CC = g++
CFLAGS = -Wall -O2 -fPIC
LDFLAGS = -fPIC
PREFIX = /usr/local
LIBDIR = $(PREFIX)/lib
SOURCES = constants.cpp context.cpp functions.cpp document.cpp \
document_parser.cpp eval_apply.cpp node.cpp \
node_factory.cpp node_emitters.cpp prelexer.cpp \
selector.cpp sass_interface.cpp
OBJECTS = $(SOURCES:.cpp=.o)
static: libsass.a
shared: libsass.so
libsass.a: $(OBJECTS)
ar rvs $@ $(OBJECTS)
libsass.so: $(OBJECTS)
$(CC) -shared $(LDFLAGS) -o $@ $(OBJECTS)
.cpp.o:
$(CC) $(CFLAGS) -c -o $@ $<
install: libsass.a
install -Dpm0755 $< $(DESTDIR)$(LIBDIR)/$<
install-shared: libsass.so
install -Dpm0755 $< $(DESTDIR)$(LIBDIR)/$<
clean:
rm -f $(OBJECTS) *.a *.so
.PHONY: static shared install install-shared clean
ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libsass.la
libsass_la_SOURCES = context.cpp functions.cpp document.cpp \
constants.cpp document_parser.cpp eval_apply.cpp node.cpp \
node_factory.cpp node_emitters.cpp prelexer.cpp \
selector.cpp sass_interface.cpp
libsass_la_LDFLAGS = -no-undefined -version-info 0:0:0
include_HEADERS = sass_interface.h
Libsass
=======
by Aaron Leung and Hampton Catlin (@hcatlin)
[![Build Status](https://secure.travis-ci.org/hcatlin/sassc.png?branch=master)](http://travis-ci.org/hcatlin/sassc)
http://github.com/hcatlin/libsass
Libsass is just a library, but if you want to RUN libsass,
then go to http://github.com/hcatlin/sassc or
http://github.com/hcatlin/sassruby or find your local
implementer.
About
-----
Libsass is a C/C++ port of the Sass CSS precompiler. The original version was written in Ruby, but this version is meant for efficiency and portability.
This library strives to be light, simple, and easy to build and integrate with a variety of platforms and languages.
Developing
----------
As you may have noticed, the libsass repo itself has
no executables and no tests. Oh noes! How can you develop???
Well, luckily, SassC is the official binary wrapper for
libsass and is *always* kept in sync. SassC uses a git submodule
to include libsass. When developing libsass, its best to actually
check out SassC and develop in that directory with the SassC spec
and tests there.
We even run Travis tests for SassC!
Usage
-----
While libsass is primarily implemented in C++, it provides a simple
C interface that is defined in [sass_inteface.h]. Its usage is pretty
straight forward.
First, you create a sass context struct. We use these objects to define
different execution parameters for the library. There are three
different context types.
sass_context // string-in-string-out compilation
sass_file_context // file-based compilation
sass_folder_context // full-folder multi-file
Each of the context's have slightly different behavior and are
implemented seperately. This does add extra work to implementing
a wrapper library, but we felt that a mixed-use context object
provides for too much implicit logic. What if you set "input_string"
AND "input_file"... what do we do? This would introduce bugs into
wrapper libraries that would be difficult to debug.
We anticipate that most adapters in most languages will define
their own logic for how to separate these use cases based on the
language. For instance, the original Ruby interface has a combined
interface, but is backed by three different processes.
To generate a context, use one of the following methods.
new_sass_context()
new_sass_file_context()
new_sass_folder_context()
Again, please see the sass_interface.h for more information.
And, to get even more information, then please see the implementations
in SassC and SassC-Ruby.
About Sass
----------
Sass is a CSS pre-processor language to add on exciting, new,
awesome features to CSS. Sass was the first language of its kind
and by far the most mature and up to date codebase.
Sass was originally created by the co-creator of this library,
Hampton Catlin (@hcatlin). The extension and continuing evolution
of the language has all been the result of years of work by Nathan
Weizenbaum (@nex3) and Chris Eppstein (@chriseppstein).
For more information about Sass itself, please visit http://sass-lang.com
Contribution Agreement
----------------------
Any contribution to the project are seen as copyright assigned to Hampton Catlin. Your contribution warrants that you have the right to assign copyright on your work. This is to ensure that the project remains free and open -- similar to the Apache Foundation.
Our license is designed to be as simple as possible.
#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();
}
size_t depth()
{
size_t d = 0;
Backtrace* p = parent;
while (p) {
++d;
p = p->parent;
}
return d-1;
}
};
}
\ No newline at end of file
#define SASS_COLOR_NAMES
namespace Sass {
const char* color_names[] =
{
"aliceblue",
"antiquewhite",
"aqua",
"aquamarine",
"azure",
"beige",
"bisque",
"black",
"blanchedalmond",
"blue",
"blueviolet",
"brown",
"burlywood",
"cadetblue",
"chartreuse",
"chocolate",
"coral",
"cornflowerblue",
"cornsilk",
"crimson",
"cyan",
"darkblue",
"darkcyan",
"darkgoldenrod",
"darkgray",
"darkgrey",
"darkgreen",
"darkkhaki",
"darkmagenta",
"darkolivegreen",
"darkorange",
"darkorchid",
"darkred",
"darksalmon",
"darkseagreen",
"darkslateblue",
"darkslategray",
"darkslategrey",
"darkturquoise",
"darkviolet",
"deeppink",
"deepskyblue",
"dimgray",
"dimgrey",
"dodgerblue",
"firebrick",
"floralwhite",
"forestgreen",
"fuchsia",
"gainsboro",
"ghostwhite",
"gold",
"goldenrod",
"gray",
"grey",
"green",
"greenyellow",
"honeydew",
"hotpink",
"indianred",
"indigo",
"ivory",
"khaki",
"lavender",
"lavenderblush",
"lawngreen",
"lemonchiffon",
"lightblue",
"lightcoral",
"lightcyan",
"lightgoldenrodyellow",
"lightgray",
"lightgrey",
"lightgreen",
"lightpink",
"lightsalmon",
"lightseagreen",
"lightskyblue",
"lightslategray",
"lightslategrey",
"lightsteelblue",
"lightyellow",
"lime",
"limegreen",
"linen",
"magenta",
"maroon",
"mediumaquamarine",
"mediumblue",
"mediumorchid",
"mediumpurple",
"mediumseagreen",
"mediumslateblue",
"mediumspringgreen",
"mediumturquoise",
"mediumvioletred",
"midnightblue",
"mintcream",
"mistyrose",
"moccasin",
"navajowhite",
"navy",
"oldlace",
"olive",
"olivedrab",
"orange",
"orangered",
"orchid",
"palegoldenrod",
"palegreen",
"paleturquoise",
"palevioletred",
"papayawhip",
"peachpuff",
"peru",
"pink",
"plum",
"powderblue",
"purple",
"red",
"rosybrown",
"royalblue",
"saddlebrown",
"salmon",
"sandybrown",
"seagreen",
"seashell",
"sienna",
"silver",
"skyblue",
"slateblue",
"slategray",
"slategrey",
"snow",
"springgreen",
"steelblue",
"tan",
"teal",
"thistle",
"tomato",
"turquoise",
"violet",
"wheat",
"white",
"whitesmoke",
"yellow",
"yellowgreen",
// sentinel value
0
};
const double color_values[] =
{
0xf0, 0xf8, 0xff,
0xfa, 0xeb, 0xd7,
0x00, 0xff, 0xff,
0x7f, 0xff, 0xd4,
0xf0, 0xff, 0xff,
0xf5, 0xf5, 0xdc,
0xff, 0xe4, 0xc4,
0x00, 0x00, 0x00,
0xff, 0xeb, 0xcd,
0x00, 0x00, 0xff,
0x8a, 0x2b, 0xe2,
0xa5, 0x2a, 0x2a,
0xde, 0xb8, 0x87,
0x5f, 0x9e, 0xa0,
0x7f, 0xff, 0x00,
0xd2, 0x69, 0x1e,
0xff, 0x7f, 0x50,
0x64, 0x95, 0xed,
0xff, 0xf8, 0xdc,
0xdc, 0x14, 0x3c,
0x00, 0xff, 0xff,
0x00, 0x00, 0x8b,
0x00, 0x8b, 0x8b,
0xb8, 0x86, 0x0b,
0xa9, 0xa9, 0xa9,
0xa9, 0xa9, 0xa9,
0x00, 0x64, 0x00,
0xbd, 0xb7, 0x6b,
0x8b, 0x00, 0x8b,
0x55, 0x6b, 0x2f,
0xff, 0x8c, 0x00,
0x99, 0x32, 0xcc,
0x8b, 0x00, 0x00,
0xe9, 0x96, 0x7a,
0x8f, 0xbc, 0x8f,
0x48, 0x3d, 0x8b,
0x2f, 0x4f, 0x4f,
0x2f, 0x4f, 0x4f,
0x00, 0xce, 0xd1,
0x94, 0x00, 0xd3,
0xff, 0x14, 0x93,
0x00, 0xbf, 0xff,
0x69, 0x69, 0x69,
0x69, 0x69, 0x69,
0x1e, 0x90, 0xff,
0xb2, 0x22, 0x22,
0xff, 0xfa, 0xf0,
0x22, 0x8b, 0x22,
0xff, 0x00, 0xff,
0xdc, 0xdc, 0xdc,
0xf8, 0xf8, 0xff,
0xff, 0xd7, 0x00,
0xda, 0xa5, 0x20,
0x80, 0x80, 0x80,
0x80, 0x80, 0x80,
0x00, 0x80, 0x00,
0xad, 0xff, 0x2f,
0xf0, 0xff, 0xf0,
0xff, 0x69, 0xb4,
0xcd, 0x5c, 0x5c,
0x4b, 0x00, 0x82,
0xff, 0xff, 0xf0,
0xf0, 0xe6, 0x8c,
0xe6, 0xe6, 0xfa,
0xff, 0xf0, 0xf5,
0x7c, 0xfc, 0x00,
0xff, 0xfa, 0xcd,
0xad, 0xd8, 0xe6,
0xf0, 0x80, 0x80,
0xe0, 0xff, 0xff,
0xfa, 0xfa, 0xd2,
0xd3, 0xd3, 0xd3,
0xd3, 0xd3, 0xd3,
0x90, 0xee, 0x90,
0xff, 0xb6, 0xc1,
0xff, 0xa0, 0x7a,
0x20, 0xb2, 0xaa,
0x87, 0xce, 0xfa,
0x77, 0x88, 0x99,
0x77, 0x88, 0x99,
0xb0, 0xc4, 0xde,
0xff, 0xff, 0xe0,
0x00, 0xff, 0x00,
0x32, 0xcd, 0x32,
0xfa, 0xf0, 0xe6,
0xff, 0x00, 0xff,
0x80, 0x00, 0x00,
0x66, 0xcd, 0xaa,
0x00, 0x00, 0xcd,
0xba, 0x55, 0xd3,
0x93, 0x70, 0xd8,
0x3c, 0xb3, 0x71,
0x7b, 0x68, 0xee,
0x00, 0xfa, 0x9a,
0x48, 0xd1, 0xcc,
0xc7, 0x15, 0x85,
0x19, 0x19, 0x70,
0xf5, 0xff, 0xfa,
0xff, 0xe4, 0xe1,
0xff, 0xe4, 0xb5,
0xff, 0xde, 0xad,
0x00, 0x00, 0x80,
0xfd, 0xf5, 0xe6,
0x80, 0x80, 0x00,
0x6b, 0x8e, 0x23,
0xff, 0xa5, 0x00,
0xff, 0x45, 0x00,
0xda, 0x70, 0xd6,
0xee, 0xe8, 0xaa,
0x98, 0xfb, 0x98,
0xaf, 0xee, 0xee,
0xd8, 0x70, 0x93,
0xff, 0xef, 0xd5,
0xff, 0xda, 0xb9,
0xcd, 0x85, 0x3f,
0xff, 0xc0, 0xcb,
0xdd, 0xa0, 0xdd,
0xb0, 0xe0, 0xe6,
0x80, 0x00, 0x80,
0xff, 0x00, 0x00,
0xbc, 0x8f, 0x8f,
0x41, 0x69, 0xe1,
0x8b, 0x45, 0x13,
0xfa, 0x80, 0x72,
0xf4, 0xa4, 0x60,
0x2e, 0x8b, 0x57,
0xff, 0xf5, 0xee,
0xa0, 0x52, 0x2d,
0xc0, 0xc0, 0xc0,
0x87, 0xce, 0xeb,
0x6a, 0x5a, 0xcd,
0x70, 0x80, 0x90,
0x70, 0x80, 0x90,
0xff, 0xfa, 0xfa,
0x00, 0xff, 0x7f,
0x46, 0x82, 0xb4,
0xd2, 0xb4, 0x8c,
0x00, 0x80, 0x80,
0xd8, 0xbf, 0xd8,
0xff, 0x63, 0x47,
0x40, 0xe0, 0xd0,
0xee, 0x82, 0xee,
0xf5, 0xde, 0xb3,
0xff, 0xff, 0xff,
0xf5, 0xf5, 0xf5,
0xff, 0xff, 0x00,
0x9a, 0xcd, 0x32,
// sentinel value
0xfff
};
}
\ No newline at end of file
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `floor' function. */
#undef HAVE_FLOOR
/* Define to 1 if you have the `getcwd' function. */
#undef HAVE_GETCWD
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if stdbool.h conforms to C99. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if the system has the type `_Bool'. */
#undef HAVE__BOOL
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
This source diff could not be displayed because it is too large. You can view the blob instead.
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.68])
AC_INIT([libsass], [1.0], [support@moovweb.com])
AC_CONFIG_SRCDIR([error.hpp])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
LT_INIT
# Checks for programs.
AC_PROG_CXX
AC_PROG_AWK
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_LIBTOOL
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([floor getcwd strtol])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
#include "constants.hpp"
namespace Sass {
namespace Constants {
// hidden variable name for the image path (for the image-url built-in)
extern const char image_path_var[] = "$[image path]";
// sass keywords
extern const char import_kwd[] = "@import";
extern const char mixin_kwd[] = "@mixin";
extern const char function_kwd[] = "@function";
extern const char return_kwd[] = "@return";
extern const char include_kwd[] = "@include";
extern const char content_kwd[] = "@content";
extern const char extend_kwd[] = "@extend";
extern const char if_kwd[] = "@if";
extern const char else_kwd[] = "@else";
extern const char if_after_else_kwd[] = "if";
extern const char for_kwd[] = "@for";
extern const char from_kwd[] = "from";
extern const char to_kwd[] = "to";
extern const char through_kwd[] = "through";
extern const char each_kwd[] = "@each";
extern const char in_kwd[] = "in";
extern const char while_kwd[] = "@while";
extern const char warn_kwd[] = "@warn";
extern const char default_kwd[] = "default";
// css standard units
extern const char em_kwd[] = "em";
extern const char ex_kwd[] = "ex";
extern const char px_kwd[] = "px";
extern const char cm_kwd[] = "cm";
extern const char mm_kwd[] = "mm";
extern const char pt_kwd[] = "pt";
extern const char pc_kwd[] = "pc";
extern const char deg_kwd[] = "deg";
extern const char rad_kwd[] = "rad";
extern const char grad_kwd[] = "grad";
extern const char ms_kwd[] = "ms";
extern const char s_kwd[] = "s";
extern const char Hz_kwd[] = "Hz";
extern const char kHz_kwd[] = "kHz";
// css functions and keywords
extern const char charset_kwd[] = "@charset";
extern const char media_kwd[] = "@media";
extern const char only_kwd[] = "only";
extern const char rgb_kwd[] = "rgb(";
extern const char url_kwd[] = "url(";
extern const char image_url_kwd[] = "image-url(";
extern const char important_kwd[] = "important";
extern const char pseudo_not_kwd[] = ":not(";
extern const char even_kwd[] = "even";
extern const char odd_kwd[] = "odd";
// css attribute-matching operators
extern const char tilde_equal[] = "~=";
extern const char pipe_equal[] = "|=";
extern const char caret_equal[] = "^=";
extern const char dollar_equal[] = "$=";
extern const char star_equal[] = "*=";
// relational & logical operators and constants
extern const char and_kwd[] = "and";
extern const char or_kwd[] = "or";
extern const char not_kwd[] = "not";
extern const char gt[] = ">";
extern const char gte[] = ">=";
extern const char lt[] = "<";
extern const char lte[] = "<=";
extern const char eq[] = "==";
extern const char neq[] = "!=";
extern const char true_kwd[] = "true";
extern const char false_kwd[] = "false";
// miscellaneous punctuation and delimiters
extern const char percent_str[] = "%";
extern const char empty_str[] = "";
extern const char slash_slash[] = "//";
extern const char slash_star[] = "/*";
extern const char star_slash[] = "*/";
extern const char hash_lbrace[] = "#{";
extern const char rbrace[] = "}";
extern const char rparen[] = ")";
extern const char sign_chars[] = "-+";
extern const char hyphen[] = "-";
extern const char ellipsis[] = "...";
// type names
extern const char numeric_name[] = "numeric value";
extern const char number_name[] = "number";
extern const char percentage_name[] = "percentage";
extern const char dimension_name[] = "numeric dimension";
extern const char string_name[] = "string";
extern const char bool_name[] = "bool";
extern const char color_name[] = "color";
extern const char list_name[] = "list";
extern const char arglist_name[] = "arglist";
}
}
\ No newline at end of file
#define SASS_CONSTANTS
namespace Sass {
namespace Constants {
// hidden variable name for the image path (for the image-url built-in)
extern const char image_path_var[];
// sass keywords
extern const char import_kwd[];
extern const char mixin_kwd[];
extern const char function_kwd[];
extern const char return_kwd[];
extern const char include_kwd[];
extern const char content_kwd[];
extern const char extend_kwd[];
extern const char if_kwd[];
extern const char else_kwd[];
extern const char if_after_else_kwd[];
extern const char for_kwd[];
extern const char from_kwd[];
extern const char to_kwd[];
extern const char through_kwd[];
extern const char each_kwd[];
extern const char in_kwd[];
extern const char while_kwd[];
extern const char warn_kwd[];
extern const char default_kwd[];
// css standard units
extern const char em_kwd[];
extern const char ex_kwd[];
extern const char px_kwd[];
extern const char cm_kwd[];
extern const char mm_kwd[];
extern const char pt_kwd[];
extern const char pc_kwd[];
extern const char deg_kwd[];
extern const char rad_kwd[];
extern const char grad_kwd[];
extern const char ms_kwd[];
extern const char s_kwd[];
extern const char Hz_kwd[];
extern const char kHz_kwd[];
// css functions and keywords
extern const char charset_kwd[];
extern const char media_kwd[];
extern const char only_kwd[];
extern const char rgb_kwd[];
extern const char url_kwd[];
extern const char image_url_kwd[];
extern const char important_kwd[];
extern const char pseudo_not_kwd[];
extern const char even_kwd[];
extern const char odd_kwd[];
// css attribute-matching operators
extern const char tilde_equal[];
extern const char pipe_equal[];
extern const char caret_equal[];
extern const char dollar_equal[];
extern const char star_equal[];
// relational & logical operators and constants
extern const char and_kwd[];
extern const char or_kwd[];
extern const char not_kwd[];
extern const char gt[];
extern const char gte[];
extern const char lt[];
extern const char lte[];
extern const char eq[];
extern const char neq[];
extern const char true_kwd[];
extern const char false_kwd[];
// miscellaneous punctuation and delimiters
extern const char percent_str[];
extern const char empty_str[];
extern const char slash_slash[];
extern const char slash_star[];
extern const char star_slash[];
extern const char hash_lbrace[];
extern const char rbrace[];
extern const char rparen[];
extern const char sign_chars[];
extern const char hyphen[];
extern const char ellipsis[];
// type names
extern const char numeric_name[];
extern const char number_name[];
extern const char percentage_name[];
extern const char dimension_name[];
extern const char string_name[];
extern const char bool_name[];
extern const char color_name[];
extern const char list_name[];
extern const char arglist_name[];
}
}
\ No newline at end of file
#ifdef _WIN32
#include <direct.h>
#define getcwd _getcwd
#define PATH_SEP ';'
#else
#include <unistd.h>
#define PATH_SEP ':'
#endif
#include <cstring>
#include <iostream>
#include <sstream>
#include "context.hpp"
#include "constants.hpp"
#include "color_names.hpp"
#include "prelexer.hpp"
namespace Sass {
using namespace Constants;
using std::pair; using std::cerr; using std::endl;
void Context::collect_include_paths(const char* paths_str)
{
const size_t wd_len = 1024;
char wd[wd_len];
include_paths.push_back(getcwd(wd, wd_len));
if (*include_paths.back().rbegin() != '/') include_paths.back() += '/';
if (paths_str) {
const char* beg = paths_str;
const char* end = Prelexer::find_first<PATH_SEP>(beg);
while (end) {
string path(beg, end - beg);
if (!path.empty()) {
if (*path.rbegin() != '/') path += '/';
include_paths.push_back(path);
}
beg = end + 1;
end = Prelexer::find_first<PATH_SEP>(beg);
}
string path(beg);
if (!path.empty()) {
if (*path.rbegin() != '/') path += '/';
include_paths.push_back(path);
}
}
// for (int i = 0; i < include_paths.size(); ++i) {
// cerr << include_paths[i] << endl;
// }
}
Context::Context(const char* paths_str, const char* img_path_str, bool sc)
: global_env(Environment()),
function_env(map<string, Function>()),
extensions(multimap<Node, Node>()),
pending_extensions(vector<pair<Node, Node> >()),
source_refs(vector<const char*>()),
include_paths(vector<string>()),
color_names_to_values(map<string, Node>()),
color_values_to_names(map<Node, string>()),
new_Node(Node_Factory()),
image_path(0),
ref_count(0),
has_extensions(false),
source_comments(sc)
{
register_functions();
collect_include_paths(paths_str);
setup_color_map();
string path_string(img_path_str ? img_path_str : "");
path_string = "'" + path_string + "/'";
image_path = new char[path_string.length() + 1];
std::strcpy(image_path, path_string.c_str());
// stash this hidden variable for the image-url built-in to use
global_env[Token::make(image_path_var)] = new_Node(Node::string_constant, "[IMAGE PATH]", 0, Token::make(image_path));
}
Context::~Context()
{
for (size_t i = 0; i < source_refs.size(); ++i) {
delete[] source_refs[i];
}
delete[] image_path;
new_Node.free();
}
inline void Context::register_function(Signature sig, Primitive ip)
{
Function f(const_cast<char*>(sig), ip, *this);
function_env[f.name] = f;
}
inline void Context::register_function(Signature sig, Primitive ip, size_t arity)
{
Function f(const_cast<char*>(sig), ip, *this);
std::stringstream stub;
stub << f.name << " " << arity;
function_env[stub.str()] = f;
}
inline void Context::register_overload_stub(string name)
{
function_env[name] = Function(name, true);
}
void Context::register_functions()
{
using namespace Functions;
// RGB Functions
register_function(rgb_sig, rgb);
register_overload_stub("rgba");
register_function(rgba_4_sig, rgba_4, 4);
register_function(rgba_2_sig, rgba_2, 2);
register_function(red_sig, red);
register_function(green_sig, green);
register_function(blue_sig, blue);
register_function(mix_sig, mix);
// HSL Functions
register_function(hsl_sig, hsl);
register_function(hsla_sig, hsla);
register_function(hue_sig, hue);
register_function(saturation_sig, saturation);
register_function(lightness_sig, lightness);
register_function(adjust_hue_sig, adjust_hue);
register_function(lighten_sig, lighten);
register_function(darken_sig, darken);
register_function(saturate_sig, saturate);
register_function(desaturate_sig, desaturate);
register_function(grayscale_sig, grayscale);
register_function(complement_sig, complement);
register_function(invert_sig, invert);
// Opacity Functions
register_function(alpha_sig, alpha);
register_function(opacity_sig, opacity);
register_function(opacify_sig, opacify);
register_function(fade_in_sig, fade_in);
register_function(transparentize_sig, transparentize);
register_function(fade_out_sig, fade_out);
// Other Color Functions
register_function(adjust_color_sig, adjust_color);
register_function(scale_color_sig, scale_color);
register_function(change_color_sig, change_color);
register_function(ie_hex_str_sig, ie_hex_str);
// String Functions
register_function(unquote_sig, unquote);
register_function(quote_sig, quote);
// Number Functions
register_function(percentage_sig, percentage);
register_function(round_sig, round);
register_function(ceil_sig, ceil);
register_function(floor_sig, floor);
register_function(abs_sig, abs);
// List Functions
register_function(length_sig, length);
register_function(nth_sig, nth);
register_function(index_sig, index);
register_function(join_sig, join);
register_function(append_sig, append);
register_overload_stub("compact");
register_function(compact_1_sig, compact_1, 1);
register_function(compact_n_sig, compact_n, 0);
register_function(compact_n_sig, compact_n, 2);
register_function(compact_n_sig, compact_n, 3);
register_function(compact_n_sig, compact_n, 4);
register_function(compact_n_sig, compact_n, 5);
register_function(compact_n_sig, compact_n, 6);
register_function(compact_n_sig, compact_n, 7);
register_function(compact_n_sig, compact_n, 8);
register_function(compact_n_sig, compact_n, 9);
register_function(compact_n_sig, compact_n, 10);
register_function(compact_n_sig, compact_n, 11);
register_function(compact_n_sig, compact_n, 12);
// Introspection Functions
register_function(type_of_sig, type_of);
register_function(unit_sig, unit);
register_function(unitless_sig, unitless);
register_function(comparable_sig, comparable);
// Boolean Functions
register_function(not_sig, not_impl);
register_function(if_sig, if_impl);
// Path Functions
register_function(image_url_sig, image_url);
}
void Context::setup_color_map()
{
size_t i = 0;
while (color_names[i]) {
string name(color_names[i]);
Node value(new_Node("[COLOR TABLE]", 0,
color_values[i*3],
color_values[i*3+1],
color_values[i*3+2],
1));
color_names_to_values[name] = value;
color_values_to_names[value] = name;
++i;
}
}
}
#define SASS_CONTEXT
//#ifndef SASS_ENVIRONMENT
#include "environment.hpp"
//#endif
#include <utility>
#ifndef SASS_NODE_FACTORY
#include "node_factory.hpp"
#endif
#ifndef SASS_FUNCTIONS
#include "functions.hpp"
#endif
namespace Sass {
using std::pair;
using std::map;
struct Context {
Environment global_env;
map<string, Function> function_env;
multimap<Node, Node> extensions;
vector<pair<Node, Node> > pending_extensions;
vector<const char*> source_refs; // all the source c-strings
vector<string> include_paths;
map<string, Node> color_names_to_values;
map<Node, string> color_values_to_names;
Node_Factory new_Node;
char* image_path;
size_t ref_count;
// string sass_path;
// string css_path;
bool has_extensions;
bool source_comments;
void collect_include_paths(const char* paths_str);
Context(const char* paths_str = 0, const char* img_path_str = 0, bool sc = false);
~Context();
void register_function(Signature sig, Primitive ip);
void register_function(Signature sig, Primitive ip, size_t arity);
void register_overload_stub(string name);
void register_functions();
void setup_color_map();
};
}
#ifdef _WIN32
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#include <cstdio>
#include <cstring>
#include "document.hpp"
#include "eval_apply.hpp"
#include "error.hpp"
#include <iostream>
#include <sstream>
#include <sys/stat.h>
namespace Sass {
Document::Document(Context& ctx) : context(ctx)
{ ++context.ref_count; }
Document::Document(const Document& doc)
: path(doc.path),
source(doc.source),
position(doc.position),
end(doc.end),
line(doc.line),
own_source(doc.own_source),
context(doc.context),
root(doc.root),
lexed(doc.lexed)
{ ++doc.context.ref_count; }
Document::~Document()
{ --context.ref_count; }
Document Document::make_from_file(Context& ctx, string path)
{
std::FILE *f;
const char* path_str = path.c_str();
struct stat st;
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)) {
// 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();
// if "_" + given + ".scss" isn't found ...
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) {
// then try given + ".scss"
string non_partial_filename(string(file_name_str) + ".scss");
tmp = folder + non_partial_filename;
path_str = tmp.c_str();
// if we still can't find the file, then throw an error
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) {
throw path;
}
}
}
}
f = std::fopen(path_str, "rb");
size_t len = st.st_size;
char* source = new char[len + 1];
size_t bytes_read = std::fread(source, sizeof(char), len, f);
if (bytes_read != len) {
std::cerr << "Warning: possible error reading from " << path << std::endl;
}
if (std::ferror(f)) throw path;
source[len] = '\0';
char* end = source + len;
if (std::fclose(f)) throw path;
const char *file_name_str = Prelexer::folders(path_str);
string include_path(path_str, file_name_str - path_str);
Document doc(ctx);
doc.path = path_str;
doc.line = 1;
doc.root = ctx.new_Node(Node::root, path, 1, 0);
doc.lexed = Token::make();
doc.own_source = true;
doc.source = source;
doc.end = end;
doc.position = source;
doc.context.source_refs.push_back(source);
return doc;
}
Document Document::make_from_source_chars(Context& ctx, const char* src, string path, bool own_source)
{
Document doc(ctx);
doc.path = path;
doc.line = 1;
doc.root = ctx.new_Node(Node::root, path, 1, 0);
doc.lexed = Token::make();
doc.own_source = own_source;
doc.source = src;
doc.end = src + std::strlen(src);
doc.position = src;
if (own_source) doc.context.source_refs.push_back(src);
return doc;
}
Document Document::make_from_token(Context& ctx, Token t, string path, size_t line_number)
{
Document doc(ctx);
doc.path = path;
doc.line = line_number;
doc.root = ctx.new_Node(Node::root, path, 1, 0);
doc.lexed = Token::make();
doc.own_source = false;
doc.source = t.begin;
doc.end = t.end;
doc.position = doc.source;
return doc;
}
void Document::throw_syntax_error(string message, size_t ln)
{ throw Error(Error::syntax, path, ln ? ln : line, message); }
void Document::throw_read_error(string message, size_t ln)
{ throw Error(Error::read, path, ln ? ln : line, message); }
using std::string;
using std::stringstream;
using std::endl;
string Document::emit_css(CSS_Style style) {
stringstream output;
switch (style) {
case echo:
root.echo(output);
break;
case nested:
root.emit_nested_css(output, 0, true, false, context.source_comments);
break;
case expanded:
root.emit_expanded_css(output, "");
break;
case compressed:
root.emit_compressed_css(output);
break;
default:
break;
}
string retval(output.str());
// trim trailing whitespace
if (!retval.empty()) {
size_t newlines = 0;
size_t i = retval.length();
while (i--) {
if (retval[i] == '\n') {
++newlines;
continue;
}
else {
break;
}
}
retval.resize(retval.length() - newlines);
retval += "\n";
}
return retval;
}
}
#define SASS_DOCUMENT
#include <map>
#ifndef SASS_PRELEXER
#include "prelexer.hpp"
#endif
#ifndef SASS_NODE
#include "node.hpp"
#endif
#ifndef SASS_CONTEXT
#include "context.hpp"
#endif
struct Selector_Lookahead {
const char* found;
bool has_interpolants;
};
namespace Sass {
using std::string;
using std::vector;
using std::map;
using namespace Prelexer;
struct Document {
enum CSS_Style { nested, expanded, compact, compressed, echo };
string path;
const char* source;
const char* position;
const char* end;
size_t line;
bool own_source;
Context& context;
Node root;
Token lexed;
private:
// force the use of the "make_from_..." factory funtions
Document(Context& ctx);
public:
Document(const Document& doc);
~Document();
static Document make_from_file(Context& ctx, string path);
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);
template <prelexer mx>
const char* peek(const char* start = 0)
{
if (!start) start = position;
const char* after_whitespace;
if (mx == block_comment) {
after_whitespace = // start;
zero_plus< alternatives<spaces, line_comment> >(start);
}
else if (/*mx == ancestor_of ||*/ mx == no_spaces) {
after_whitespace = position;
}
else if (mx == spaces || mx == ancestor_of) {
after_whitespace = mx(start);
if (after_whitespace) {
return after_whitespace;
}
else {
return 0;
}
}
else if (mx == optional_spaces) {
after_whitespace = optional_spaces(start);
}
else {
after_whitespace = spaces_and_comments(start);
}
const char* after_token = mx(after_whitespace);
if (after_token) {
return after_token;
}
else {
return 0;
}
}
template <prelexer mx>
const char* lex()
{
const char* after_whitespace;
if (mx == block_comment) {
after_whitespace = // position;
zero_plus< alternatives<spaces, line_comment> >(position);
}
else if (mx == ancestor_of || mx == no_spaces) {
after_whitespace = position;
}
else if (mx == spaces) {
after_whitespace = spaces(position);
if (after_whitespace) {
line += count_interval<'\n'>(position, after_whitespace);
lexed = Token::make(position, after_whitespace);
return position = after_whitespace;
}
else {
return 0;
}
}
else if (mx == optional_spaces) {
after_whitespace = optional_spaces(position);
}
else {
after_whitespace = spaces_and_comments(position);
}
const char* after_token = mx(after_whitespace);
if (after_token) {
line += count_interval<'\n'>(position, after_token);
lexed = Token::make(after_whitespace, after_token);
return position = after_token;
}
else {
return 0;
}
}
void parse_scss();
Node parse_import();
Node parse_include();
Node parse_mixin_definition();
Node parse_function_definition();
Node parse_parameters();
Node parse_parameter(Node::Type);
Node parse_mixin_call(Node::Type inside_of = Node::none);
Node parse_arguments();
Node parse_argument(Node::Type);
Node parse_assignment();
Node parse_propset();
Node parse_ruleset(Selector_Lookahead lookahead, Node::Type inside_of = Node::none);
Node parse_selector_schema(const char* end_of_selector);
Node parse_selector_group();
Node parse_selector();
Node parse_selector_combinator();
Node parse_simple_selector_sequence();
Node parse_simple_selector();
Node parse_pseudo();
Node parse_attribute_selector();
Node parse_block(Node surrounding_ruleset, Node::Type inside_of = Node::none);
Node parse_rule();
Node parse_values();
Node parse_list();
Node parse_comma_list();
Node parse_space_list();
Node parse_disjunction();
Node parse_conjunction();
Node parse_relation();
Node parse_expression();
Node parse_term();
Node parse_factor();
Node parse_value();
Node parse_function_call();
Node parse_string();
Node parse_value_schema();
Node parse_identifier_schema();
Node parse_url_schema();
Node parse_if_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none);
Node parse_for_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none);
Node parse_each_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none);
Node parse_while_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none);
Node parse_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none);
Node parse_media_query(Node::Type inside_of = Node::none);
Node parse_media_expression();
Node parse_warning();
Selector_Lookahead lookahead_for_selector(const char* start = 0);
Selector_Lookahead lookahead_for_extension_target(const char* start = 0);
void throw_syntax_error(string message, size_t ln = 0);
void throw_read_error(string message, size_t ln = 0);
string emit_css(CSS_Style style);
};
}
#define SASS_ENVIRONMENT
#include <map>
#ifndef SASS_NODE
#include "node.hpp"
#endif
namespace Sass {
using std::map;
struct Environment {
map<Token, Node> current_frame;
Environment* parent;
Environment* global;
Environment()
: current_frame(map<Token, Node>()), parent(0), global(0)
{ }
void link(Environment& env)
{
parent = &env;
global = parent->global ? parent->global : parent;
}
bool query(const Token& key) const
{
if (current_frame.count(key)) return true;
else if (parent) return parent->query(key);
else return false;
}
Node& operator[](const Token& key)
{
if (current_frame.count(key)) return current_frame[key];
else if (parent) return (*parent)[key];
else return current_frame[key];
}
void print()
{
for (map<Token, Node>::iterator i = current_frame.begin(); i != current_frame.end(); ++i) {
cerr << i->first.to_string() << ": " << i->second.to_string() << endl;
}
if (parent) {
cerr << "---" << endl;
parent->print();
}
}
};
}
\ No newline at end of file
#define SASS_ERROR
namespace Sass {
struct Error {
enum Type { read, write, syntax, evaluation };
Type type;
string path;
size_t line;
string message;
Error(Type type, string path, size_t line, string message)
: type(type), path(path), line(line), message(message)
{ }
};
}
\ No newline at end of file
#define SASS_EVAL_APPLY
#include <map>
#ifndef SASS_NODE
#include "node.hpp"
#endif
#ifndef SASS_CONTEXT
#include "context.hpp"
#endif
#ifndef SASS_BACKTRACE
#include "backtrace.hpp"
#endif
namespace Sass {
using std::map;
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());
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(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_arguments(Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, Backtrace& bt);
Node eval_function(string name, Node stm, Environment& bindings, Node_Factory& new_Node, Context& ctx, Backtrace& bt, bool toplevel = false);
Node reduce(Node list, size_t head, Node acc, Node_Factory& new_Node, Backtrace& bt);
double operate(Node op, double lhs, double rhs, Backtrace& bt);
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, Backtrace& bt, string& path, size_t line);
Node expand_selector(Node sel, Node pre, Node_Factory& new_Node);
Node expand_backref(Node sel, Node pre);
void extend(Node expr, multimap<Node, Node>& extension_requests, Node_Factory& new_Node);
void extend_selectors(vector<pair<Node, Node> >&, multimap<Node, Node>&, Node_Factory&);
Node generate_extension(Node extendee, Node extender, Node_Factory& new_Node);
Node selector_prefix(Node sel, Node_Factory& new_Node);
Node selector_base(Node sel);
Node selector_butfirst(Node sel, Node_Factory& new_Node);
Node selector_butlast(Node sel, Node_Factory& new_Node);
void to_lowercase(string& s);
}
\ No newline at end of file
require 'mkmf'
# .. more stuff
#$LIBPATH.push(Config::CONFIG['libdir'])
$CFLAGS << " #{ENV["CFLAGS"]}"
$LIBS << " #{ENV["LIBS"]}"
create_makefile("libsass")
#define SASS_FUNCTIONS
#include <cstring>
#include <map>
#ifndef SASS_NODE
#include "node.hpp"
#endif
#ifndef SASS_BACKTRACE
#include "backtrace.hpp"
#endif
namespace Sass {
struct Environment;
struct Context;
struct Node_Factory;
using std::map;
typedef Node (*Primitive)(const Node, Environment&, Node_Factory&, Backtrace& bt, string&, size_t);
typedef const char Signature[];
struct Function {
string name;
Node parameters;
Node parameter_names;
Node definition;
Primitive primitive;
bool overloaded;
Function()
{ /* TO DO: set up the generic callback here */ }
// for user-defined functions
Function(Node def)
: name(def[0].to_string()),
parameters(def[1]),
definition(def),
primitive(0),
overloaded(false)
{ }
// Stub for overloaded primitives
Function(string name, bool overloaded = true)
: name(name),
parameters(Node()),
definition(Node()),
primitive(0),
overloaded(overloaded)
{ }
Function(char* signature, Primitive ip, Context& ctx);
Node operator()(Environment& bindings, Node_Factory& new_Node, Backtrace& bt, string& path, size_t line) const
{
if (primitive) return primitive(parameters, bindings, new_Node, bt, path, line);
else return Node();
}
};
namespace Functions {
// RGB Functions ///////////////////////////////////////////////////////
extern Signature rgb_sig;
Node rgb(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature rgba_4_sig;
Node rgba_4(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature rgba_2_sig;
Node rgba_2(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature red_sig;
Node red(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature green_sig;
Node green(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature blue_sig;
Node blue(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature mix_sig;
Node mix(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
// HSL Functions ///////////////////////////////////////////////////////
extern Signature hsl_sig;
Node hsl(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature hsla_sig;
Node hsla(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature hue_sig;
Node hue(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature saturation_sig;
Node saturation(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature lightness_sig;
Node lightness(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature adjust_hue_sig;
Node adjust_hue(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature lighten_sig;
Node lighten(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature darken_sig;
Node darken(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature saturate_sig;
Node saturate(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature desaturate_sig;
Node desaturate(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature grayscale_sig;
Node grayscale(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature complement_sig;
Node complement(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature invert_sig;
Node invert(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
// Opacity Functions ///////////////////////////////////////////////////
extern Signature alpha_sig;
Node alpha(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature opacity_sig;
Node opacity(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature opacify_sig;
Node opacify(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature fade_in_sig;
Node fade_in(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature transparentize_sig;
Node transparentize(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature fade_out_sig;
Node fade_out(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
// Other Color Functions ///////////////////////////////////////////////
extern Signature adjust_color_sig;
Node adjust_color(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature scale_color_sig;
Node scale_color(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature change_color_sig;
Node change_color(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature ie_hex_str_sig;
Node ie_hex_str(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
// String Functions ////////////////////////////////////////////////////
extern Signature unquote_sig;
Node unquote(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature quote_sig;
Node quote(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
// Number Functions ////////////////////////////////////////////////////
extern Signature percentage_sig;
Node percentage(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature round_sig;
Node round(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature ceil_sig;
Node ceil(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature floor_sig;
Node floor(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature abs_sig;
Node abs(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
// List Functions //////////////////////////////////////////////////////
extern Signature length_sig;
Node length(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature nth_sig;
Node nth(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature index_sig;
Node index(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature join_sig;
Node join(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature append_sig;
Node append(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature compact_1_sig;
Node compact_1(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature compact_n_sig;
Node compact_n(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
// Introspection Functions /////////////////////////////////////////////
extern Signature type_of_sig;
Node type_of(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature unit_sig;
Node unit(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature unitless_sig;
Node unitless(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature comparable_sig;
Node comparable(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
// Boolean Functions ///////////////////////////////////////////////////
extern Signature not_sig;
Node not_impl(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
extern Signature if_sig;
Node if_impl(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
// Path Functions //////////////////////////////////////////////////////
extern Signature image_url_sig;
Node image_url(const Node, Environment&, Node_Factory&, Backtrace&, string& path, size_t line);
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 3337 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.2])
m4_define([LT_PACKAGE_REVISION], [1.3337])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.2'
macro_revision='1.3337'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
#include "node_factory.hpp"
namespace Sass {
Node_Impl* Node_Factory::alloc_Node_Impl(Node::Type type, string path, size_t line)
{
Node_Impl* ip = new Node_Impl();
ip->type = type;
if (type == Node::backref) ip->has_backref = true;
ip->path = path;
ip->line = line;
pool_.push_back(ip);
return ip;
}
// returns a deep-copy of its argument
Node_Impl* Node_Factory::alloc_Node_Impl(Node_Impl* ip)
{
Node_Impl* ip_cpy = new Node_Impl(*ip);
pool_.push_back(ip_cpy);
if (ip_cpy->has_children) {
for (size_t i = 0, S = ip_cpy->size(); i < S; ++i) {
Node n(ip_cpy->at(i));
ip_cpy->at(i) = (*this)(n);
}
}
return ip_cpy;
}
// returns a deep-copy of its argument, but uses the path and line that are passed in
Node_Impl* Node_Factory::alloc_Node_Impl(string& path, size_t line, Node_Impl* ip)
{
Node_Impl* ip_cpy = new Node_Impl(*ip);
pool_.push_back(ip_cpy);
if (ip_cpy->has_children) {
for (size_t i = 0, S = ip_cpy->size(); i < S; ++i) {
Node n(ip_cpy->at(i));
ip_cpy->at(i) = (*this)(path, line, n);
}
}
return ip_cpy;
}
// for cloning nodes
Node Node_Factory::operator()(const Node& n1)
{
Node_Impl* ip_cpy = alloc_Node_Impl(n1.ip_); // deep-copy the implementation object
return Node(ip_cpy);
}
// for cloning nodes and resetting their path and line-number fields
Node Node_Factory::operator()(string& path, size_t line, const Node& n1)
{
Node_Impl* ip_cpy = alloc_Node_Impl(path, line, n1.ip_); // deep-copy the implementation object
ip_cpy->path = path;
ip_cpy->line = line;
return Node(ip_cpy);
}
// for making leaf nodes out of terminals/tokens
Node Node_Factory::operator()(Node::Type type, string path, size_t line, Token t)
{
Node_Impl* ip = alloc_Node_Impl(type, path, line);
ip->value.token = t;
return Node(ip);
}
// for making boolean values or interior nodes that have children
Node Node_Factory::operator()(Node::Type type, string path, size_t line, size_t size)
{
Node_Impl* ip = alloc_Node_Impl(type, path, line);
if (type == Node::boolean) ip->value.boolean = size;
else ip->children.reserve(size);
return Node(ip);
}
// for making nodes representing numbers
Node Node_Factory::operator()(string path, size_t line, double v, Node::Type type)
{
Node_Impl* ip = alloc_Node_Impl(type, path, line);
ip->value.numeric = v;
return Node(ip);
}
// for making nodes representing numeric dimensions (e.g. 5px, 3em)
Node Node_Factory::operator()(string path, size_t line, double v, const Token& t)
{
Node_Impl* ip = alloc_Node_Impl(Node::numeric_dimension, path, line);
ip->value.dimension.numeric = v;
ip->value.dimension.unit = t;
return Node(ip);
}
// for making nodes representing rgba color quads
Node Node_Factory::operator()(string path, size_t line, double r, double g, double b, double a)
{
Node color((*this)(Node::numeric_color, path, line, 4));
color << (*this)(path, line, r)
<< (*this)(path, line, g)
<< (*this)(path, line, b)
<< (*this)(path, line, a);
return color;
}
void Node_Factory::free()
{ for (size_t i = 0, S = pool_.size(); i < S; ++i) delete pool_[i]; }
}
\ No newline at end of file
#define SASS_NODE_FACTORY
#include <vector>
#ifndef SASS_NODE
#include "node.hpp"
#endif
namespace Sass {
using namespace std;
struct Token;
struct Node_Impl;
class Node_Factory {
vector<Node_Impl*> pool_;
Node_Impl* alloc_Node_Impl(Node::Type type, string file, size_t line);
// returns a deep-copy of its argument
Node_Impl* alloc_Node_Impl(Node_Impl* ip);
Node_Impl* alloc_Node_Impl(string& path, size_t line, Node_Impl* ip);
public:
// for cloning nodes
Node operator()(const Node& n1);
Node operator()(string& path, size_t line, const Node& n1);
// for making leaf nodes out of terminals/tokens
Node operator()(Node::Type type, string file, size_t line, Token t);
// for making boolean values or interior nodes that have children
Node operator()(Node::Type type, string file, size_t line, size_t size);
// for making nodes representing numbers and numeric percentages
Node operator()(string file, size_t line, double v, Node::Type type = Node::number);
// for making nodes representing numeric dimensions (e.g. 5px, 3em)
Node operator()(string file, size_t line, double v, const Token& t);
// for making nodes representing rgba color quads
Node operator()(string file, size_t line, double r, double g, double b, double a = 1.0);
void free();
};
}
\ No newline at end of file
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#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*) calloc(1, sizeof(sass_context)); }
void sass_free_context(sass_context* ctx)
{
if (ctx->output_string) free(ctx->output_string);
if (ctx->error_message) free(ctx->error_message);
free(ctx);
}
sass_file_context* sass_new_file_context()
{ return (sass_file_context*) calloc(1, sizeof(sass_file_context)); }
void sass_free_file_context(sass_file_context* ctx)
{
if (ctx->output_string) free(ctx->output_string);
if (ctx->error_message) free(ctx->error_message);
free(ctx);
}
sass_folder_context* sass_new_folder_context()
{ return (sass_folder_context*) calloc(1, sizeof(sass_folder_context)); }
static char* process_document(Sass::Document& doc, int style)
{
using namespace Sass;
Backtrace root_trace(0, "", 0, "");
doc.parse_scss();
expand(doc.root,
Node(),
doc.context.global_env,
doc.context.function_env,
doc.context.new_Node,
doc.context,
root_trace);
// 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);
string output(doc.emit_css(static_cast<Document::CSS_Style>(style)));
char* c_output = (char*) malloc(output.size() + 1);
strcpy(c_output, output.c_str());
return c_output;
}
int sass_compile(sass_context* c_ctx)
{
using namespace Sass;
try {
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;
// Document doc(0, c_ctx->input_string, cpp_ctx);
Document doc(Document::make_from_source_chars(cpp_ctx, c_ctx->source_string));
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 << e.path << ":" << e.line << ": error: " << 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 << "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;
Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path, c_ctx->options.source_comments);
try {
Document doc(Document::make_from_file(cpp_ctx, 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;
}
catch (Error& e) {
stringstream msg_stream;
msg_stream << e.path << ":" << e.line << ": error: " << 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 << "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());
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_folder(sass_folder_context* c_ctx)
{
return 1;
}
}
#define SASS_INTERFACE
#include <node.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SASS_STYLE_NESTED 0
#define SASS_STYLE_EXPANDED 1
#define SASS_STYLE_COMPACT 2
#define SASS_STYLE_COMPRESSED 3
struct sass_options {
int output_style;
int source_comments; // really want a bool, but C doesn't have them
char* include_paths;
char* image_path;
};
struct sass_context {
char* source_string;
char* output_string;
struct sass_options options;
int error_status;
char* error_message;
uv_work_t request;
v8::Persistent<v8::Function> callback;
};
struct sass_file_context {
char* input_path;
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_context* sass_new_context (void);
struct sass_file_context* sass_new_file_context (void);
struct sass_folder_context* sass_new_folder_context (void);
void sass_free_context (struct sass_context* ctx);
void sass_free_file_context (struct sass_file_context* ctx);
void sass_free_folder_context (struct sass_folder_context* ctx);
int sass_compile (struct sass_context* ctx);
int sass_compile_file (struct sass_file_context* ctx);
int sass_compile_folder (struct sass_folder_context* ctx);
#ifdef __cplusplus
}
#endif
#include <set>
#include "selector.hpp"
namespace Sass {
using namespace std;
Node normalize_selector(Node s, Node_Factory& new_Node)
{
switch (s.type())
{
case Node::selector_group: {
Node normalized(new_Node(Node::selector_group, s.path(), s.line(), 1));
set<Node> normalizer;
for (size_t i = 0, S = s.size(); i < S; ++i)
normalizer.insert(normalize_selector(s[i], new_Node));
for (set<Node>::iterator i = normalizer.begin(); i != normalizer.end(); ++i)
normalized << *i;
return normalized;
} break;
case Node::selector: {
Node normalized(new_Node(Node::selector, s.path(), s.line(), s.size()));
for (size_t i = 0, S = s.size(); i < S; ++i)
normalized << normalize_selector(s[i], new_Node);
return normalized;
} break;
case Node::simple_selector_sequence: {
Node normalized(new_Node(Node::simple_selector_sequence, s.path(), s.line(), 1));
set<Node> normalizer;
size_t i = 0;
if (!selector_is_qualifier(s[0])) {
normalized << s[0];
i = 1;
}
for (size_t S = s.size(); i < S; ++i)
normalizer.insert(normalize_selector(s[i], new_Node));
for (set<Node>::iterator i = normalizer.begin(); i != normalizer.end(); ++i)
normalized << *i;
return normalized;
} break;
default: {
return s;
} break;
}
return s;
}
// Remove duplicate selectors from a selector group. Used when extending.
Node remove_duplicate_selectors(Node group, Node_Factory& new_Node)
{
if (group.type() != Node::selector_group) return group;
Node filtered(new_Node(Node::selector_group, group.path(), group.line(), 1));
for (size_t i = 0, S = group.size(); i < S; ++i) {
bool found_dup = false;
for (size_t j = 0; j < filtered.size(); ++j) {
if (group[i] == filtered[j]) {
found_dup = true;
break;
}
}
if (!found_dup) filtered << group[i];
}
return filtered;
}
bool selector_is_qualifier(Node s)
{
switch (s.type())
{
case Node::pseudo:
case Node::pseudo_negation:
case Node::functional_pseudo:
case Node::attribute_selector: {
return true;
} break;
case Node::simple_selector: {
if ((*s.token().begin == '.') || (*s.token().begin == '#')) return true;
} break;
default: {
return false;
} break;
}
return false;
}
// Node selector_is_specialization_of(Node s, Node t)
// {
// }
}
\ No newline at end of file
#ifndef SASS_NODE
#include "node.hpp"
#endif
#ifndef SASS_NODE_FACTORY
#include "node_factory.hpp"
#endif
namespace Sass {
Node normalize_selector(Node s, Node_Factory& new_Node);
Node remove_duplicate_selectors(Node group, Node_Factory& new_Node);
bool selector_is_qualifier(Node s);
}
\ No newline at end of file
#if _MSC_VER >= 1600
#include <unordered_map>
#else
#include <tr1/unordered_map>
#endif
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#ifndef SASS_NODE
#include "node.hpp"
#endif
#include "node_factory.hpp"
int main()
{
using namespace Sass;
using namespace std;
cout << sizeof(Node_Impl*) << endl;
cout << sizeof(Node) << endl;
cout << sizeof(Node_Impl) << endl << endl;
Node_Factory new_Node = Node_Factory();
Node interior(new_Node(Node::block, "", 0, 3));
cout << interior.size() << endl;
cout << interior.has_children() << endl;
cout << interior.should_eval() << endl << endl;
Node num(new_Node("", 0, 255, 123, 32));
Node num2(new_Node("", 0, 255, 123, 32));
Node num3(new_Node("", 0, 255, 122, 20, .75));
cout << num.size() << endl;
cout << num.has_children() << endl;
cout << num.has_statements() << endl << endl;
cout << num[1].is_numeric() << endl;
cout << num[1].numeric_value() << endl << endl;
cout << (num == num2) << endl;
cout << (num == num3) << endl << endl;
cout << (num3[2] < num2[2]) << endl;
cout << (num2[3] < num3[3]) << endl << endl;
cout << (num2[2] >= num3[2]) << endl;
cout << (num2[3] != num3[3]) << endl << endl;
Node num4(new_Node(num3));
cout << num3[3].numeric_value() << endl;
cout << num4[3].numeric_value() << endl;
num4[3] = new_Node("", 0, 0.4567);
cout << num3[3].numeric_value() << endl;
cout << num4[3].numeric_value() << endl << endl;
Node block1(new_Node(Node::block, "block", 1, 2));
block1 << num2 << num4;
Node block2(new_Node(block1));
cout << (block1 == block2) << endl;
cout << block1[1][3].numeric_value() << endl;
cout << block2[1][3].numeric_value() << endl;
block2[1][3] = new_Node("", 0, .9876);
cout << block1[1][3].numeric_value() << endl;
cout << block2[1][3].numeric_value() << endl << endl;
map<Node, string> dict;
Node n(new_Node("", 0, 42));
Node m(new_Node("", 0, 41));
dict[n] = "hello";
dict[m] = "goodbye";
cout << dict[m] << " " << dict[n] << endl;
cout << "Lexicographical comparison: " << endl;
cout << lexicographical_compare(num2.begin(), num2.end(),
num3.begin(), num3.end())
<< endl;
cout << lexicographical_compare(num.begin(), num.end(),
num2.begin(), num2.end())
<< endl;
cout << lexicographical_compare(num3.begin(), num3.end(),
num.begin(), num.end())
<< endl << endl;
new_Node.free();
return 0;
}
\ No newline at end of file
#include "sass_context_wrapper.h"
#include <cstdlib>
extern "C" {
using namespace std;
sass_context_wrapper* sass_new_context_wrapper()
{
return (sass_context_wrapper*) calloc(1, sizeof(sass_context_wrapper));
}
void sass_free_context_wrapper(sass_context_wrapper* ctx_w)
{
if (ctx_w->ctx) sass_free_context(ctx_w->ctx);
free(ctx_w);
}
}
#include "libsass/sass_interface.h"
#include <node.h>
#ifdef __cplusplus
extern "C" {
#endif
struct sass_context_wrapper {
sass_context* ctx;
uv_work_t request;
v8::Persistent<v8::Function> callback;
};
struct sass_context_wrapper* sass_new_context_wrapper(void);
void sass_free_context_wrapper(struct sass_context_wrapper* ctx);
#ifdef __cplusplus
}
#endif
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