Commit 901b5264 by Dean Mao

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

parents 4852ae17 038c77f9
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.
This diff is collapsed. Click to expand it.
......@@ -12,7 +12,7 @@ all: $(OBJECTS)
ar rvs libsass.a $(OBJECTS)
shared: $(OBJECTS)
gcc -shared -o libsass.so *.o
$(CC) -shared -o libsass.so *.o
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
......
ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libsass.la
libsass_la_SOURCES = context.cpp functions.cpp document.cpp \
document_parser.cpp eval_apply.cpp node.cpp \
node_factory.cpp node_emitters.cpp prelexer.cpp \
sass_interface.cpp
libsass_la_LDFLAGS = -no-undefined -version-info 0:0:0
include_HEADERS = sass_interface.h
/* 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
This diff is collapsed. Click to expand it.
......@@ -29,8 +29,24 @@ namespace Sass {
Document Document::make_from_file(Context& ctx, string path)
{
std::FILE *f;
f = std::fopen(path.c_str(), "rb");
if (!f) throw path;
const char* path_str = path.c_str();
f = std::fopen(path_str, "rb");
if (!f) {
string path_with_extension(path + ".scss");
f = std::fopen(path_with_extension.c_str(), "rb");
if (!f) {
const char* file_name_str = Prelexer::folders(path_str);
string path_with_underscore(Token::make(path_str, file_name_str).to_string() +
"_" +
Token::make(file_name_str).to_string());
f = std::fopen(path_with_underscore.c_str(), "rb");
if (!f) {
string path_with_underscore_and_extension(path_with_underscore + ".scss");
f = std::fopen(path_with_underscore_and_extension.c_str(), "rb");
if (!f) throw path;
}
}
}
if (std::fseek(f, 0, SEEK_END)) throw path;
int status = std::ftell(f);
if (status < 0) throw path;
......@@ -117,7 +133,21 @@ namespace Sass {
break;
}
string retval(output.str());
if (!retval.empty()) retval.resize(retval.size()-1);
// trim trailing whitespace
if (!retval.empty()) {
size_t newlines = 0;
for (size_t i = retval.length() - 1; i >= 0; --i) {
if (retval[i] == '\n') {
++newlines;
continue;
}
else {
break;
}
}
retval.resize(retval.length() - newlines);
retval += "\n";
}
return retval;
}
}
......@@ -166,6 +166,7 @@ namespace Sass {
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();
......
......@@ -58,8 +58,16 @@ namespace Sass {
root << parse_warning();
if (!lex< exactly<';'> >()) throw_syntax_error("top-level @warn directive must be terminated by ';'");
}
else if (peek< directive >()) {
Node dir(parse_directive(Node(), Node::none));
if (dir.type() == Node::blockless_directive) {
if (!lex< exactly<';'> >()) throw_syntax_error("top-level blockless directive must be terminated by ';'");
}
root << dir;
}
else {
lex< spaces_and_comments >();
if (position >= end) break;
throw_syntax_error("invalid top-level expression");
}
lex< optional_spaces >();
......@@ -549,6 +557,11 @@ namespace Sass {
else if (peek< media >()) {
block << parse_media_query(inside_of);
}
else if (peek< directive >()) {
Node dir(parse_directive(surrounding_ruleset, inside_of));
if (dir.type() == Node::blockless_directive) semicolon = true;
block << dir;
}
else if (!peek< exactly<';'> >()) {
Node rule(parse_rule());
// check for lbrace; if it's there, we have a namespace property with a value
......@@ -807,7 +820,10 @@ namespace Sass {
lex< exactly<')'> >();
return result;
}
if (peek< functional >())
{ return parse_function_call(); }
if (lex< value_schema >())
{ return Document::make_from_token(context, lexed, path, line).parse_value_schema(); }
......@@ -816,10 +832,7 @@ namespace Sass {
if (lex< sequence< false_kwd, negate< identifier > > >())
{ return context.new_Node(Node::boolean, path, line, false); }
if (peek< functional >())
{ return parse_function_call(); }
if (lex< important >())
{ return context.new_Node(Node::important, path, line, lexed); }
......@@ -934,7 +947,7 @@ namespace Sass {
}
Node Document::parse_identifier_schema()
{
{
lex< sequence< optional< exactly<'*'> >, identifier_schema > >();
Token id(lexed);
const char* i = id.begin;
......@@ -975,8 +988,15 @@ namespace Sass {
Node Document::parse_function_call()
{
lex< identifier >();
Node name(context.new_Node(Node::identifier, path, line, lexed));
Node name;
if (lex< identifier_schema >()) {
name = parse_identifier_schema();
}
else {
lex< identifier >();
name = context.new_Node(Node::identifier, path, line, lexed);
}
Node args(parse_arguments());
Node call(context.new_Node(Node::function_call, path, line, 2));
call << name << args;
......@@ -1051,6 +1071,17 @@ namespace Sass {
return loop;
}
Node Document::parse_directive(Node surrounding_ruleset, Node::Type inside_of)
{
lex< directive >();
Node dir_name(context.new_Node(Node::blockless_directive, path, line, lexed));
if (!peek< exactly<'{'> >()) return dir_name;
Node block(parse_block(surrounding_ruleset, inside_of));
Node dir(context.new_Node(Node::block_directive, path, line, 2));
dir << dir_name << block;
return dir;
}
Node Document::parse_media_query(Node::Type inside_of)
{
lex< media >();
......
......@@ -290,9 +290,19 @@ namespace Sass {
case Node::function_call: {
// TO DO: default-constructed Function should be a generic callback (maybe)
pair<string, size_t> sig(expr[0].token().to_string(), expr[1].size());
if (!f_env.count(sig)) return expr; // TO DO: EVAL THE ARGUMENTS
else return apply_function(f_env[sig], expr[1], prefix, env, f_env, new_Node, ctx);
// eval the function name in case it's interpolated
expr[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx);
pair<string, size_t> sig(expr[0].to_string(), expr[1].size());
if (!f_env.count(sig)) {
Node args(expr[1]);
for (size_t i = 0, S = args.size(); i < S; ++i) {
args[i] = eval(args[i], prefix, env, f_env, new_Node, ctx);
}
return expr;
}
else {
return apply_function(f_env[sig], expr[1], prefix, env, f_env, new_Node, ctx);
}
} break;
case Node::unary_plus: {
......@@ -407,6 +417,12 @@ namespace Sass {
}
} break;
case Node::block_directive: {
// TO DO: eval the directive name for interpolants
eval(expr[1], new_Node(Node::none, expr.path(), expr.line(), 0), env, f_env, new_Node, ctx);
return expr;
} break;
case Node::warning: {
expr[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx);
return expr;
......
......@@ -257,6 +257,7 @@ namespace Sass {
// throw_eval_error("argument to unquote must be a string", cpy.path(), cpy.line());
// }
cpy.is_unquoted() = true;
cpy.is_quoted() = false;
return cpy;
}
......@@ -264,12 +265,24 @@ namespace Sass {
{ "quote", "$string", 0 };
Node quote(const vector<Token>& parameters, map<Token, Node>& bindings, Node_Factory& new_Node) {
Node orig(bindings[parameters[0]]);
if (orig.type() != Node::string_constant && orig.type() != Node::identifier) {
throw_eval_error("argument to quote must be a string or identifier", orig.path(), orig.line());
switch (orig.type())
{
default: {
throw_eval_error("argument to quote must be a string or identifier", orig.path(), orig.line());
} break;
case Node::string_constant:
case Node::string_schema:
case Node::identifier:
case Node::identifier_schema:
case Node::concatenation: {
Node cpy(new_Node(orig));
cpy.is_unquoted() = false;
cpy.is_quoted() = true;
return cpy;
} break;
}
Node cpy(new_Node(orig));
cpy.is_unquoted() = false;
return cpy;
return orig;
}
// Number Functions ////////////////////////////////////////////////////
......
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])])
This diff is collapsed. Click to expand it.
......@@ -55,10 +55,28 @@ namespace Sass {
}
}
string Node::unquote() const
{
string intermediate(to_string());
if (!intermediate.empty() && (intermediate[0] == '"' || intermediate[0] == '\'')) {
return intermediate.substr(1, intermediate.length() - 2);
}
else {
return intermediate;
}
}
bool Node::operator==(Node rhs) const
{
Type t = type();
if (t != rhs.type()) return false;
Type t = type(), u = rhs.type();
if ((t == identifier || t == string_constant || t == string_schema || t == concatenation) &&
(u == identifier || u == string_constant || u == string_schema || u == concatenation)) {
return unquote() == rhs.unquote();
}
else if (t != u) {
return false;
}
switch (t)
{
......
......@@ -164,6 +164,9 @@ namespace Sass {
warning,
block_directive,
blockless_directive,
variable,
assignment
};
......@@ -180,6 +183,7 @@ namespace Sass {
bool from_variable() const;
bool& should_eval() const;
bool& is_unquoted() const;
bool& is_quoted() const;
bool is_numeric() const;
bool is_guarded() const;
bool& has_been_extended() const;
......@@ -213,6 +217,8 @@ namespace Sass {
bool is(Node n) const { return ip_ == n.ip_; }
void flatten();
string unquote() const;
bool operator==(Node rhs) const;
bool operator!=(Node rhs) const;
......@@ -253,6 +259,7 @@ namespace Sass {
bool from_variable;
bool should_eval;
bool is_unquoted;
bool is_quoted;
bool has_been_extended;
Node_Impl()
......@@ -268,7 +275,8 @@ namespace Sass {
has_backref(false),
from_variable(false),
should_eval(false),
is_unquoted(false),
is_unquoted(false), // for strings
is_quoted(false), // for identifiers -- yeah, it's hacky for now
has_been_extended(false)
{ }
......@@ -297,21 +305,32 @@ namespace Sass {
case Node::css_import:
case Node::rule:
case Node::propset:
case Node::warning: has_statements = true; break;
case Node::warning:
case Node::block_directive:
case Node::blockless_directive: {
has_statements = true;
} break;
case Node::media_query:
case Node::ruleset: has_blocks = true; break;
case Node::ruleset: {
has_blocks = true;
} break;
case Node::block:
case Node::if_directive:
case Node::for_through_directive:
case Node::for_to_directive:
case Node::each_directive:
case Node::while_directive:
case Node::expansion: has_expansions = true; break;
case Node::expansion: {
has_expansions = true;
} break;
case Node::backref: has_backref = true; break;
case Node::backref: {
has_backref = true;
} break;
default: break;
default: break;
}
if (n.has_backref()) has_backref = true;
}
......@@ -373,6 +392,7 @@ namespace Sass {
inline bool Node::from_variable() const { return ip_->from_variable; }
inline bool& Node::should_eval() const { return ip_->should_eval; }
inline bool& Node::is_unquoted() const { return ip_->is_unquoted; }
inline bool& Node::is_quoted() const { return ip_->is_quoted; }
inline bool Node::is_numeric() const { return ip_->is_numeric(); }
inline bool Node::is_guarded() const { return (type() == assignment) && (size() == 3); }
inline bool& Node::has_been_extended() const { return ip_->has_been_extended; }
......
......@@ -286,6 +286,12 @@ namespace Sass {
else return result;
}
} break;
case identifier: {
string result(token().to_string());
if (is_quoted()) return "\"" + result + "\"";
else return result;
} break;
case boolean: {
if (boolean_value()) return "true";
......@@ -307,6 +313,7 @@ namespace Sass {
result += at(i).to_string(identifier_schema);
}
}
if (is_quoted()) result = "\"" + result + "\"";
return result;
} break;
......@@ -321,6 +328,7 @@ namespace Sass {
result += chunk;
}
}
if (is_unquoted()) result = result.substr(1, result.length() - 2);
return result;
} break;
......@@ -329,8 +337,12 @@ namespace Sass {
for (size_t i = 0, S = size(); i < S; ++i) {
result += at(i).to_string().substr(1, at(i).token().length()-2);
}
if (inside_of == identifier_schema || inside_of == property) return result;
else return "\"" + result + "\"";
// if (inside_of == identifier_schema || inside_of == property) return result;
// else return "\"" + result + "\"";
if (!(inside_of == identifier_schema || inside_of == property) && !is_unquoted()) {
result = "\"" + result + "\"";
}
return result;
} break;
case warning: {
......@@ -378,8 +390,19 @@ namespace Sass {
buf << " {";
for (size_t i = 0, S = block.size(); i < S; ++i) {
Type stm_type = block[i].type();
if (stm_type == comment || stm_type == rule || stm_type == css_import || stm_type == propset || stm_type == warning) {
block[i].emit_nested_css(buf, depth+1);
if (stm_type == block_directive) buf << endl;
switch (stm_type)
{
case comment:
case rule:
case css_import:
case propset:
case block_directive:
case blockless_directive:
case warning: {
block[i].emit_nested_css(buf, depth+1);
} break;
default: break;
}
}
buf << " }";
......@@ -404,6 +427,36 @@ namespace Sass {
buf << " }" << endl;
} break;
case blockless_directive: {
buf << endl << string(2*depth, ' ');
buf << to_string();
buf << ";";
} break;
case block_directive: {
Node header(at(0));
Node block(at(1));
if (block.has_expansions()) block.flatten();
buf << string(2*depth, ' ');
buf << header.to_string();
buf << " {";
for (size_t i = 0, S = block.size(); i < S; ++i) {
switch (block[i].type())
{
case ruleset:
case media_query:
case block_directive:
buf << endl;
break;
default:
break;
}
block[i].emit_nested_css(buf, depth+1, false, in_media_query);
}
buf << " }" << endl;
if ((depth == 0) && at_toplevel && !in_media_query) buf << endl;
} break;
case propset: {
emit_propset(buf, depth, "");
} break;
......
......@@ -185,6 +185,10 @@ namespace Sass {
return exactly<warn_kwd>(src);
}
const char* directive(const char* src) {
return sequence< exactly<'@'>, identifier >(src);
}
// Match CSS type selectors
const char* namespace_prefix(const char* src) {
return sequence< optional< alternatives< identifier, exactly<'*'> > >,
......@@ -294,7 +298,7 @@ namespace Sass {
}
// Match CSS function call openers.
const char* functional(const char* src) {
return sequence< identifier, exactly<'('> >(src);
return sequence< alternatives< identifier_schema, identifier >, exactly<'('> >(src);
}
// Match the CSS negation pseudo-class.
extern const char pseudo_not_chars[] = ":not(";
......
......@@ -331,6 +331,8 @@ namespace Sass {
const char* warn(const char* src);
const char* directive(const char* src);
// Match CSS type selectors
const char* namespace_prefix(const char* src);
const char* type_selector(const char* src);
......
......@@ -17,8 +17,9 @@ extern "C" {
void sass_free_context(sass_context* ctx)
{
if (ctx->output_string)
free(ctx->output_string);
if (ctx->output_string) free(ctx->output_string);
if (ctx->error_message) free(ctx->error_message);
free(ctx);
}
......@@ -27,8 +28,9 @@ extern "C" {
void sass_free_file_context(sass_file_context* ctx)
{
if (ctx->output_string)
free(ctx->output_string);
if (ctx->output_string) free(ctx->output_string);
if (ctx->error_message) free(ctx->error_message);
free(ctx);
}
......
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