Commit 99d21588 by Gong Hao

use git submodule for libsass, and add paths and style args for render

parent 5d331102
[submodule "libsass"]
path = libsass
url = git://github.com/hcatlin/libsass.git
...@@ -51,8 +51,8 @@ Handle<Value> Render(const Arguments& args) { ...@@ -51,8 +51,8 @@ Handle<Value> Render(const Arguments& args) {
ctx->source_string = new char[strlen(*astr)+1]; ctx->source_string = new char[strlen(*astr)+1];
strcpy(ctx->source_string, *astr); strcpy(ctx->source_string, *astr);
ctx->options.include_paths = 0; ctx->options.include_paths = args[2];
ctx->options.output_style = SASS_STYLE_NESTED; ctx->options.output_style = args[3];
ctx->callback = Persistent<Function>::New(callback); ctx->callback = Persistent<Function>::New(callback);
ctx->request.data = ctx; ctx->request.data = ctx;
......
Subproject commit e9971023785dabd41aa44f431f603f62b15e6017
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.
Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
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
# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# This Makefile.in 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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
DIST_COMMON = README $(am__configure_deps) $(include_HEADERS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/config.h.in $(top_srcdir)/configure AUTHORS COPYING \
ChangeLog INSTALL NEWS config.guess config.sub depcomp \
install-sh ltmain.sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libsass_la_LIBADD =
am_libsass_la_OBJECTS = context.lo functions.lo document.lo \
constants.lo document_parser.lo eval_apply.lo node.lo node_factory.lo \
node_emitters.lo prelexer.lo selector.lo sass_interface.lo
libsass_la_OBJECTS = $(am_libsass_la_OBJECTS)
libsass_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libsass_la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libsass_la_SOURCES)
DIST_SOURCES = $(libsass_la_SOURCES)
HEADERS = $(include_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
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
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
config.h: stamp-h1
@if test ! -f $@; then rm -f stamp-h1; else :; fi
@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libsass.la: $(libsass_la_OBJECTS) $(libsass_la_DEPENDENCIES) $(EXTRA_libsass_la_DEPENDENCIES)
$(libsass_la_LINK) -rpath $(libdir) $(libsass_la_OBJECTS) $(libsass_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/document.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constants.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/document_parser.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_apply.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/functions.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node_emitters.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node_factory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prelexer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selector.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sass_interface.Plo@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__remove_distdir)
dist-lzma: distdir
tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
$(am__remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@test -n '$(distuninstallcheck_dir)' || { \
echo 'ERROR: trying to run $@ with an empty' \
'$$(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
$(am__cd) '$(distuninstallcheck_dir)' || { \
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-includeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES
.MAKE: all install-am install-strip
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
clean-generic clean-libLTLIBRARIES clean-libtool ctags dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \
dist-tarZ dist-xz dist-zip distcheck distclean \
distclean-compile distclean-generic distclean-hdr \
distclean-libtool distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-includeHEADERS install-info \
install-info-am install-libLTLIBRARIES install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-includeHEADERS \
uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
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.
# generated automatically by aclocal 1.11.3 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
# Inc.
# 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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
[m4_warning([this file was generated for autoconf 2.68.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.])])
# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
# Foundation, Inc.
#
# 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 1
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.11.3], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
# _AM_AUTOCONF_VERSION(VERSION)
# -----------------------------
# aclocal traces this macro to find the Autoconf version.
# This is a private macro too. Using m4_define simplifies
# the logic in aclocal, which can simply ignore this definition.
m4_define([_AM_AUTOCONF_VERSION], [])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.11.3])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
#
# 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 1
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is `.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
[dnl Rely on autoconf to set up CDPATH properly.
AC_PREREQ([2.50])dnl
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
# Free Software Foundation, Inc.
#
# 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 9
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ(2.52)dnl
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
m4_define([_AM_COND_VALUE_$1], [$2])dnl
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([[conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
# 2010, 2011 Free Software Foundation, Inc.
#
# 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 12
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "GCJ", or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
[$1], UPC, [depcc="$UPC" am_compiler_list=],
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
# We will build objects and dependencies in a subdirectory because
# it helps to detect inapplicable dependency modes. For instance
# both Tru64's cc and ICC support -MD to output dependencies as a
# side effect of compilation, but ICC will put the dependencies in
# the current directory while Tru64 will put them in the object
# directory.
mkdir sub
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
am__universal=false
m4_case([$1], [CC],
[case " $depcc " in #(
*\ -arch\ *\ -arch\ *) am__universal=true ;;
esac],
[CXX],
[case " $depcc " in #(
*\ -arch\ *\ -arch\ *) am__universal=true ;;
esac])
for depmode in $am_compiler_list; do
# Setup a source with many dependencies, because some compilers
# like to wrap large dependency lists on column 80 (with \), and
# we should not choose a depcomp mode which is confused by this.
#
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
# Solaris 8's {/usr,}/bin/sh.
touch sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this. Also, some Intel
# versions had trouble with output in subdirs
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
gcc)
# This depmode causes a compiler race in universal mode.
test "$am__universal" = false || continue
;;
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
am__minus_obj=
;;
none) break ;;
esac
if depmode=$depmode \
source=sub/conftest.c object=$am__obj \
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
$SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
>/dev/null 2>conftest.err &&
grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
# When given -MP, icc 7.0 and 7.1 complain thusly:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
if (grep 'ignoring option' conftest.err ||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
test "x$enable_dependency_tracking" != xno \
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
am__nodep='_no'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
AC_SUBST([am__nodep])dnl
_AM_SUBST_NOTMAKE([am__nodep])dnl
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
# Free Software Foundation, Inc.
#
# 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
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[{
# Autoconf 2.62 quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
*\'*) eval set x "$CONFIG_FILES" ;;
*) set x $CONFIG_FILES ;;
esac
shift
for mf
do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named `Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
# from the Makefile without running `make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
}
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
#
# 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 16
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out. PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition. After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.62])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
# test to see if srcdir already configured
if test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
fi
# test whether we have cygpath
if test -z "$CYGPATH_W"; then
if (cygpath --version) >/dev/null 2>/dev/null; then
CYGPATH_W='cygpath -w'
else
CYGPATH_W=echo
fi
fi
AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
[_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_CC],
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
[_AM_DEPENDENCIES(OBJC)],
[define([AC_PROG_OBJC],
defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
])
_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
])
dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
_am_arg=$1
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$_am_arg | $_am_arg:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
# Inc.
#
# 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 1
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
if test x"${install_sh}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
*)
install_sh="\${SHELL} $am_aux_dir/install-sh"
esac
fi
AC_SUBST(install_sh)])
# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
#
# 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 2
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
[rm -rf .tst 2>/dev/null
mkdir .tst 2>/dev/null
if test -d .tst; then
am__leading_dot=.
else
am__leading_dot=_
fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
#
# 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 4
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
am__doit:
@echo this is the am__doit target
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# Ignore all kinds of additional output from `make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
am__quote=
_am_result=GNU
;;
esac
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=.include
am__quote="\""
_am_result=BSD
;;
esac
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
# Free Software Foundation, Inc.
#
# 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
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
if test x"${MISSING+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
*)
MISSING="\${SHELL} $am_aux_dir/missing" ;;
esac
fi
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
AC_MSG_WARN([`missing' script is too old or missing])
fi
])
# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
# Inc.
#
# 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 1
# AM_PROG_MKDIR_P
# ---------------
# Check for `mkdir -p'.
AC_DEFUN([AM_PROG_MKDIR_P],
[AC_PREREQ([2.60])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
dnl while keeping a definition of mkdir_p for backward compatibility.
dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
dnl Makefile.ins that do not define MKDIR_P, so we do our own
dnl adjustment using top_builddir (which is defined more often than
dnl MKDIR_P).
AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
case $mkdir_p in
[[\\/$]]* | ?:[[\\/]]*) ;;
*/*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
esac
])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
# Foundation, Inc.
#
# 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
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# --------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
# Free Software Foundation, Inc.
#
# 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
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
'
case `pwd` in
*[[\\\"\#\$\&\'\`$am_lf]]*)
AC_MSG_ERROR([unsafe absolute working directory name]);;
esac
case $srcdir in
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
esac
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t "$srcdir/configure" conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
#
# 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 1
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using `strip' when the user
# run `make install-strip'. However `strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the `STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
#
# 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 3
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
# This macro is traced by Automake.
AC_DEFUN([_AM_SUBST_NOTMAKE])
# AM_SUBST_NOTMAKE(VARIABLE)
# --------------------------
# Public sister of _AM_SUBST_NOTMAKE.
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
#
# 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 2
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
# FORMAT should be one of `v7', `ustar', or `pax'.
#
# Substitute a variable $(am__tar) that is a command
# writing to stdout a FORMAT-tarball containing the directory
# $tardir.
# tardir=directory && $(am__tar) > result.tar
#
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AC_SUBST([AMTAR], ['$${TAR-tar}'])
m4_if([$1], [v7],
[am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
[m4_case([$1], [ustar],, [pax],,
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
# Loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
# Do not fold the above two line into one, because Tru64 sh and
# Solaris sh will not grok spaces in the rhs of `-'.
for _am_tool in $_am_tools
do
case $_am_tool in
gnutar)
for _am_tar in tar gnutar gtar;
do
AM_RUN_LOG([$_am_tar --version]) && break
done
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
am__untar="$_am_tar -xf -"
;;
plaintar)
# Must skip GNU tar: if it does not support --format= it doesn't create
# ustar tarball either.
(tar --version) >/dev/null 2>&1 && continue
am__tar='tar chf - "$$tardir"'
am__tar_='tar chf - "$tardir"'
am__untar='tar xf -'
;;
pax)
am__tar='pax -L -x $1 -w "$$tardir"'
am__tar_='pax -L -x $1 -w "$tardir"'
am__untar='pax -r'
;;
cpio)
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
am__untar='cpio -i -H $1 -d'
;;
none)
am__tar=false
am__tar_=false
am__untar=false
;;
esac
# If the value was cached, stop now. We just wanted to have am__tar
# and am__untar set.
test -n "${am_cv_prog_tar_$1}" && break
# tar/untar a dummy directory, and stop if the command works
rm -rf conftest.dir
mkdir conftest.dir
echo GrepMe > conftest.dir/file
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
rm -rf conftest.dir
if test -s conftest.tar; then
AM_RUN_LOG([$am__untar <conftest.tar])
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
fi
done
rm -rf conftest.dir
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
m4_include([m4/libtool.m4])
m4_include([m4/ltoptions.m4])
m4_include([m4/ltsugar.m4])
m4_include([m4/ltversion.m4])
m4_include([m4/lt~obsolete.m4])
#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
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
timestamp='2012-02-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Per Bothner. Please send patches (context
# diff format) to <config-patches@gnu.org> and include a ChangeLog
# entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
* )
break ;;
esac
done
if test $# != 0; then
echo "$me: too many arguments$help" >&2
exit 1
fi
trap 'exit 1' 1 2 15
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int x;" > $dummy.c ;
for c in cc gcc c89 c99 ; do
if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac ; set_cc_for_build= ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
os=netbsd
else
os=netbsdelf
fi
;;
*)
os=netbsd
;;
esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
case "${UNAME_VERSION}" in
Debian*)
release='-gnu'
;;
*)
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
*:SolidBSD:*:*)
echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
exit ;;
macppc:MirBSD:*:*)
echo powerpc-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
UNAME_MACHINE="alpha" ;;
"EV4.5 (21064)")
UNAME_MACHINE="alpha" ;;
"LCA4 (21066/21068)")
UNAME_MACHINE="alpha" ;;
"EV5 (21164)")
UNAME_MACHINE="alphaev5" ;;
"EV5.6 (21164A)")
UNAME_MACHINE="alphaev56" ;;
"EV5.6 (21164PC)")
UNAME_MACHINE="alphapca56" ;;
"EV5.7 (21164PC)")
UNAME_MACHINE="alphapca57" ;;
"EV6 (21264)")
UNAME_MACHINE="alphaev6" ;;
"EV6.7 (21264A)")
UNAME_MACHINE="alphaev67" ;;
"EV6.8CB (21264C)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8AL (21264B)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8CX (21264D)")
UNAME_MACHINE="alphaev68" ;;
"EV6.9A (21264/EV69A)")
UNAME_MACHINE="alphaev69" ;;
"EV7 (21364)")
UNAME_MACHINE="alphaev7" ;;
"EV7.9 (21364A)")
UNAME_MACHINE="alphaev79" ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
exit ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit ;;
*:[Mm]orph[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-morphos
exit ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit ;;
*:z/VM:*:*)
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
arm:riscos:*:*|arm:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit ;;
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit ;;
DRS?6000:unix:4.0:6*)
echo sparc-icl-nx6
exit ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
s390x:SunOS:*:*)
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
echo i386-pc-auroraux${UNAME_RELEASE}
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
eval $set_cc_for_build
SUN_ARCH="i386"
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH="x86_64"
fi
fi
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
exit ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
;;
sun4)
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
exit ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c &&
dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
SYSTEM_NAME=`$dummy $dummyarg` &&
{ echo "$SYSTEM_NAME"; exit; }
echo mips-mips-riscos${UNAME_RELEASE}
exit ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit ;;
Motorola:*:4.3:PL8-*)
echo powerpc-harris-powermax
exit ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
echo powerpc-harris-powermax
exit ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
[ ${TARGET_BINARY_INTERFACE}x = x ]
then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
echo i386-ibm-aix
exit ;;
ia64:AIX:*:*)
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
then
echo "$SYSTEM_NAME"
else
echo rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit ;;
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
if [ ${HP_ARCH} = "hppa2.0w" ]
then
eval $set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
# generating 64-bit code. GNU and HP use different nomenclature:
#
# $ CC_FOR_BUILD=cc ./config.guess
# => hppa2.0w-hp-hpux11.23
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
HP_ARCH="hppa64"
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit ;;
ia64:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ia64-hp-hpux${HPUX_REV}
exit ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
*:UNICOS/mp:*:*)
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
*:Interix*:*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
8664:Windows_NT:*)
echo x86_64-pc-mks
exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i586-pc-interix
exit ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
echo x86_64-unknown-cygwin
exit ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
exit ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-gnu
exit ;;
crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-gnu
exit ;;
frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
hexagon:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
LIBC=gnu
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef ${UNAME_MACHINE}
#undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-gnu
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
esac
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
x86_64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit ;;
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
paragon:*:*:*)
echo i860-intel-osf1
exit ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit ;;
mc68k:UNIX:SYSTEM5:3.51m)
echo m68k-convergent-sysv
exit ;;
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
exit ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit ;;
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
echo ${UNAME_MACHINE}-stratus-vos
exit ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
exit ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit ;;
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
SX-7:SUPER-UX:*:*)
echo sx7-nec-superux${UNAME_RELEASE}
exit ;;
SX-8:SUPER-UX:*:*)
echo sx8-nec-superux${UNAME_RELEASE}
exit ;;
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
i386)
eval $set_cc_for_build
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
UNAME_PROCESSOR="x86_64"
fi
fi ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
exit ;;
BS2000:POSIX*:*:*)
echo bs2000-siemens-sysv
exit ;;
DS/*:UNIX_System_V:*:*)
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
exit ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
if test "$cputype" = "386"; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit ;;
*:TENEX:*:*)
echo pdp10-unknown-tenex
exit ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
echo pdp10-dec-tops20
exit ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
echo pdp10-xkl-tops20
exit ;;
*:TOPS-20:*:*)
echo pdp10-unknown-tops20
exit ;;
*:ITS:*:*)
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
V*) echo vax-dec-vms ; exit ;;
esac ;;
*:XENIX:*:SysV)
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
exit ;;
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix\n"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
# if !defined (ultrix)
# include <sys/param.h>
# if defined (BSD)
# if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
# else
# if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# endif
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# else
printf ("vax-dec-ultrix\n"); exit (0);
# endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
c34*)
echo c34-convex-bsd
exit ;;
c38*)
echo c38-convex-bsd
exit ;;
c4*)
echo c4-convex-bsd
exit ;;
esac
fi
cat >&2 <<EOF
$0: unable to guess system type
This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
pertinent to <config-patches@gnu.org> in order to provide the needed
information to handle your system.
config.guess timestamp = $timestamp
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
hostinfo = `(hostinfo) 2>/dev/null`
/bin/universe = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = ${UNAME_MACHINE}
UNAME_RELEASE = ${UNAME_RELEASE}
UNAME_SYSTEM = ${UNAME_SYSTEM}
UNAME_VERSION = ${UNAME_VERSION}
EOF
exit 1
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
/* 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
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
timestamp='2012-02-10'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted GNU ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Canonicalize a configuration name.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help"
exit 1 ;;
*local*)
# First pass through any local machine types.
echo $1
exit ;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
-sun*os*)
# Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray | -microblaze)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
;;
-scout)
;;
-wrs)
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nios | nios2 \
| ns16k | ns32k \
| open8 \
| or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
ms1)
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
os=-none
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
basic_machine=i386-unknown
os=-bsd
;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
a29khif)
basic_machine=a29k-amd
os=-udi
;;
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-unknown
;;
amigaos | amigados)
basic_machine=m68k-unknown
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
apollo68bsd)
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
;;
cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
basic_machine=m68k-crds
;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
crx)
basic_machine=crx-unknown
os=-elf
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
os=-ose
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
go32)
basic_machine=i386-pc
os=-go32
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
h8300xray)
basic_machine=h8300-hitachi
os=-xray
;;
h8500hms)
basic_machine=h8500-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
basic_machine=hppa1.1-hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
hppaosf)
basic_machine=hppa1.1-hp
os=-osf
;;
hppro)
basic_machine=hppa1.1-hp
os=-proelf
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach)
basic_machine=i386-mach
os=-mach
;;
i386-vsta | vsta)
basic_machine=i386-unknown
os=-vsta
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
microblaze)
basic_machine=microblaze-xilinx
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i386-pc
os=-msys
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
netbsd386)
basic_machine=i386-unknown
os=-netbsd
;;
netwinder)
basic_machine=armv4l-rebel
os=-linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
necv70)
basic_machine=v70-nec
os=-sysv
;;
next | m*-next )
basic_machine=m68k-next
case $os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
mon960)
basic_machine=i960-intel
os=-mon960
;;
nonstopux)
basic_machine=mips-compaq
os=-nonstopux
;;
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
;;
openrisc | openrisc-*)
basic_machine=or32-unknown
;;
os400)
basic_machine=powerpc-ibm
os=-os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
;;
os68k)
basic_machine=m68k-none
os=-os68k
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pc98)
basic_machine=i386-pc
;;
pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
pw32)
basic_machine=i586-unknown
os=-pw32
;;
rdos)
basic_machine=i386-pc
os=-rdos
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
st2000)
basic_machine=m68k-tandem
;;
stratus)
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
basic_machine=sv1-cray
os=-unicos
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tile*)
basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
v810 | necv810)
basic_machine=v810-nec
os=-none
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
w65*)
basic_machine=w65-wdc
os=-none
;;
w89k-*)
basic_machine=hppa1.1-winbond
os=-proelf
;;
xbox)
basic_machine=i686-pc
os=-mingw32
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
;;
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k)
basic_machine=hppa1.1-winbond
;;
op50n)
basic_machine=hppa1.1-oki
;;
op60c)
basic_machine=hppa1.1-oki
;;
romp)
basic_machine=romp-ibm
;;
mmix)
basic_machine=mmix-knuth
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
mac | mpw | mac-mpw)
basic_machine=m68k-apple
;;
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
case $basic_machine in
x86-* | i*86-*)
;;
*)
os=-nto$os
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-syllable*)
os=-syllable
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
;;
-nsk*)
os=-nsk
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-ose*)
os=-ose
;;
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
exit 1
;;
esac
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn)
os=-riscix1.2
;;
arm*-rebel)
os=-linux
;;
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
;;
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
*-knuth)
os=-mmixware
;;
*-wec)
os=-proelf
;;
*-winbond)
os=-proelf
;;
*-oki)
os=-proelf
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=-sysv
;;
*-cbm)
os=-amigaos
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f30[01]-fujitsu | f700-fujitsu)
os=-uxpv
;;
*-rom68k)
os=-coff
;;
*-*bug)
os=-coff
;;
*-apple)
os=-macos
;;
*-atari*)
os=-mint
;;
*)
os=-none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-cnk*|-aix*)
vendor=ibm
;;
-beos*)
vendor=be
;;
-hpux*)
vendor=hp
;;
-mpeix*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
-hms*)
vendor=hitachi
;;
-mpw* | -macos*)
vendor=apple
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
exit
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
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 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 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[] = "-+";
// 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";
}
}
\ 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 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 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[];
// 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[];
}
}
\ No newline at end of file
#ifdef _WIN32
#include <direct.h>
#define getcwd _getcwd
#else
#include <unistd.h>
#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<':'>(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<':'>(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)
: global_env(Environment()),
function_env(map<string, Function>()),
extensions(multimap<Node, Node>()),
pending_extensions(vector<pair<Node, Node> >()),
source_refs(vector<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)
{
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);
// 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<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;
void collect_include_paths(const char* paths_str);
Context(const char* paths_str = 0, const char* img_path_str = 0);
~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();
};
}
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2011-12-04.11; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
# 2011 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test "$stat" = 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/ \1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/ /
G
p
}' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
#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;
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) {
tmp = path + ".scss";
path_str = tmp.c_str();
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) {
const char *full_path_str = path.c_str();
const char *file_name_str = Prelexer::folders(full_path_str);
tmp = Token::make(full_path_str, file_name_str).to_string() +
"_" +
string(file_name_str);
path_str = tmp.c_str();
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode)) {
tmp = tmp + ".scss";
path_str = tmp.c_str();
if (stat(path_str, &st) == -1 || S_ISDIR(st.st_mode))
throw path;
}
}
}
f = std::fopen(path_str, "rb");
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;
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);
if (!include_path.empty()) {
doc.context.include_paths.push_back(include_path);
}
return doc;
}
Document Document::make_from_source_chars(Context& ctx, 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 = const_cast<char*>(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);
break;
case expanded:
root.emit_expanded_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;
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, 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 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);
};
}
\ No newline at end of file
#include <cstdlib>
#include <iostream>
#include "document.hpp"
#include "constants.hpp"
#include "error.hpp"
#ifndef SASS_PRELEXER
#include "prelexer.hpp"
#endif
namespace Sass {
using namespace std;
using namespace Constants;
void Document::parse_scss()
{
lex< optional_spaces >();
Selector_Lookahead lookahead_result;
while (position < end) {
if (lex< block_comment >()) {
root << context.new_Node(Node::comment, path, line, lexed);
}
else if (peek< import >()) {
Node importee(parse_import());
if (importee.type() == Node::css_import) root << importee;
else root += importee;
if (!lex< exactly<';'> >()) throw_syntax_error("top-level @import directive must be terminated by ';'");
}
else if (peek< mixin >() || peek< exactly<'='> >()) {
root << parse_mixin_definition();
}
else if (peek< function >()) {
root << parse_function_definition();
}
else if (peek< variable >()) {
root << parse_assignment();
if (!lex< exactly<';'> >()) throw_syntax_error("top-level variable binding must be terminated by ';'");
}
else if (peek< sequence< identifier, optional_spaces, exactly<':'>, optional_spaces, exactly<'{'> > >(position)) {
root << parse_propset();
}
else if ((lookahead_result = lookahead_for_selector(position)).found) {
root << parse_ruleset(lookahead_result);
}
else if (peek< include >() || peek< exactly<'+'> >()) {
root << parse_mixin_call();
if (!lex< exactly<';'> >()) throw_syntax_error("top-level @include directive must be terminated by ';'");
}
else if (peek< if_directive >()) {
root << parse_if_directive(Node(), Node::none);
}
else if (peek< for_directive >()) {
root << parse_for_directive(Node(), Node::none);
}
else if (peek< each_directive >()) {
root << parse_each_directive(Node(), Node::none);
}
else if (peek< while_directive >()) {
root << parse_while_directive(Node(), Node::none);
}
else if (peek< media >()) {
root << parse_media_query(Node::none);
}
else if (peek< warn >()) {
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 >();
}
}
Node Document::parse_import()
{
lex< import >();
if (lex< uri_prefix >())
{
if (peek< string_constant >()) {
Node schema(parse_string());
Node importee(context.new_Node(Node::css_import, path, line, 1));
importee << schema;
if (!lex< exactly<')'> >()) throw_syntax_error("unterminated url in @import directive");
return importee;
}
else {
const char* beg = position;
const char* end = find_first< exactly<')'> >(position);
if (!end) throw_syntax_error("unterminated url in @import directive");
Node path_node(context.new_Node(Node::identifier, path, line, Token::make(beg, end)));
Node importee(context.new_Node(Node::css_import, path, line, 1));
importee << path_node;
position = end;
lex< exactly<')'> >();
return importee;
}
}
if (!lex< string_constant >()) throw_syntax_error("@import directive requires a url or quoted path");
// TO DO: BETTER PATH HANDLING
string import_path(lexed.unquote());
for (vector<string>::iterator path = context.include_paths.begin(); path < context.include_paths.end(); ++path) {
try {
Document importee(Document::make_from_file(context, *path + import_path));
importee.parse_scss();
return importee.root;
}
catch (string& path) {
}
}
throw_read_error("error reading file \"" + import_path + "\"");
// unreached statement
return Node();
}
Node Document::parse_mixin_definition()
{
lex< mixin >() || lex< exactly<'='> >();
if (!lex< identifier >()) throw_syntax_error("invalid name in @mixin directive");
Node name(context.new_Node(Node::identifier, path, line, lexed));
Node params(parse_parameters());
if (!peek< exactly<'{'> >()) throw_syntax_error("body for mixin " + name.token().to_string() + " must begin with a '{'");
Node body(parse_block(Node(), Node::mixin));
Node the_mixin(context.new_Node(Node::mixin, path, line, 3));
the_mixin << name << params << body;
return the_mixin;
}
Node Document::parse_function_definition()
{
lex< function >();
size_t func_line = line;
if (!lex< identifier >()) throw_syntax_error("name required for function definition");
Node name(context.new_Node(Node::identifier, path, line, lexed));
Node params(parse_parameters());
if (!peek< exactly<'{'> >()) throw_syntax_error("body for function " + name.to_string() + " must begin with a '{'");
Node body(parse_block(Node(), Node::function));
Node func(context.new_Node(Node::function, path, func_line, 3));
func << name << params << body;
return func;
}
Node Document::parse_parameters()
{
Node params(context.new_Node(Node::parameters, path, line, 0));
Token name(lexed);
Node::Type param_type = Node::none;
if (lex< exactly<'('> >()) {
if (peek< variable >()) {
Node param(parse_parameter(param_type));
if (param.type() == Node::assignment) param_type = Node::assignment;
params << param;
while (lex< exactly<','> >()) {
if (!peek< variable >()) throw_syntax_error("expected a variable name (e.g. $x) for the parameter list for " + name.to_string());
Node param(parse_parameter(param_type));
if (param.type() == Node::assignment) param_type = Node::assignment;
params << param;
}
if (!lex< exactly<')'> >()) throw_syntax_error("parameter list for " + name.to_string() + " requires a ')'");
}
else if (!lex< exactly<')'> >()) throw_syntax_error("expected a variable name (e.g. $x) or ')' for the parameter list for " + name.to_string());
}
return params;
}
Node Document::parse_parameter(Node::Type param_type) {
lex< variable >();
Node var(context.new_Node(Node::variable, path, line, lexed));
if (param_type == Node::assignment) {
if (lex< exactly<':'> >()) { // default value
Node val(parse_space_list());
Node par_and_val(context.new_Node(Node::assignment, path, line, 2));
par_and_val << var << val;
return par_and_val;
}
else {
throw_syntax_error("required parameter " + var.token().to_string() + " must precede all optional parameters");
}
}
else if (lex< exactly<':'> >()) { // default value
Node val(parse_space_list());
Node par_and_val(context.new_Node(Node::assignment, path, line, 2));
par_and_val << var << val;
return par_and_val;
}
return var;
}
Node Document::parse_mixin_call()
{
lex< include >() || lex< exactly<'+'> >();
if (!lex< identifier >()) throw_syntax_error("invalid name in @include directive");
Node name(context.new_Node(Node::identifier, path, line, lexed));
Node args(parse_arguments());
Node the_call(context.new_Node(Node::mixin_call, path, line, 2));
the_call << name << args;
return the_call;
}
Node Document::parse_arguments()
{
Token name(lexed);
Node args(context.new_Node(Node::arguments, path, line, 0));
Node::Type arg_type = Node::none;
if (lex< exactly<'('> >()) {
if (!peek< exactly<')'> >(position)) {
Node arg(parse_argument(Node::none));
args << arg;
if (arg.type() == Node::assignment) arg_type = Node::assignment;
while (lex< exactly<','> >()) {
Node arg(parse_argument(arg_type));
args << arg;
if (arg.type() == Node::assignment) arg_type = Node::assignment;
}
}
if (!lex< exactly<')'> >()) throw_syntax_error("improperly terminated argument list for " + name.to_string());
}
return args;
}
Node Document::parse_argument(Node::Type arg_type)
{
// if arg_type is assignment, only accept keyword args from here onwards
if (arg_type == Node::assignment) {
if (peek< sequence < variable, spaces_and_comments, exactly<':'> > >()) {
lex< variable >();
Node var(context.new_Node(Node::variable, path, line, lexed));
lex< exactly<':'> >();
Node val(parse_space_list());
val.should_eval() = true;
Node assn(context.new_Node(Node::assignment, path, line, 2));
assn << var << val;
return assn;
}
else {
throw_syntax_error("ordinal arguments must precede keyword arguments");
}
}
// otherwise accept either, and let the caller set the arg_type flag
if (arg_type == Node::none &&
peek< sequence < variable, spaces_and_comments, exactly<':'> > >()) {
lex< variable >();
Node var(context.new_Node(Node::variable, path, line, lexed));
lex< exactly<':'> >();
Node val(parse_space_list());
val.should_eval() = true;
Node assn(context.new_Node(Node::assignment, path, line, 2));
assn << var << val;
return assn;
}
Node val(parse_space_list());
val.should_eval() = true;
return val;
}
Node Document::parse_assignment()
{
lex< variable >();
Node var(context.new_Node(Node::variable, path, line, lexed));
if (!lex< exactly<':'> >()) throw_syntax_error("expected ':' after " + lexed.to_string() + " in assignment statement");
Node val(parse_list());
Node assn(context.new_Node(Node::assignment, path, line, 2));
assn << var << val;
if (lex< default_flag >()) assn << context.new_Node(Node::none, path, line, 0);
return assn;
}
Node Document::parse_propset()
{
lex< identifier >();
Node property_segment(context.new_Node(Node::identifier, path, line, lexed));
lex< exactly<':'> >();
lex< exactly<'{'> >();
Node block(context.new_Node(Node::block, path, line, 1));
while (!lex< exactly<'}'> >()) {
if (peek< sequence< identifier, optional_spaces, exactly<':'>, optional_spaces, exactly<'{'> > >(position)) {
block << parse_propset();
}
else {
block << parse_rule();
lex< exactly<';'> >();
}
}
if (block.empty()) throw_syntax_error("namespaced property cannot be empty");
Node propset(context.new_Node(Node::propset, path, line, 2));
propset << property_segment;
propset << block;
return propset;
}
Node Document::parse_ruleset(Selector_Lookahead lookahead, Node::Type inside_of)
{
Node ruleset(context.new_Node(Node::ruleset, path, line, 3));
if (lookahead.has_interpolants) {
ruleset << parse_selector_schema(lookahead.found);
}
else {
ruleset << parse_selector_group();
}
if (!peek< exactly<'{'> >()) throw_syntax_error("expected a '{' after the selector");
ruleset << parse_block(ruleset, inside_of);
return ruleset;
}
Node Document::parse_selector_schema(const char* end_of_selector)
{
const char* i = position;
const char* p;
Node schema(context.new_Node(Node::selector_schema, path, line, 1));
while (i < end_of_selector) {
p = find_first_in_interval< exactly<hash_lbrace> >(i, end_of_selector);
if (p) {
// accumulate the preceding segment if there is one
if (i < p) schema << context.new_Node(Node::identifier, path, line, Token::make(i, p));
// find the end of the interpolant and parse it
const char* j = find_first_in_interval< exactly<rbrace> >(p, end_of_selector);
Node interp_node(Document::make_from_token(context, Token::make(p+2, j), path, line).parse_list());
interp_node.should_eval() = true;
schema << interp_node;
i = j + 1;
}
else { // no interpolants left; add the last segment if there is one
if (i < end_of_selector) schema << context.new_Node(Node::identifier, path, line, Token::make(i, end_of_selector));
break;
}
}
position = end_of_selector;
return schema;
}
Node Document::parse_selector_group()
{
Node sel1(parse_selector());
if (!peek< exactly<','> >()) return sel1;
Node group(context.new_Node(Node::selector_group, path, line, 2));
group << sel1;
while (lex< exactly<','> >()) group << parse_selector();
return group;
}
Node Document::parse_selector()
{
Node seq1(parse_simple_selector_sequence());
if (peek< exactly<','> >() ||
peek< exactly<')'> >() ||
peek< exactly<'{'> >() ||
peek< exactly<';'> >()) return seq1;
Node selector(context.new_Node(Node::selector, path, line, 2));
selector << seq1;
while (!peek< exactly<'{'> >() &&
!peek< exactly<','> >() &&
!peek< exactly<';'> >()) {
selector << parse_simple_selector_sequence();
}
return selector;
}
Node Document::parse_simple_selector_sequence()
{
// check for initial and trailing combinators
if (lex< exactly<'+'> >() ||
lex< exactly<'~'> >() ||
lex< exactly<'>'> >())
{ return context.new_Node(Node::selector_combinator, path, line, lexed); }
// check for backref or type selector, which are only allowed at the front
Node simp1;
if (lex< exactly<'&'> >()) {
simp1 = context.new_Node(Node::backref, path, line, lexed);
}
else if (lex< alternatives< type_selector, universal > >()) {
simp1 = context.new_Node(Node::simple_selector, path, line, lexed);
}
else {
simp1 = parse_simple_selector();
}
// now we have one simple/atomic selector -- see if that's all
if (peek< spaces >() || peek< exactly<'>'> >() ||
peek< exactly<'+'> >() || peek< exactly<'~'> >() ||
peek< exactly<','> >() || peek< exactly<')'> >() ||
peek< exactly<'{'> >() || peek< exactly<';'> >())
{ return simp1; }
// otherwise, we have a sequence of simple selectors
Node seq(context.new_Node(Node::simple_selector_sequence, path, line, 2));
seq << simp1;
while (!peek< spaces >(position) &&
!(peek < exactly<'+'> >(position) ||
peek < exactly<'~'> >(position) ||
peek < exactly<'>'> >(position) ||
peek < exactly<','> >(position) ||
peek < exactly<')'> >(position) ||
peek < exactly<'{'> >(position) ||
peek < exactly<';'> >(position))) {
seq << parse_simple_selector();
}
return seq;
}
Node Document::parse_selector_combinator()
{
lex< exactly<'+'> >() || lex< exactly<'~'> >() ||
lex< exactly<'>'> >() || lex< ancestor_of >();
return context.new_Node(Node::selector_combinator, path, line, lexed);
}
Node Document::parse_simple_selector()
{
if (lex< id_name >() || lex< class_name >()) {
return context.new_Node(Node::simple_selector, path, line, lexed);
}
else if (peek< exactly<':'> >(position)) {
return parse_pseudo();
}
else if (peek< exactly<'['> >(position)) {
return parse_attribute_selector();
}
else {
throw_syntax_error("invalid selector after " + lexed.to_string());
}
// unreachable statement
return Node();
}
Node Document::parse_pseudo() {
if (lex< pseudo_not >()) {
Node ps_not(context.new_Node(Node::pseudo_negation, path, line, 2));
ps_not << context.new_Node(Node::value, path, line, lexed);
ps_not << parse_selector_group();
lex< exactly<')'> >();
return ps_not;
}
else if (lex< sequence< pseudo_prefix, functional > >()) {
Node pseudo(context.new_Node(Node::functional_pseudo, path, line, 2));
Token name(lexed);
pseudo << context.new_Node(Node::value, path, line, name);
if (lex< alternatives< even, odd > >()) {
pseudo << context.new_Node(Node::value, path, line, lexed);
}
else if (peek< binomial >(position)) {
lex< coefficient >();
pseudo << context.new_Node(Node::value, path, line, lexed);
lex< exactly<'n'> >();
pseudo << context.new_Node(Node::value, path, line, lexed);
lex< sign >();
pseudo << context.new_Node(Node::value, path, line, lexed);
lex< digits >();
pseudo << context.new_Node(Node::value, path, line, lexed);
}
else if (lex< sequence< optional<sign>,
optional<digits>,
exactly<'n'> > >()) {
pseudo << context.new_Node(Node::value, path, line, lexed);
}
else if (lex< sequence< optional<sign>, digits > >()) {
pseudo << context.new_Node(Node::value, path, line, lexed);
}
else if (lex< identifier >()) {
pseudo << context.new_Node(Node::identifier, path, line, lexed);
}
else if (lex< string_constant >()) {
pseudo << context.new_Node(Node::string_constant, path, line, lexed);
}
else {
throw_syntax_error("invalid argument to " + name.to_string() + "...)");
}
if (!lex< exactly<')'> >()) throw_syntax_error("unterminated argument to " + name.to_string() + "...)");
return pseudo;
}
else if (lex < sequence< pseudo_prefix, identifier > >()) {
return context.new_Node(Node::pseudo, path, line, lexed);
}
else {
throw_syntax_error("unrecognized pseudo-class or pseudo-element");
}
// unreachable statement
return Node();
}
Node Document::parse_attribute_selector()
{
Node attr_sel(context.new_Node(Node::attribute_selector, path, line, 3));
lex< exactly<'['> >();
if (!lex< type_selector >()) throw_syntax_error("invalid attribute name in attribute selector");
Token name(lexed);
attr_sel << context.new_Node(Node::value, path, line, name);
if (lex< exactly<']'> >()) return attr_sel;
if (!lex< alternatives< exact_match, class_match, dash_match,
prefix_match, suffix_match, substring_match > >()) {
throw_syntax_error("invalid operator in attribute selector for " + name.to_string());
}
attr_sel << context.new_Node(Node::value, path, line, lexed);
if (!lex< string_constant >() && !lex< identifier >()) throw_syntax_error("expected a string constant or identifier in attribute selector for " + name.to_string());
attr_sel << context.new_Node(Node::value, path, line, lexed);
if (!lex< exactly<']'> >()) throw_syntax_error("unterminated attribute selector for " + name.to_string());
return attr_sel;
}
Node Document::parse_block(Node surrounding_ruleset, Node::Type inside_of)
{
lex< exactly<'{'> >();
bool semicolon = false;
Selector_Lookahead lookahead_result;
Node block(context.new_Node(Node::block, path, line, 0));
while (!lex< exactly<'}'> >()) {
if (semicolon) {
if (!lex< exactly<';'> >()) throw_syntax_error("non-terminal statement or declaration must end with ';'");
semicolon = false;
while (lex< block_comment >()) {
block << context.new_Node(Node::comment, path, line, lexed);
}
if (lex< exactly<'}'> >()) break;
}
if (lex< block_comment >()) {
block << context.new_Node(Node::comment, path, line, lexed);
}
else if (peek< import >(position)) {
if (inside_of == Node::mixin || inside_of == Node::function) {
lex< import >(); // to adjust the line number
throw_syntax_error("@import directive not allowed inside definition of mixin or function");
}
Node imported_tree(parse_import());
if (imported_tree.type() == Node::css_import) {
block << imported_tree;
}
else {
for (size_t i = 0, S = imported_tree.size(); i < S; ++i) {
block << imported_tree[i];
}
semicolon = true;
}
}
else if (lex< variable >()) {
block << parse_assignment();
semicolon = true;
}
else if (peek< if_directive >()) {
block << parse_if_directive(surrounding_ruleset, inside_of);
}
else if (peek< for_directive >()) {
block << parse_for_directive(surrounding_ruleset, inside_of);
}
else if (peek< each_directive >()) {
block << parse_each_directive(surrounding_ruleset, inside_of);
}
else if (peek < while_directive >()) {
block << parse_while_directive(surrounding_ruleset, inside_of);
}
else if (lex < return_directive >()) {
Node ret_expr(context.new_Node(Node::return_directive, path, line, 1));
ret_expr << parse_list();
ret_expr.should_eval() = true;
block << ret_expr;
semicolon = true;
}
else if (peek< warn >()) {
block << parse_warning();
semicolon = true;
}
else if (inside_of == Node::function) {
throw_syntax_error("only variable declarations and control directives are allowed inside functions");
}
else if (peek< include >(position)) {
block << parse_mixin_call();
semicolon = true;
}
else if (peek< sequence< identifier, optional_spaces, exactly<':'>, optional_spaces, exactly<'{'> > >(position)) {
block << parse_propset();
}
else if ((lookahead_result = lookahead_for_selector(position)).found) {
block << parse_ruleset(lookahead_result, inside_of);
}
else if (peek< exactly<'+'> >()) {
block << parse_mixin_call();
semicolon = true;
}
else if (lex< extend >()) {
Node request(context.new_Node(Node::extend_directive, path, line, 1));
Selector_Lookahead lookahead = lookahead_for_extension_target(position);
if (!lookahead.found) throw_syntax_error("invalid selector for @extend");
if (lookahead.has_interpolants) request << parse_selector_schema(lookahead.found);
else request << parse_selector_group();
semicolon = true;
block << request;
}
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
if (peek< exactly<'{'> >()) {
Node inner(parse_block(Node()));
Node propset(context.new_Node(Node::propset, path, line, 2));
propset << rule[0];
rule[0] = context.new_Node(Node::property, path, line, Token::make());
inner.push_front(rule);
propset << inner;
block << propset;
}
else {
block << rule;
semicolon = true;
}
}
else lex< exactly<';'> >();
while (lex< block_comment >()) {
block << context.new_Node(Node::comment, path, line, lexed);
}
}
return block;
}
Node Document::parse_rule() {
Node rule(context.new_Node(Node::rule, path, line, 2));
if (peek< sequence< optional< exactly<'*'> >, identifier_schema > >()) {
rule << parse_identifier_schema();
}
else if (lex< sequence< optional< exactly<'*'> >, identifier > >()) {
rule << context.new_Node(Node::property, path, line, lexed);
}
else {
throw_syntax_error("invalid property name");
}
if (!lex< exactly<':'> >()) throw_syntax_error("property \"" + lexed.to_string() + "\" must be followed by a ':'");
rule << parse_list();
return rule;
}
Node Document::parse_list()
{
return parse_comma_list();
}
Node Document::parse_comma_list()
{
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<'{'> >(position) ||
peek< exactly<')'> >(position))
{ return context.new_Node(Node::list, path, line, 0); }
Node list1(parse_space_list());
// if it's a singleton, return it directly; don't wrap it
if (!peek< exactly<','> >(position)) return list1;
Node comma_list(context.new_Node(Node::list, path, line, 2));
comma_list.is_comma_separated() = true;
comma_list << list1;
comma_list.should_eval() |= list1.should_eval();
while (lex< exactly<','> >())
{
Node list(parse_space_list());
comma_list << list;
comma_list.should_eval() |= list.should_eval();
}
return comma_list;
}
Node Document::parse_space_list()
{
Node disj1(parse_disjunction());
// if it's a singleton, return it directly; don't wrap it
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<'{'> >(position) ||
peek< exactly<')'> >(position) ||
peek< exactly<','> >(position) ||
peek< default_flag >(position))
{ return disj1; }
Node space_list(context.new_Node(Node::list, path, line, 2));
space_list << disj1;
space_list.should_eval() |= disj1.should_eval();
while (!(peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<'{'> >(position) ||
peek< exactly<')'> >(position) ||
peek< exactly<','> >(position) ||
peek< default_flag >(position)))
{
Node disj(parse_disjunction());
space_list << disj;
space_list.should_eval() |= disj.should_eval();
}
return space_list;
}
Node Document::parse_disjunction()
{
Node conj1(parse_conjunction());
// if it's a singleton, return it directly; don't wrap it
if (!peek< sequence< or_op, negate< identifier > > >()) return conj1;
Node disjunction(context.new_Node(Node::disjunction, path, line, 2));
disjunction << conj1;
while (lex< sequence< or_op, negate< identifier > > >()) disjunction << parse_conjunction();
disjunction.should_eval() = true;
return disjunction;
}
Node Document::parse_conjunction()
{
Node rel1(parse_relation());
// if it's a singleton, return it directly; don't wrap it
if (!peek< sequence< and_op, negate< identifier > > >()) return rel1;
Node conjunction(context.new_Node(Node::conjunction, path, line, 2));
conjunction << rel1;
while (lex< sequence< and_op, negate< identifier > > >()) conjunction << parse_relation();
conjunction.should_eval() = true;
return conjunction;
}
Node Document::parse_relation()
{
Node expr1(parse_expression());
// if it's a singleton, return it directly; don't wrap it
if (!(peek< eq_op >(position) ||
peek< neq_op >(position) ||
peek< gt_op >(position) ||
peek< gte_op >(position) ||
peek< lt_op >(position) ||
peek< lte_op >(position)))
{ return expr1; }
Node relation(context.new_Node(Node::relation, path, line, 3));
expr1.should_eval() = true;
relation << expr1;
if (lex< eq_op >()) relation << context.new_Node(Node::eq, path, line, lexed);
else if (lex< neq_op >()) relation << context.new_Node(Node::neq, path, line, lexed);
else if (lex< gte_op >()) relation << context.new_Node(Node::gte, path, line, lexed);
else if (lex< lte_op >()) relation << context.new_Node(Node::lte, path, line, lexed);
else if (lex< gt_op >()) relation << context.new_Node(Node::gt, path, line, lexed);
else if (lex< lt_op >()) relation << context.new_Node(Node::lt, path, line, lexed);
Node expr2(parse_expression());
expr2.should_eval() = true;
relation << expr2;
relation.should_eval() = true;
return relation;
}
Node Document::parse_expression()
{
Node term1(parse_term());
// if it's a singleton, return it directly; don't wrap it
if (!(peek< exactly<'+'> >(position) ||
peek< sequence< negate< number >, exactly<'-'> > >(position)))
{ return term1; }
Node expression(context.new_Node(Node::expression, path, line, 3));
term1.should_eval() = true;
expression << term1;
while (lex< exactly<'+'> >() || lex< sequence< negate< number >, exactly<'-'> > >()) {
if (lexed.begin[0] == '+') {
expression << context.new_Node(Node::add, path, line, lexed);
}
else {
expression << context.new_Node(Node::sub, path, line, lexed);
}
Node term(parse_term());
term.should_eval() = true;
expression << term;
}
expression.should_eval() = true;
return expression;
}
Node Document::parse_term()
{
Node fact1(parse_factor());
// if it's a singleton, return it directly; don't wrap it
if (!(peek< exactly<'*'> >(position) ||
peek< exactly<'/'> >(position)))
{ return fact1; }
Node term(context.new_Node(Node::term, path, line, 3));
term << fact1;
if (fact1.should_eval()) term.should_eval() = true;
while (lex< exactly<'*'> >() || lex< exactly<'/'> >()) {
if (lexed.begin[0] == '*') {
term << context.new_Node(Node::mul, path, line, lexed);
term.should_eval() = true;
}
else {
term << context.new_Node(Node::div, path, line, lexed);
}
Node fact(parse_factor());
term.should_eval() |= fact.should_eval();
term << fact;
}
return term;
}
Node Document::parse_factor()
{
if (lex< exactly<'('> >()) {
Node value(parse_comma_list());
value.should_eval() = true;
if (value.type() == Node::list && value.size() > 0) {
value[0].should_eval() = true;
}
if (!lex< exactly<')'> >()) throw_syntax_error("unclosed parenthesis");
return value;
}
else if (lex< sequence< exactly<'+'>, negate< number > > >()) {
Node plus(context.new_Node(Node::unary_plus, path, line, 1));
plus << parse_factor();
plus.should_eval() = true;
return plus;
}
else if (lex< sequence< exactly<'-'>, negate< number> > >()) {
Node minus(context.new_Node(Node::unary_minus, path, line, 1));
minus << parse_factor();
minus.should_eval() = true;
return minus;
}
else {
return parse_value();
}
}
Node Document::parse_value()
{
if (lex< uri_prefix >())
{
Node result(context.new_Node(Node::uri, path, line, 1));
if (lex< variable >()) {
result << context.new_Node(Node::variable, path, line, lexed);
result.should_eval() = true;
}
else if (lex< string_constant >()) {
result << parse_string();
result.should_eval() = true;
}
else if (lex< url_schema >()) {
result << Document::make_from_token(context, lexed, path, line).parse_url_schema();
result.should_eval() = true;
}
else if (lex< url_value >()) {
result << context.new_Node(Node::identifier, path, line, lexed);
}
else {
const char* value = position;
const char* rparen = find_first< exactly<')'> >(position);
if (!rparen) throw_syntax_error("URI is missing ')'");
Token content_tok(Token::make(value, rparen));
Node content_node(context.new_Node(Node::identifier, path, line, content_tok));
// lex< string_constant >();
result << content_node;
position = rparen;
}
if (!lex< exactly<')'> >()) throw_syntax_error("URI is missing ')'");
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(); }
if (lex< sequence< true_val, negate< identifier > > >())
{ return context.new_Node(Node::boolean, path, line, true); }
if (lex< sequence< false_val, negate< identifier > > >())
{ return context.new_Node(Node::boolean, path, line, false); }
if (lex< important >())
{ return context.new_Node(Node::important, path, line, lexed); }
if (lex< identifier >())
{ return context.new_Node(Node::identifier, path, line, lexed); }
if (lex< percentage >())
{ return context.new_Node(Node::textual_percentage, path, line, lexed); }
if (lex< dimension >())
{ return context.new_Node(Node::textual_dimension, path, line, lexed); }
if (lex< number >())
{ return context.new_Node(Node::textual_number, path, line, lexed); }
if (lex< hex >())
{ return context.new_Node(Node::textual_hex, path, line, lexed); }
// if (lex< percentage >())
// { return context.new_Node(path, line, atof(lexed.begin), Node::numeric_percentage); }
// if (lex< dimension >()) {
// return context.new_Node(path, line, atof(lexed.begin),
// Token::make(Prelexer::number(lexed.begin), lexed.end));
// }
// if (lex< number >())
// { return context.new_Node(path, line, atof(lexed.begin)); }
// if (lex< hex >()) {
// Node triple(context.new_Node(Node::numeric_color, path, line, 4));
// Token hext(Token::make(lexed.begin+1, lexed.end));
// if (hext.length() == 6) {
// for (int i = 0; i < 6; i += 2) {
// triple << context.new_Node(path, line, static_cast<double>(strtol(string(hext.begin+i, 2).c_str(), NULL, 16)));
// }
// }
// else {
// for (int i = 0; i < 3; ++i) {
// triple << context.new_Node(path, line, static_cast<double>(strtol(string(2, hext.begin[i]).c_str(), NULL, 16)));
// }
// }
// triple << context.new_Node(path, line, 1.0);
// return triple;
// }
if (peek< string_constant >())
{ return parse_string(); }
if (lex< variable >())
{
Node var(context.new_Node(Node::variable, path, line, lexed));
var.should_eval() = true;
return var;
}
throw_syntax_error("error reading values after " + lexed.to_string());
// unreachable statement
return Node();
}
Node Document::parse_string()
{
lex< string_constant >();
Token str(lexed);
const char* i = str.begin;
// see if there any interpolants
const char* p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(str.begin, str.end);
if (!p) {
Node result(context.new_Node(Node::string_constant, path, line, str));
result.is_quoted() = true;
return result;
}
Node schema(context.new_Node(Node::string_schema, path, line, 1));
while (i < str.end) {
p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(i, str.end);
if (p) {
if (i < p) {
schema << context.new_Node(Node::identifier, path, line, Token::make(i, p)); // accumulate the preceding segment if it's nonempty
}
const char* j = find_first_in_interval< exactly<rbrace> >(p, str.end); // find the closing brace
if (j) {
// parse the interpolant and accumulate it
Node interp_node(Document::make_from_token(context, Token::make(p+2, j), path, line).parse_list());
interp_node.should_eval() = true;
schema << interp_node;
i = j+1;
}
else {
// throw an error if the interpolant is unterminated
throw_syntax_error("unterminated interpolant inside string constant " + str.to_string());
}
}
else { // no interpolants left; add the last segment if nonempty
if (i < str.end) schema << context.new_Node(Node::identifier, path, line, Token::make(i, str.end));
break;
}
}
schema.is_quoted() = true;
schema.should_eval() = true;
return schema;
}
Node Document::parse_value_schema()
{
Node schema(context.new_Node(Node::value_schema, path, line, 1));
while (position < end) {
if (lex< interpolant >()) {
Token insides(Token::make(lexed.begin + 2, lexed.end - 1));
Node interp_node(Document::make_from_token(context, insides, path, line).parse_list());
interp_node.should_eval() = true;
schema << interp_node;
}
else if (lex< identifier >()) {
schema << context.new_Node(Node::identifier, path, line, lexed);
}
else if (lex< percentage >()) {
schema << context.new_Node(Node::textual_percentage, path, line, lexed);
// schema << context.new_Node(path, line, atof(lexed.begin), Node::numeric_percentage);
}
else if (lex< dimension >()) {
schema << context.new_Node(Node::textual_dimension, path, line, lexed);
// schema << context.new_Node(path, line, atof(lexed.begin),
// Token::make(Prelexer::number(lexed.begin), lexed.end));
}
else if (lex< number >()) {
schema << context.new_Node(Node::textual_number, path, line, lexed);
// schema << context.new_Node(path, line, atof(lexed.begin));
}
else if (lex< hex >()) {
schema << context.new_Node(Node::textual_hex, path, line, lexed);
// Node triple(context.new_Node(Node::numeric_color, path, line, 4));
// Token hext(Token::make(lexed.begin+1, lexed.end));
// if (hext.length() == 6) {
// for (int i = 0; i < 6; i += 2) {
// triple << context.new_Node(path, line, static_cast<double>(strtol(string(hext.begin+i, 2).c_str(), NULL, 16)));
// }
// }
// else {
// for (int i = 0; i < 3; ++i) {
// triple << context.new_Node(path, line, static_cast<double>(strtol(string(2, hext.begin[i]).c_str(), NULL, 16)));
// }
// }
// triple << context.new_Node(path, line, 1.0);
// schema << triple;
}
else if (lex< string_constant >()) {
Node str(context.new_Node(Node::string_constant, path, line, lexed));
str.is_quoted() = true;
schema << str;
}
else if (lex< variable >()) {
schema << context.new_Node(Node::variable, path, line, lexed);
}
else {
throw_syntax_error("error parsing interpolated value");
}
}
schema.should_eval() = true;
return schema;
}
Node Document::parse_url_schema()
{
Node schema(context.new_Node(Node::value_schema, path, line, 1));
while (position < end) {
if (position[0] == '/') {
lexed = Token::make(position, position+1);
schema << context.new_Node(Node::identifier, path, line, lexed);
++position;
}
else if (lex< interpolant >()) {
Token insides(Token::make(lexed.begin + 2, lexed.end - 1));
Node interp_node(Document::make_from_token(context, insides, path, line).parse_list());
interp_node.should_eval() = true;
schema << interp_node;
}
else if (lex< sequence< identifier, exactly<':'> > >()) {
schema << context.new_Node(Node::identifier, path, line, lexed);
}
else if (lex< filename >()) {
schema << context.new_Node(Node::identifier, path, line, lexed);
}
else {
throw_syntax_error("error parsing interpolated url");
}
}
schema.should_eval() = true;
return schema;
}
Node Document::parse_identifier_schema()
{
lex< sequence< optional< exactly<'*'> >, identifier_schema > >();
Token id(lexed);
const char* i = id.begin;
// see if there any interpolants
const char* p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(id.begin, id.end);
if (!p) {
return context.new_Node(Node::string_constant, path, line, id);
}
Node schema(context.new_Node(Node::identifier_schema, path, line, 1));
while (i < id.end) {
p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(i, id.end);
if (p) {
if (i < p) {
schema << context.new_Node(Node::identifier, path, line, Token::make(i, p)); // accumulate the preceding segment if it's nonempty
}
const char* j = find_first_in_interval< exactly<rbrace> >(p, id.end); // find the closing brace
if (j) {
// parse the interpolant and accumulate it
Node interp_node(Document::make_from_token(context, Token::make(p+2, j), path, line).parse_list());
interp_node.should_eval() = true;
schema << interp_node;
i = j+1;
}
else {
// throw an error if the interpolant is unterminated
throw_syntax_error("unterminated interpolant inside interpolated identifier " + id.to_string());
}
}
else { // no interpolants left; add the last segment if nonempty
if (i < id.end) schema << context.new_Node(Node::identifier, path, line, Token::make(i, id.end));
break;
}
}
schema.should_eval() = true;
return schema;
}
Node Document::parse_function_call()
{
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, name.path(), name.line(), 2));
call << name << args;
call.should_eval() = true;
return call;
}
Node Document::parse_if_directive(Node surrounding_ruleset, Node::Type inside_of)
{
lex< if_directive >();
Node conditional(context.new_Node(Node::if_directive, path, line, 2));
conditional << parse_list(); // the predicate
if (!lex< exactly<'{'> >()) throw_syntax_error("expected '{' after the predicate for @if");
conditional << parse_block(surrounding_ruleset, inside_of); // the consequent
// collect all "@else if"s
while (lex< elseif_directive >()) {
conditional << parse_list(); // the next predicate
if (!lex< exactly<'{'> >()) throw_syntax_error("expected '{' after the predicate for @else if");
conditional << parse_block(surrounding_ruleset, inside_of); // the next consequent
}
// parse the "@else" if present
if (lex< else_directive >()) {
if (!lex< exactly<'{'> >()) throw_syntax_error("expected '{' after @else");
conditional << parse_block(surrounding_ruleset, inside_of); // the alternative
}
return conditional;
}
Node Document::parse_for_directive(Node surrounding_ruleset, Node::Type inside_of)
{
lex< for_directive >();
size_t for_line = line;
if (!lex< variable >()) throw_syntax_error("@for directive requires an iteration variable");
Node var(context.new_Node(Node::variable, path, line, lexed));
if (!lex< from >()) throw_syntax_error("expected 'from' keyword in @for directive");
Node lower_bound(parse_expression());
Node::Type for_type = Node::for_through_directive;
if (lex< through >()) for_type = Node::for_through_directive;
else if (lex< to >()) for_type = Node::for_to_directive;
else throw_syntax_error("expected 'through' or 'to' keywod in @for directive");
Node upper_bound(parse_expression());
if (!peek< exactly<'{'> >()) throw_syntax_error("expected '{' after the upper bound in @for directive");
Node body(parse_block(surrounding_ruleset, inside_of));
Node loop(context.new_Node(for_type, path, for_line, 4));
loop << var << lower_bound << upper_bound << body;
return loop;
}
Node Document::parse_each_directive(Node surrounding_ruleset, Node::Type inside_of)
{
lex < each_directive >();
size_t each_line = line;
if (!lex< variable >()) throw_syntax_error("@each directive requires an iteration variable");
Node var(context.new_Node(Node::variable, path, line, lexed));
if (!lex< in >()) throw_syntax_error("expected 'in' keyword in @each directive");
Node list(parse_list());
if (!peek< exactly<'{'> >()) throw_syntax_error("expected '{' after the upper bound in @each directive");
Node body(parse_block(surrounding_ruleset, inside_of));
Node each(context.new_Node(Node::each_directive, path, each_line, 3));
each << var << list << body;
return each;
}
Node Document::parse_while_directive(Node surrounding_ruleset, Node::Type inside_of)
{
lex< while_directive >();
size_t while_line = line;
Node predicate(parse_list());
Node body(parse_block(surrounding_ruleset, inside_of));
Node loop(context.new_Node(Node::while_directive, path, while_line, 2));
loop << predicate << body;
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 >();
Node media_query(context.new_Node(Node::media_query, path, line, 2));
Node media_expr(parse_media_expression());
if (peek< exactly<'{'> >()) {
media_query << media_expr;
}
else if (peek< exactly<','> >()) {
Node media_expr_group(context.new_Node(Node::media_expression_group, path, line, 2));
media_expr_group << media_expr;
while (lex< exactly<','> >()) {
media_expr_group << parse_media_expression();
}
media_query << media_expr_group;
}
else {
throw_syntax_error("expected '{' in media query");
}
media_query << parse_block(Node(), inside_of);
return media_query;
}
Node Document::parse_media_expression()
{
Node media_expr(context.new_Node(Node::media_expression, path, line, 1));
// if the query begins with 'not' or 'only', then a media type is required
if (lex< not_op >() || lex< exactly<only_kwd> >()) {
media_expr << context.new_Node(Node::identifier, path, line, lexed);
if (!lex< identifier >()) throw_syntax_error("media type expected in media query");
media_expr << context.new_Node(Node::identifier, path, line, lexed);
}
// otherwise, the media type is optional
else if (lex< identifier >()) {
media_expr << context.new_Node(Node::identifier, path, line, lexed);
}
// if no media type was present, then require a parenthesized property
if (media_expr.empty()) {
if (!lex< exactly<'('> >()) throw_syntax_error("invalid media query");
media_expr << parse_rule();
if (!lex< exactly<')'> >()) throw_syntax_error("unclosed parenthesis");
}
// parse the rest of the properties for this disjunct
while (!peek< exactly<','> >() && !peek< exactly<'{'> >()) {
if (!lex< and_op >()) throw_syntax_error("invalid media query");
media_expr << context.new_Node(Node::identifier, path, line, lexed);
if (!lex< exactly<'('> >()) throw_syntax_error("invalid media query");
media_expr << parse_rule();
if (!lex< exactly<')'> >()) throw_syntax_error("unclosed parenthesis");
}
return media_expr;
}
Node Document::parse_warning()
{
lex< warn >();
Node warning(context.new_Node(Node::warning, path, line, 1));
warning << parse_list();
warning[0].should_eval() = true;
return warning;
}
Selector_Lookahead Document::lookahead_for_selector(const char* start)
{
const char* p = start ? start : position;
const char* q;
bool saw_interpolant = false;
while ((q = peek< identifier >(p)) ||
(q = peek< id_name >(p)) ||
(q = peek< class_name >(p)) ||
(q = peek< sequence< pseudo_prefix, identifier > >(p)) ||
(q = peek< string_constant >(p)) ||
(q = peek< exactly<'*'> >(p)) ||
(q = peek< exactly<'('> >(p)) ||
(q = peek< exactly<')'> >(p)) ||
(q = peek< exactly<'['> >(p)) ||
(q = peek< exactly<']'> >(p)) ||
(q = peek< exactly<'+'> >(p)) ||
(q = peek< exactly<'~'> >(p)) ||
(q = peek< exactly<'>'> >(p)) ||
(q = peek< exactly<','> >(p)) ||
(q = peek< binomial >(p)) ||
(q = peek< sequence< optional<sign>,
optional<digits>,
exactly<'n'> > >(p)) ||
(q = peek< sequence< optional<sign>,
digits > >(p)) ||
(q = peek< number >(p)) ||
(q = peek< exactly<'&'> >(p)) ||
(q = peek< alternatives<exact_match,
class_match,
dash_match,
prefix_match,
suffix_match,
substring_match> >(p)) ||
(q = peek< sequence< exactly<'.'>, interpolant > >(p)) ||
(q = peek< sequence< exactly<'#'>, interpolant > >(p)) ||
(q = peek< sequence< exactly<'-'>, interpolant > >(p)) ||
(q = peek< sequence< pseudo_prefix, interpolant > >(p)) ||
(q = peek< interpolant >(p))) {
p = q;
if (*(p - 1) == '}') saw_interpolant = true;
}
Selector_Lookahead result;
result.found = peek< exactly<'{'> >(p) ? p : 0;
result.has_interpolants = saw_interpolant;
return result;
}
Selector_Lookahead Document::lookahead_for_extension_target(const char* start)
{
const char* p = start ? start : position;
const char* q;
bool saw_interpolant = false;
while ((q = peek< identifier >(p)) ||
(q = peek< id_name >(p)) ||
(q = peek< class_name >(p)) ||
(q = peek< sequence< pseudo_prefix, identifier > >(p)) ||
(q = peek< string_constant >(p)) ||
(q = peek< exactly<'*'> >(p)) ||
(q = peek< exactly<'('> >(p)) ||
(q = peek< exactly<')'> >(p)) ||
(q = peek< exactly<'['> >(p)) ||
(q = peek< exactly<']'> >(p)) ||
(q = peek< exactly<'+'> >(p)) ||
(q = peek< exactly<'~'> >(p)) ||
(q = peek< exactly<'>'> >(p)) ||
(q = peek< exactly<','> >(p)) ||
(q = peek< binomial >(p)) ||
(q = peek< sequence< optional<sign>,
optional<digits>,
exactly<'n'> > >(p)) ||
(q = peek< sequence< optional<sign>,
digits > >(p)) ||
(q = peek< number >(p)) ||
(q = peek< exactly<'&'> >(p)) ||
(q = peek< alternatives<exact_match,
class_match,
dash_match,
prefix_match,
suffix_match,
substring_match> >(p)) ||
(q = peek< sequence< exactly<'.'>, interpolant > >(p)) ||
(q = peek< sequence< exactly<'#'>, interpolant > >(p)) ||
(q = peek< sequence< exactly<'-'>, interpolant > >(p)) ||
(q = peek< sequence< pseudo_prefix, interpolant > >(p)) ||
(q = peek< interpolant >(p))) {
p = q;
if (*(p - 1) == '}') saw_interpolant = true;
}
Selector_Lookahead result;
result.found = peek< alternatives< exactly<';'>, exactly<'}'> > >(p) ? p : 0;
result.has_interpolants = saw_interpolant;
return result;
}
}
#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
#include "eval_apply.hpp"
#include "selector.hpp"
#include "constants.hpp"
#include "prelexer.hpp"
#include "document.hpp"
#include "error.hpp"
#include <cctype>
#include <iostream>
#include <sstream>
#include <cstdlib>
namespace Sass {
using namespace Constants;
using std::cerr; using std::endl;
static void throw_eval_error(string message, string path, size_t line)
{
if (!path.empty() && Prelexer::string_constant(path.c_str()))
path = path.substr(1, path.size() - 1);
throw Error(Error::evaluation, path, line, message);
}
// Expansion function for nodes in an expansion context.
void expand(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool function_name)
{
switch (expr.type())
{
case Node::root: {
for (size_t i = 0, S = expr.size(); i < S; ++i) {
expand(expr[i], prefix, env, f_env, new_Node, ctx);
}
} break;
case Node::mixin: { // mixin definition
env[expr[0].token()] = expr;
} break;
case Node::function: { // function definition
f_env[expr[0].to_string()] = Function(expr);
} break;
case Node::mixin_call: { // mixin invocation
Token name(expr[0].token());
Node args(expr[1]);
if (!env.query(name)) throw_eval_error("mixin " + name.to_string() + " is undefined", expr.path(), expr.line());
Node mixin(env[name]);
Node expansion(apply_mixin(mixin, args, prefix, env, f_env, new_Node, ctx));
expr.pop_all(); // pop the mixin metadata
expr += expansion; // push the expansion
} break;
case Node::propset: {
// TO DO: perform the property expansion here, rather than in the emitter (also requires the parser to allow interpolants in the property names)
expand(expr[1], prefix, env, f_env, new_Node, ctx);
} break;
case Node::ruleset: {
// if the selector contains interpolants, eval it and re-parse
if (expr[0].type() == Node::selector_schema) {
Node schema(expr[0]);
string expansion;
for (size_t i = 0, S = schema.size(); i < S; ++i) {
schema[i] = eval(schema[i], prefix, env, f_env, new_Node, ctx);
if (schema[i].type() == Node::string_constant) {
expansion += schema[i].token().unquote();
}
else {
expansion += schema[i].to_string();
}
}
// need to re-parse the selector because its structure may have changed
expansion += " {"; // the parser looks for an lbrace to end a selector
char* expn_src = new char[expansion.size() + 1];
strcpy(expn_src, expansion.c_str());
Document needs_reparsing(Document::make_from_source_chars(ctx, expn_src, schema.path(), true));
needs_reparsing.line = schema.line(); // set the line number to the original node's line
expr[0] = needs_reparsing.parse_selector_group();
}
// expand the selector with the prefix and save it in expr[2]
expr << expand_selector(expr[0], prefix, new_Node);
// // gather selector extensions into a pending queue
// if (ctx.has_extensions) {
// // check single selector
// if (expr.back().type() != Node::selector_group) {
// Node sel(selector_base(expr.back()));
// if (ctx.extensions.count(sel)) {
// for (multimap<Node, Node>::iterator i = ctx.extensions.lower_bound(sel); i != ctx.extensions.upper_bound(sel); ++i) {
// ctx.pending_extensions.push_back(pair<Node, Node>(expr, i->second));
// }
// }
// }
// // individually check each selector in a group
// else {
// Node group(expr.back());
// for (size_t i = 0, S = group.size(); i < S; ++i) {
// Node sel(selector_base(group[i]));
// if (ctx.extensions.count(sel)) {
// for (multimap<Node, Node>::iterator j = ctx.extensions.lower_bound(sel); j != ctx.extensions.upper_bound(sel); ++j) {
// ctx.pending_extensions.push_back(pair<Node, Node>(expr, j->second));
// }
// }
// }
// }
// }
// expand the body with the newly expanded selector as the prefix
// cerr << "ORIGINAL SELECTOR:\t" << expr[2].to_string() << endl;
// cerr << "NORMALIZED SELECTOR:\t" << normalize_selector(expr[2], new_Node).to_string() << endl << endl;
expand(expr[1], expr.back(), env, f_env, new_Node, ctx);
} break;
case Node::media_query: {
Node block(expr[1]);
Node new_ruleset(new_Node(Node::ruleset, expr.path(), expr.line(), 3));
expr[1] = new_ruleset << prefix << block << prefix;
expand(expr[1], new_Node(Node::none, expr.path(), expr.line(), 0), env, f_env, new_Node, ctx);
} break;
case Node::block: {
Environment new_frame;
new_frame.link(env);
for (size_t i = 0, S = expr.size(); i < S; ++i) {
expand(expr[i], prefix, new_frame, f_env, new_Node, ctx);
}
} break;
case Node::assignment: {
Node var(expr[0]);
if (expr.is_guarded() && env.query(var.token())) return;
Node val(expr[1]);
if (val.type() == Node::list) {
for (size_t i = 0, S = val.size(); i < S; ++i) {
if (val[i].should_eval()) val[i] = eval(val[i], prefix, env, f_env, new_Node, ctx);
}
}
else {
val = eval(val, prefix, env, f_env, new_Node, ctx);
}
// If a binding exists (possibly upframe), then update it.
// Otherwise, make a new on in the current frame.
if (env.query(var.token())) {
env[var.token()] = val;
}
else {
env.current_frame[var.token()] = val;
}
} break;
case Node::rule: {
Node lhs(expr[0]);
if (lhs.is_schema()) {
expr[0] = eval(lhs, prefix, env, f_env, new_Node, ctx);
}
Node rhs(expr[1]);
if (rhs.type() == Node::list) {
for (size_t i = 0, S = rhs.size(); i < S; ++i) {
if (rhs[i].should_eval()) {
rhs[i] = eval(rhs[i], prefix, env, f_env, new_Node, ctx);
}
}
}
else if (rhs.is_schema() || rhs.should_eval()) {
expr[1] = eval(rhs, prefix, env, f_env, new_Node, ctx);
}
} break;
case Node::extend_directive: {
if (prefix.is_null()) throw_eval_error("@extend directive may only be used within rules", expr.path(), expr.line());
// if the extendee contains interpolants, eval it and re-parse
if (expr[0].type() == Node::selector_schema) {
Node schema(expr[0]);
string expansion;
for (size_t i = 0, S = schema.size(); i < S; ++i) {
schema[i] = eval(schema[i], prefix, env, f_env, new_Node, ctx);
if (schema[i].type() == Node::string_constant) {
expansion += schema[i].token().unquote();
}
else {
expansion += schema[i].to_string();
}
}
// need to re-parse the selector because its structure may have changed
expansion += " {"; // the parser looks for an lbrace to end a selector
char* expn_src = new char[expansion.size() + 1];
strcpy(expn_src, expansion.c_str());
Document needs_reparsing(Document::make_from_source_chars(ctx, expn_src, schema.path(), true));
needs_reparsing.line = schema.line(); // set the line number to the original node's line
expr[0] = needs_reparsing.parse_selector_group();
}
// only simple selector sequences may be extended
switch (expr[0].type())
{
case Node::selector_group:
throw_eval_error("selector groups may not be extended", expr[0].path(), expr[0].line());
break;
case Node::selector:
throw_eval_error("nested selectors may not be extended", expr[0].path(), expr[0].line());
break;
default:
break;
}
// each extendee maps to a set of extenders: extendee -> { extenders }
// if it's a single selector, just add it to the set
if (prefix.type() != Node::selector_group) {
ctx.extensions.insert(pair<Node, Node>(expr[0], prefix));
}
// otherwise add each member of the selector group separately
else {
for (size_t i = 0, S = prefix.size(); i < S; ++i) {
ctx.extensions.insert(pair<Node, Node>(expr[0], prefix[i]));
}
}
ctx.has_extensions = true;
} break;
case Node::if_directive: {
Node expansion = Node();
for (size_t i = 0, S = expr.size(); i < S; i += 2) {
if (expr[i].type() != Node::block) {
Node predicate_val(eval(expr[i], prefix, env, f_env, new_Node, ctx));
if (!predicate_val.is_false()) {
expand(expansion = expr[i+1], prefix, env, f_env, new_Node, ctx);
break;
}
}
else {
expand(expansion = expr[i], prefix, env, f_env, new_Node, ctx);
break;
}
}
expr.pop_all();
if (!expansion.is_null()) expr += expansion;
} break;
case Node::for_through_directive:
case Node::for_to_directive: {
Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3));
Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 1));
fake_mixin << new_Node(Node::identifier, "", 0, Token::make(for_kwd)) // stub name for debugging
<< (fake_param << expr[0]) // iteration variable
<< expr[3]; // body
Node lower_bound(eval(expr[1], prefix, env, f_env, new_Node, ctx));
Node upper_bound(eval(expr[2], prefix, env, f_env, new_Node, ctx));
if (!(lower_bound.is_numeric() && upper_bound.is_numeric())) {
throw_eval_error("bounds of @for directive must be numeric", expr.path(), expr.line());
}
expr.pop_all();
for (double i = lower_bound.numeric_value(),
U = upper_bound.numeric_value() + ((expr.type() == Node::for_to_directive) ? 0 : 1);
i < U;
++i) {
Node i_node(new_Node(expr.path(), expr.line(), i));
Node fake_arg(new_Node(Node::arguments, expr.path(), expr.line(), 1));
fake_arg << i_node;
expr += apply_mixin(fake_mixin, fake_arg, prefix, env, f_env, new_Node, ctx, true);
}
} break;
case Node::each_directive: {
Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3));
Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 1));
fake_mixin << new_Node(Node::identifier, "", 0, Token::make(each_kwd)) // stub name for debugging
<< (fake_param << expr[0]) // iteration variable
<< expr[2]; // body
Node list(eval(expr[1], prefix, env, f_env, new_Node, ctx));
// If the list isn't really a list, make a singleton out of it.
if (list.type() != Node::list) {
list = (new_Node(Node::list, list.path(), list.line(), 1) << list);
}
expr.pop_all();
for (size_t i = 0, S = list.size(); i < S; ++i) {
Node fake_arg(new_Node(Node::arguments, expr.path(), expr.line(), 1));
list[i].should_eval() = true;
fake_arg << eval(list[i], prefix, env, f_env, new_Node, ctx);
expr += apply_mixin(fake_mixin, fake_arg, prefix, env, f_env, new_Node, ctx, true);
}
} break;
case Node::while_directive: {
Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3));
Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 0));
Node fake_arg(new_Node(Node::arguments, expr.path(), expr.line(), 0));
fake_mixin << new_Node(Node::identifier, "", 0, Token::make(while_kwd)) // stub name for debugging
<< fake_param // no iteration variable
<< expr[1]; // body
Node pred(expr[0]);
expr.pop_back();
expr.pop_back();
Node ev_pred(eval(pred, prefix, env, f_env, new_Node, ctx));
while (!ev_pred.is_false()) {
expr += apply_mixin(fake_mixin, fake_arg, prefix, env, f_env, new_Node, ctx, true);
ev_pred = eval(pred, prefix, env, f_env, new_Node, ctx);
}
} break;
case Node::block_directive: {
// TO DO: eval the directive name for interpolants
expand(expr[1], new_Node(Node::none, expr.path(), expr.line(), 0), env, f_env, new_Node, ctx);
} break;
case Node::warning: {
Node contents(eval(expr[0], Node(), env, f_env, new_Node, ctx));
string prefix("WARNING: ");
string indent(" ");
string result(contents.to_string());
if (contents.type() == Node::string_constant || contents.type() == Node::string_schema) {
result = result.substr(1, result.size()-2); // unquote if it's a single string
}
// These cerrs aren't log lines! They're supposed to be here!
cerr << prefix << result << endl;
cerr << indent << "on line " << expr.line() << " of " << expr.path();
cerr << endl << endl;
} break;
default: {
// do nothing
} break;
}
}
void expand_list(Node list, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx)
{
for (size_t i = 0, S = list.size(); i < S; ++i) {
list[i].should_eval() = true;
list[i] = eval(list[i], prefix, env, f_env, new_Node, ctx);
}
}
// Evaluation function for nodes in a value context.
Node eval(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool function_name)
{
Node result = Node();
switch (expr.type())
{
case Node::list: {
if (expr.should_eval() && expr.size() > 0) {
result = new_Node(Node::list, expr.path(), expr.line(), expr.size());
result.is_comma_separated() = expr.is_comma_separated();
result << eval(expr[0], prefix, env, f_env, new_Node, ctx);
for (size_t i = 1, S = expr.size(); i < S; ++i) result << expr[i];
}
} break;
case Node::disjunction: {
for (size_t i = 0, S = expr.size(); i < S; ++i) {
result = eval(expr[i], prefix, env, f_env, new_Node, ctx);
if (result.is_false()) continue;
else break;
}
} break;
case Node::conjunction: {
for (size_t i = 0, S = expr.size(); i < S; ++i) {
result = eval(expr[i], prefix, env, f_env, new_Node, ctx);
if (result.is_false()) break;
}
} break;
case Node::relation: {
Node lhs(new_Node(Node::arguments, expr[0].path(), expr[0].line(), 1));
Node rhs(new_Node(Node::arguments, expr[2].path(), expr[2].line(), 1));
Node rel(expr[1]);
lhs << expr[0];
rhs << expr[2];
lhs = eval_arguments(lhs, prefix, env, f_env, new_Node, ctx);
rhs = eval_arguments(rhs, prefix, env, f_env, new_Node, ctx);
lhs = lhs[0];
rhs = rhs[0];
if (lhs.type() == Node::list) expand_list(lhs, prefix, env, f_env, new_Node, ctx);
if (rhs.type() == Node::list) expand_list(rhs, prefix, env, f_env, new_Node, ctx);
Node T(new_Node(Node::boolean, lhs.path(), lhs.line(), true));
Node F(new_Node(Node::boolean, lhs.path(), lhs.line(), false));
switch (rel.type())
{
case Node::eq: result = ((lhs == rhs) ? T : F); break;
case Node::neq: result = ((lhs != rhs) ? T : F); break;
case Node::gt: result = ((lhs > rhs) ? T : F); break;
case Node::gte: result = ((lhs >= rhs) ? T : F); break;
case Node::lt: result = ((lhs < rhs) ? T : F); break;
case Node::lte: result = ((lhs <= rhs) ? T : F); break;
default:
throw_eval_error("unknown comparison operator " + expr.token().to_string(), expr.path(), expr.line());
}
} break;
case Node::expression: {
Node list(new_Node(Node::expression, expr.path(), expr.line(), expr.size()));
for (size_t i = 0, S = expr.size(); i < S; ++i) {
list << eval(expr[i], prefix, env, f_env, new_Node, ctx);
}
result = reduce(list, 1, list[0], new_Node);
} break;
case Node::term: {
if (expr.should_eval()) {
Node list(new_Node(Node::term, expr.path(), expr.line(), expr.size()));
for (size_t i = 0, S = expr.size(); i < S; ++i) {
list << eval(expr[i], prefix, env, f_env, new_Node, ctx);
}
result = reduce(list, 1, list[0], new_Node);
}
} break;
case Node::textual_percentage: {
result = new_Node(expr.path(), expr.line(), std::atof(expr.token().begin), Node::numeric_percentage);
} break;
case Node::textual_dimension: {
result = new_Node(expr.path(), expr.line(),
std::atof(expr.token().begin),
Token::make(Prelexer::number(expr.token().begin),
expr.token().end));
} break;
case Node::textual_number: {
result = new_Node(expr.path(), expr.line(), std::atof(expr.token().begin));
} break;
case Node::textual_hex: {
result = new_Node(Node::numeric_color, expr.path(), expr.line(), 4);
Token hext(Token::make(expr.token().begin+1, expr.token().end));
if (hext.length() == 6) {
for (int i = 0; i < 6; i += 2) {
result << new_Node(expr.path(), expr.line(), static_cast<double>(std::strtol(string(hext.begin+i, 2).c_str(), NULL, 16)));
}
}
else {
for (int i = 0; i < 3; ++i) {
result << new_Node(expr.path(), expr.line(), static_cast<double>(std::strtol(string(2, hext.begin[i]).c_str(), NULL, 16)));
}
}
result << new_Node(expr.path(), expr.line(), 1.0);
} break;
case Node::variable: {
if (!env.query(expr.token())) throw_eval_error("reference to unbound variable " + expr.token().to_string(), expr.path(), expr.line());
result = env[expr.token()];
} break;
case Node::uri: {
result = new_Node(Node::uri, expr.path(), expr.line(), 1);
result << eval(expr[0], prefix, env, f_env, new_Node, ctx);
} break;
case Node::function_call: {
// TO DO: default-constructed Function should be a generic callback (maybe)
// eval the function name in case it's interpolated
Node name_node(eval(expr[0], prefix, env, f_env, new_Node, ctx, true));
string name(name_node.to_string());
if (!f_env.count(name)) {
// no definition available; just pass it through (with evaluated args)
Node args(expr[1]);
Node evaluated_args(new_Node(Node::arguments, args.path(), args.line(), args.size()));
for (size_t i = 0, S = args.size(); i < S; ++i) {
evaluated_args << eval(args[i], prefix, env, f_env, new_Node, ctx);
if (evaluated_args.back().type() == Node::list) {
Node arg_list(evaluated_args.back());
for (size_t j = 0, S = arg_list.size(); j < S; ++j) {
if (arg_list[j].should_eval()) arg_list[j] = eval(arg_list[j], prefix, env, f_env, new_Node, ctx);
}
}
}
result = new_Node(Node::function_call, expr.path(), expr.line(), 2);
result << name_node << evaluated_args;
}
else {
// check to see if the function is primitive/built-in
Function f(f_env[name]);
if (f.overloaded) {
stringstream s;
s << name << " " << expr[1].size();
string resolved_name(s.str());
if (!f_env.count(resolved_name)) throw_eval_error("wrong number of arguments to " + name, expr.path(), expr.line());
f = f_env[resolved_name];
}
result = apply_function(f, expr[1], prefix, env, f_env, new_Node, ctx, expr.path(), expr.line());
}
} break;
case Node::unary_plus: {
Node arg(eval(expr[0], prefix, env, f_env, new_Node, ctx));
if (arg.is_numeric()) {
result = arg;
}
else {
result = new_Node(Node::unary_plus, expr.path(), expr.line(), 1);
result << arg;
}
} break;
case Node::unary_minus: {
Node arg(eval(expr[0], prefix, env, f_env, new_Node, ctx));
if (arg.is_numeric()) {
result = new_Node(expr.path(), expr.line(), -arg.numeric_value());
}
else {
result = new_Node(Node::unary_minus, expr.path(), expr.line(), 1);
result << arg;
}
} break;
case Node::identifier: {
string id_str(expr.to_string());
to_lowercase(id_str);
if (!function_name && ctx.color_names_to_values.count(id_str)) {
Node color_orig(ctx.color_names_to_values[id_str]);
Node r(color_orig[0]);
Node g(color_orig[1]);
Node b(color_orig[2]);
Node a(color_orig[3]);
result = new_Node(expr.path(), expr.line(),
r.numeric_value(),
g.numeric_value(),
b.numeric_value(),
a.numeric_value());
}
} break;
case Node::string_schema:
case Node::value_schema:
case Node::identifier_schema: {
result = new_Node(expr.type(), expr.path(), expr.line(), expr.size());
for (size_t i = 0, S = expr.size(); i < S; ++i) {
result << eval(expr[i], prefix, env, f_env, new_Node, ctx);
}
result.is_quoted() = expr.is_quoted();
} break;
case Node::css_import: {
result = new_Node(Node::css_import, expr.path(), expr.line(), 1);
result << eval(expr[0], prefix, env, f_env, new_Node, ctx);
} break;
default: {
result = expr;
} break;
}
if (result.is_null()) result = expr;
return result;
}
// Reduce arithmetic operations. Arithmetic expressions are stored as vectors
// of operands with operators interspersed, rather than as the usual binary
// tree. (This function is essentially a left fold.)
Node reduce(Node list, size_t head, Node acc, Node_Factory& new_Node)
{
if (head >= list.size()) return acc;
Node op(list[head]);
Node rhs(list[head + 1]);
Node::Type optype = op.type();
Node::Type ltype = acc.type();
Node::Type rtype = rhs.type();
if (ltype == Node::number && rtype == Node::number) {
acc = new_Node(list.path(), list.line(), operate(op, acc.numeric_value(), rhs.numeric_value()));
}
else if (ltype == Node::number && rtype == Node::numeric_dimension) {
acc = new_Node(list.path(), list.line(), operate(op, acc.numeric_value(), rhs.numeric_value()), rhs.unit());
}
else if (ltype == Node::numeric_dimension && rtype == Node::number) {
acc = new_Node(list.path(), list.line(), operate(op, acc.numeric_value(), rhs.numeric_value()), acc.unit());
}
else if (ltype == Node::numeric_dimension && rtype == Node::numeric_dimension) {
// TO DO: TRUE UNIT ARITHMETIC
if (optype == Node::div) {
acc = new_Node(list.path(), list.line(), operate(op, acc.numeric_value(), rhs.numeric_value()));
}
else {
acc = new_Node(list.path(), list.line(), operate(op, acc.numeric_value(), rhs.numeric_value()), acc.unit());
}
}
else if (ltype == Node::number && rtype == Node::numeric_color) {
if (optype == Node::add || optype == Node::mul) {
double r = operate(op, acc.numeric_value(), rhs[0].numeric_value());
double g = operate(op, acc.numeric_value(), rhs[1].numeric_value());
double b = operate(op, acc.numeric_value(), rhs[2].numeric_value());
double a = rhs[3].numeric_value();
acc = new_Node(list.path(), list.line(), r, g, b, a);
}
else {
acc = (new_Node(Node::value_schema, list.path(), list.line(), 3) << acc);
acc << op;
acc << rhs;
}
}
else if (ltype == Node::numeric_color && rtype == Node::number) {
double r = operate(op, acc[0].numeric_value(), rhs.numeric_value());
double g = operate(op, acc[1].numeric_value(), rhs.numeric_value());
double b = operate(op, acc[2].numeric_value(), rhs.numeric_value());
double a = acc[3].numeric_value();
acc = new_Node(list.path(), list.line(), r, g, b, a);
}
else if (ltype == Node::numeric_color && rtype == Node::numeric_color) {
if (acc[3].numeric_value() != rhs[3].numeric_value()) throw_eval_error("alpha channels must be equal for " + acc.to_string() + " + " + rhs.to_string(), acc.path(), acc.line());
double r = operate(op, acc[0].numeric_value(), rhs[0].numeric_value());
double g = operate(op, acc[1].numeric_value(), rhs[1].numeric_value());
double b = operate(op, acc[2].numeric_value(), rhs[2].numeric_value());
double a = acc[3].numeric_value();
acc = new_Node(list.path(), list.line(), r, g, b, a);
}
else if (ltype == Node::concatenation && rtype == Node::concatenation) {
if (optype != Node::add) acc << op;
acc += rhs;
}
else if (ltype == Node::concatenation) {
if (optype != Node::add) acc << op;
acc << rhs;
}
else if (rtype == Node::concatenation) {
acc = (new_Node(Node::concatenation, list.path(), list.line(), 2) << acc);
if (optype != Node::add) acc << op;
acc += rhs;
acc.is_quoted() = acc[0].is_quoted();
}
else if (acc.is_string() || rhs.is_string()) {
acc = (new_Node(Node::concatenation, list.path(), list.line(), 2) << acc);
if (optype != Node::add) acc << op;
acc << rhs;
if (acc[0].is_quoted() || (ltype == Node::number && rhs.is_quoted())) {
acc.is_quoted() = true;
}
else {
acc.is_quoted() = false;
}
}
else { // lists or schemas
if (acc.is_schema() && rhs.is_schema()) {
if (optype != Node::add) acc << op;
acc += rhs;
}
else if (acc.is_schema()) {
if (optype != Node::add) acc << op;
acc << rhs;
}
else if (rhs.is_schema()) {
acc = (new_Node(Node::value_schema, list.path(), list.line(), 2) << acc);
if (optype != Node::add) acc << op;
acc += rhs;
}
else {
acc = (new_Node(Node::value_schema, list.path(), list.line(), 2) << acc);
if (optype != Node::add) acc << op;
acc << rhs;
}
acc.is_quoted() = false;
}
return reduce(list, head + 2, acc, new_Node);
}
// Helper for doing the actual arithmetic.
double operate(Node op, double lhs, double rhs)
{
switch (op.type())
{
case Node::add: return lhs + rhs; break;
case Node::sub: return lhs - rhs; break;
case Node::mul: return lhs * rhs; break;
case Node::div: {
if (rhs == 0) throw_eval_error("divide by zero", op.path(), op.line());
return lhs / rhs;
} break;
default: return 0; break;
}
}
Node eval_arguments(Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx)
{
Node evaluated_args(new_Node(Node::arguments, args.path(), args.line(), args.size()));
for (size_t i = 0, S = args.size(); i < S; ++i) {
if (args[i].type() != Node::assignment) {
evaluated_args << eval(args[i], prefix, env, f_env, new_Node, ctx);
if (evaluated_args.back().type() == Node::list) {
Node arg_list(evaluated_args.back());
Node new_arg_list(new_Node(Node::list, arg_list.path(), arg_list.line(), arg_list.size()));
for (size_t j = 0, S = arg_list.size(); j < S; ++j) {
if (arg_list[j].should_eval()) new_arg_list << eval(arg_list[j], prefix, env, f_env, new_Node, ctx);
else new_arg_list << arg_list[j];
}
}
}
else {
Node kwdarg(new_Node(Node::assignment, args[i].path(), args[i].line(), 2));
kwdarg << args[i][0];
kwdarg << eval(args[i][1], prefix, env, f_env, new_Node, ctx);
if (kwdarg.back().type() == Node::list) {
Node arg_list(kwdarg.back());
Node new_arg_list(new_Node(Node::list, arg_list.path(), arg_list.line(), arg_list.size()));
for (size_t j = 0, S = arg_list.size(); j < S; ++j) {
if (arg_list[j].should_eval()) new_arg_list << eval(arg_list[j], prefix, env, f_env, new_Node, ctx);
else new_arg_list << arg_list[j];
}
kwdarg[1] = new_arg_list;
}
evaluated_args << kwdarg;
}
}
// eval twice because args may be delayed
for (size_t i = 0, S = evaluated_args.size(); i < S; ++i) {
if (evaluated_args[i].type() != Node::assignment) {
evaluated_args[i].should_eval() = true;
evaluated_args[i] = eval(evaluated_args[i], prefix, env, f_env, new_Node, ctx);
if (evaluated_args[i].type() == Node::list) {
Node arg_list(evaluated_args[i]);
for (size_t j = 0, S = arg_list.size(); j < S; ++j) {
if (arg_list[j].should_eval()) arg_list[j] = eval(arg_list[j], prefix, env, f_env, new_Node, ctx);
}
}
}
else {
Node kwdarg(evaluated_args[i]);
kwdarg[1].should_eval() = true;
kwdarg[1] = eval(kwdarg[1], prefix, env, f_env, new_Node, ctx);
if (kwdarg[1].type() == Node::list) {
Node arg_list(kwdarg[1]);
for (size_t j = 0, S = arg_list.size(); j < S; ++j) {
if (arg_list[j].should_eval()) arg_list[j] = eval(arg_list[j], prefix, env, f_env, new_Node, ctx);
}
}
evaluated_args[i] = kwdarg;
}
}
return evaluated_args;
}
// Helper function for binding arguments in function and mixin calls.
// Needs the environment containing the bindings to be passed in by the
// caller. Also expects the caller to have pre-evaluated the arguments.
void bind_arguments(string callee_name, const Node params, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx)
{
// populate the env with the names of the parameters so we can check for
// correctness further down
for (size_t i = 0, S = params.size(); i < S; ++i) {
Node param(params[i]);
env.current_frame[param.type() == Node::variable ? param.token() : param[0].token()] = Node();
}
// now do the actual binding
size_t args_bound = 0, num_params = params.size();
for (size_t i = 0, j = 0, S = args.size(); i < S; ++i) {
if (j >= num_params) {
stringstream msg;
msg << callee_name << " only takes " << num_params << " arguments";
throw_eval_error(msg.str(), args.path(), args.line());
}
Node arg(args[i]), param(params[j]);
// ordinal argument; just bind and keep going
if (arg.type() != Node::assignment) {
env[param.type() == Node::variable ? param.token() : param[0].token()] = arg;
++j;
}
// keyword argument -- need to check for correctness
else {
Token arg_name(arg[0].token());
Node arg_value(arg[1]);
if (!env.query(arg_name)) {
throw_eval_error(callee_name + " has no parameter named " + arg_name.to_string(), arg.path(), arg.line());
}
if (!env[arg_name].is_null()) {
throw_eval_error(callee_name + " was passed argument " + arg_name.to_string() + " both by position and by name", arg.path(), arg.line());
}
env[arg_name] = arg_value;
++args_bound;
}
}
// now plug in the holes with default values, if any
for (size_t i = 0, S = params.size(); i < S; ++i) {
Node param(params[i]);
Token param_name((param.type() == Node::assignment ? param[0] : param).token());
if (env[param_name].is_null()) {
if (param.type() != Node::assignment) {
throw_eval_error(callee_name + " is missing argument " + param_name.to_string(), args.path(), args.line());
}
// eval default values in an environment where the previous vals have already been evaluated
env[param_name] = eval(param[1], prefix, env, f_env, new_Node, ctx);
}
}
}
// Apply a mixin -- bind the arguments in a new environment, link the new
// environment to the current one, then copy the body and eval in the new
// environment.
Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool dynamic_scope)
{
Node params(mixin[1]);
Node body(new_Node(mixin[2])); // clone the body
Node evaluated_args(eval_arguments(args, prefix, env, f_env, new_Node, ctx));
// Create a new environment for the mixin and link it to the appropriate parent
Environment bindings;
if (dynamic_scope) {
bindings.link(env);
}
else {
// C-style scope for now (current/global, nothing in between). May need
// to implement full lexical scope someday.
bindings.link(env.global ? *env.global : env);
}
// bind arguments in the extended environment
stringstream mixin_name;
mixin_name << "mixin";
if (!mixin[0].is_null()) mixin_name << " " << mixin[0].to_string();
bind_arguments(mixin_name.str(), params, evaluated_args, prefix, bindings, f_env, new_Node, ctx);
// evaluate the mixin's body
expand(body, prefix, bindings, f_env, new_Node, ctx);
return body;
}
// Apply a function -- bind the arguments and pass them to the underlying
// primitive function implementation, then return its value.
Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, string& path, size_t line)
{
Node evaluated_args(eval_arguments(args, prefix, env, f_env, new_Node, ctx));
// bind arguments
Environment bindings;
Node params(f.primitive ? f.parameters : f.definition[1]);
bindings.link(env.global ? *env.global : env);
bind_arguments("function " + f.name, params, evaluated_args, prefix, bindings, f_env, new_Node, ctx);
if (f.primitive) {
return f.primitive(f.parameter_names, bindings, new_Node, path, line);
}
else {
// TO DO: consider cloning the function body?
return eval_function(f.name, f.definition[2], bindings, new_Node, ctx, true);
}
}
// Special function for evaluating pure Sass functions. The evaluation
// algorithm is different in this case because the body needs to be
// executed and a single value needs to be returned directly, rather than
// styles being expanded and spliced in place.
Node eval_function(string name, Node body, Environment& bindings, Node_Factory& new_Node, Context& ctx, bool at_toplevel)
{
for (size_t i = 0, S = body.size(); i < S; ++i) {
Node stm(body[i]);
switch (stm.type())
{
case Node::assignment: {
Node val(stm[1]);
Node newval;
if (val.type() == Node::list) {
newval = new_Node(Node::list, val.path(), val.line(), val.size());
newval.is_comma_separated() = val.is_comma_separated();
for (size_t i = 0, S = val.size(); i < S; ++i) {
if (val[i].should_eval()) newval << eval(val[i], Node(), bindings, ctx.function_env, new_Node, ctx);
else newval << val[i];
}
}
else {
newval = eval(val, Node(), bindings, ctx.function_env, new_Node, ctx);
}
Node var(stm[0]);
if (stm.is_guarded() && bindings.query(var.token())) continue;
// If a binding exists (possibly upframe), then update it.
// Otherwise, make a new one in the current frame.
if (bindings.query(var.token())) {
bindings[var.token()] = newval;
}
else {
bindings.current_frame[var.token()] = newval;
}
} break;
case Node::if_directive: {
for (size_t j = 0, S = stm.size(); j < S; j += 2) {
if (stm[j].type() != Node::block) {
Node predicate_val(eval(stm[j], Node(), bindings, ctx.function_env, new_Node, ctx));
if (!predicate_val.is_false()) {
Node v(eval_function(name, stm[j+1], bindings, new_Node, ctx));
if (v.is_null()) break;
else return v;
}
}
else {
Node v(eval_function(name, stm[j], bindings, new_Node, ctx));
if (v.is_null()) break;
else return v;
}
}
} break;
case Node::for_through_directive:
case Node::for_to_directive: {
Node::Type for_type = stm.type();
Node iter_var(stm[0]);
Node lower_bound(eval(stm[1], Node(), bindings, ctx.function_env, new_Node, ctx));
Node upper_bound(eval(stm[2], Node(), bindings, ctx.function_env, new_Node, ctx));
Node for_body(stm[3]);
Environment for_env; // re-use this env for each iteration
for_env.link(bindings);
for (double j = lower_bound.numeric_value(), T = upper_bound.numeric_value() + ((for_type == Node::for_to_directive) ? 0 : 1);
j < T;
j += 1) {
for_env.current_frame[iter_var.token()] = new_Node(lower_bound.path(), lower_bound.line(), j);
Node v(eval_function(name, for_body, for_env, new_Node, ctx));
if (v.is_null()) continue;
else return v;
}
} break;
case Node::each_directive: {
Node iter_var(stm[0]);
Node list(eval(stm[1], Node(), bindings, ctx.function_env, new_Node, ctx));
if (list.type() != Node::list) {
list = (new_Node(Node::list, list.path(), list.line(), 1) << list);
}
Node each_body(stm[2]);
Environment each_env; // re-use this env for each iteration
each_env.link(bindings);
for (size_t j = 0, T = list.size(); j < T; ++j) {
list[j].should_eval() = true;
each_env.current_frame[iter_var.token()] = eval(list[j], Node(), bindings, ctx.function_env, new_Node, ctx);
Node v(eval_function(name, each_body, each_env, new_Node, ctx));
if (v.is_null()) continue;
else return v;
}
} break;
case Node::while_directive: {
Node pred_expr(stm[0]);
Node while_body(stm[1]);
Environment while_env; // re-use this env for each iteration
while_env.link(bindings);
Node pred_val(eval(pred_expr, Node(), bindings, ctx.function_env, new_Node, ctx));
while (!pred_val.is_false()) {
Node v(eval_function(name, while_body, while_env, new_Node, ctx));
if (v.is_null()) {
pred_val = eval(pred_expr, Node(), bindings, ctx.function_env, new_Node, ctx);
continue;
}
else return v;
}
} break;
case Node::warning: {
string prefix("WARNING: ");
string indent(" ");
Node contents(eval(stm[0], Node(), bindings, ctx.function_env, new_Node, ctx));
string result(contents.to_string());
if (contents.type() == Node::string_constant || contents.type() == Node::string_schema) {
result = result.substr(1, result.size()-2); // unquote if it's a single string
}
// These cerrs aren't log lines! They're supposed to be here!
cerr << prefix << result << endl;
cerr << indent << "on line " << stm.line() << " of " << stm.path();
cerr << endl << endl;
} break;
case Node::return_directive: {
Node retval(eval(stm[0], Node(), bindings, ctx.function_env, new_Node, ctx));
if (retval.type() == Node::list) {
Node new_list(new_Node(Node::list, retval.path(), retval.line(), retval.size()));
new_list.is_comma_separated() = retval.is_comma_separated();
for (size_t i = 0, S = retval.size(); i < S; ++i) {
new_list << eval(retval[i], Node(), bindings, ctx.function_env, new_Node, ctx);
}
retval = new_list;
}
return retval;
} break;
default: {
} break;
}
}
if (at_toplevel) throw_eval_error("function finished without @return", body.path(), body.line());
return Node();
}
// Expand a selector with respect to its prefix/context. Two separate cases:
// when the selector has backrefs, substitute the prefix for each occurrence
// of a backref. When the selector doesn't have backrefs, just prepend the
// prefix. This function needs multiple subsidiary cases in order to properly
// combine the various kinds of selectors.
Node expand_selector(Node sel, Node pre, Node_Factory& new_Node)
{
if (pre.is_null()) return sel;
if (sel.has_backref()) {
if ((pre.type() == Node::selector_group) && (sel.type() == Node::selector_group)) {
Node group(new_Node(Node::selector_group, sel.path(), sel.line(), pre.size() * sel.size()));
for (size_t i = 0, S = pre.size(); i < S; ++i) {
for (size_t j = 0, T = sel.size(); j < T; ++j) {
group << expand_backref(new_Node(sel[j]), pre[i]);
}
}
return group;
}
else if ((pre.type() == Node::selector_group) && (sel.type() != Node::selector_group)) {
Node group(new_Node(Node::selector_group, sel.path(), sel.line(), pre.size()));
for (size_t i = 0, S = pre.size(); i < S; ++i) {
group << expand_backref(new_Node(sel), pre[i]);
}
return group;
}
else if ((pre.type() != Node::selector_group) && (sel.type() == Node::selector_group)) {
Node group(new_Node(Node::selector_group, sel.path(), sel.line(), sel.size()));
for (size_t i = 0, S = sel.size(); i < S; ++i) {
group << expand_backref(new_Node(sel[i]), pre);
}
return group;
}
else {
return expand_backref(new_Node(sel), pre);
}
}
if ((pre.type() == Node::selector_group) && (sel.type() == Node::selector_group)) {
Node group(new_Node(Node::selector_group, sel.path(), sel.line(), pre.size() * sel.size()));
for (size_t i = 0, S = pre.size(); i < S; ++i) {
for (size_t j = 0, T = sel.size(); j < T; ++j) {
Node new_sel(new_Node(Node::selector, sel.path(), sel.line(), 2));
if (pre[i].type() == Node::selector) new_sel += pre[i];
else new_sel << pre[i];
if (sel[j].type() == Node::selector) new_sel += sel[j];
else new_sel << sel[j];
group << new_sel;
}
}
return group;
}
else if ((pre.type() == Node::selector_group) && (sel.type() != Node::selector_group)) {
Node group(new_Node(Node::selector_group, sel.path(), sel.line(), pre.size()));
for (size_t i = 0, S = pre.size(); i < S; ++i) {
Node new_sel(new_Node(Node::selector, sel.path(), sel.line(), 2));
if (pre[i].type() == Node::selector) new_sel += pre[i];
else new_sel << pre[i];
if (sel.type() == Node::selector) new_sel += sel;
else new_sel << sel;
group << new_sel;
}
return group;
}
else if ((pre.type() != Node::selector_group) && (sel.type() == Node::selector_group)) {
Node group(new_Node(Node::selector_group, sel.path(), sel.line(), sel.size()));
for (size_t i = 0, S = sel.size(); i < S; ++i) {
Node new_sel(new_Node(Node::selector, sel.path(), sel.line(), 2));
if (pre.type() == Node::selector) new_sel += pre;
else new_sel << pre;
if (sel[i].type() == Node::selector) new_sel += sel[i];
else new_sel << sel[i];
group << new_sel;
}
return group;
}
else {
Node new_sel(new_Node(Node::selector, sel.path(), sel.line(), 2));
if (pre.type() == Node::selector) new_sel += pre;
else new_sel << pre;
if (sel.type() == Node::selector) new_sel += sel;
else new_sel << sel;
return new_sel;
}
// unreachable statement
return Node();
}
// Helper for expanding selectors with backrefs.
Node expand_backref(Node sel, Node pre)
{
switch (sel.type())
{
case Node::backref: {
return pre;
} break;
case Node::simple_selector_sequence:
case Node::selector: {
for (size_t i = 0, S = sel.size(); i < S; ++i) {
sel[i] = expand_backref(sel[i], pre);
}
return sel;
} break;
default: {
return sel;
} break;
}
// unreachable statement
return Node();
}
// Resolve selector extensions. Walk through the document tree and check each
// selector to see whether it's the base of an extension. Needs to be a
// separate pass after evaluation because extension requests may be located
// within mixins, and their targets may be interpolated.
void extend(Node expr, multimap<Node, Node>& extension_requests, Node_Factory& new_Node)
{
switch (expr.type())
{
case Node::ruleset: {
if (!expr[2].has_been_extended()) {
// check single selector
if (expr[2].type() != Node::selector_group) {
Node sel(selector_base(expr[2]));
// if this selector has extenders ...
size_t num_requests = extension_requests.count(sel);
if (num_requests) {
Node group(new_Node(Node::selector_group, sel.path(), sel.line(), 1 + num_requests));
group << expr[2];
// for each of its extenders ...
for (multimap<Node, Node>::iterator request = extension_requests.lower_bound(sel);
request != extension_requests.upper_bound(sel);
++request) {
Node ext(generate_extension(expr[2], request->second, new_Node));
if (ext.type() == Node::selector_group) group += ext;
else group << ext;
}
group = remove_duplicate_selectors(group, new_Node);
group.has_been_extended() = true;
expr[2] = group;
}
}
// individually check each selector in a group
else {
Node group(expr[2]);
Node new_group(new_Node(Node::selector_group, group.path(), group.line(), group.size()));
// for each selector in the group ...
for (size_t i = 0, S = group.size(); i < S; ++i) {
new_group << group[i];
Node sel(selector_base(group[i]));
// if it has extenders ...
if (!group[i].has_been_extended() && extension_requests.count(sel)) {
// for each of its extenders ...
for (multimap<Node, Node>::iterator request = extension_requests.lower_bound(sel);
request != extension_requests.upper_bound(sel);
++request) {
Node ext(generate_extension(group[i], request->second, new_Node));
if (ext.type() == Node::selector_group) new_group += ext;
else new_group << ext;
}
group[i].has_been_extended() = true;
}
}
if (new_group.size() > 0) {
group.has_been_extended() = true;
new_group = remove_duplicate_selectors(new_group, new_Node);
new_group.has_been_extended() = true;
expr[2] = new_group;
}
}
}
extend(expr[1], extension_requests, new_Node);
} break;
case Node::root:
case Node::block:
case Node::mixin_call:
case Node::if_directive:
case Node::for_through_directive:
case Node::for_to_directive:
case Node::each_directive:
case Node::while_directive: {
// at this point, all directives have been expanded into style blocks,
// so just recursively process their children
for (size_t i = 0, S = expr.size(); i < S; ++i) {
extend(expr[i], extension_requests, new_Node);
}
} break;
default: {
// do nothing
} break;
}
return;
}
void extend_selectors(vector<pair<Node, Node> >& pending, multimap<Node, Node>& extension_table, Node_Factory& new_Node)
{
for (size_t i = 0, S = pending.size(); i < S; ++i) {
// Node extender(pending[i].second[2]);
// Node original_extender(pending[i].second[0]);
Node ruleset_to_extend(pending[i].first);
Node extendee(ruleset_to_extend[2]);
if (extendee.type() != Node::selector_group && !extendee.has_been_extended()) {
Node extendee_base(selector_base(extendee));
Node extender_group(new_Node(Node::selector_group, extendee.path(), extendee.line(), 1));
for (multimap<Node, Node>::iterator i = extension_table.lower_bound(extendee_base), E = extension_table.upper_bound(extendee_base);
i != E;
++i) {
if (i->second.size() <= 2) continue; // TODO: UN-HACKIFY THIS
if (i->second[2].type() == Node::selector_group)
extender_group += i->second[2];
else
extender_group << i->second[2];
}
Node extended_group(new_Node(Node::selector_group, extendee.path(), extendee.line(), extender_group.size() + 1));
extendee.has_been_extended() = true;
extended_group << extendee;
for (size_t i = 0, S = extender_group.size(); i < S; ++i) {
extended_group << generate_extension(extendee, extender_group[i], new_Node);
}
ruleset_to_extend[2] = extended_group;
}
else {
Node extended_group(new_Node(Node::selector_group, extendee.path(), extendee.line(), extendee.size() + 1));
for (size_t i = 0, S = extendee.size(); i < S; ++i) {
Node extendee_i(extendee[i]);
Node extendee_i_base(selector_base(extendee_i));
extended_group << extendee_i;
if (!extendee_i.has_been_extended() && extension_table.count(extendee_i_base)) {
Node extender_group(new_Node(Node::selector_group, extendee.path(), extendee.line(), 1));
for (multimap<Node, Node>::iterator i = extension_table.lower_bound(extendee_i_base), E = extension_table.upper_bound(extendee_i_base);
i != E;
++i) {
if (i->second.size() <= 2) continue; // TODO: UN-HACKIFY THIS
if (i->second[2].type() == Node::selector_group)
extender_group += i->second[2];
else
extender_group << i->second[2];
}
for (size_t j = 0, S = extender_group.size(); j < S; ++j) {
extended_group << generate_extension(extendee_i, extender_group[j], new_Node);
}
extendee_i.has_been_extended() = true;
}
}
ruleset_to_extend[2] = extended_group;
}
}
}
// Helper for generating selector extensions; called for each extendee and
// extender in a pair of selector groups.
Node generate_extension(Node extendee, Node extender, Node_Factory& new_Node)
{
Node new_group(new_Node(Node::selector_group, extendee.path(), extendee.line(), 1));
if (extendee.type() != Node::selector) {
switch (extender.type())
{
case Node::simple_selector:
case Node::attribute_selector:
case Node::simple_selector_sequence:
case Node::selector: {
new_group << extender;
return new_group;
} break;
default: {
// not sure why selectors sometimes get wrapped in a singleton group
return generate_extension(extendee, extender[0], new_Node);
} break;
}
}
else {
switch (extender.type())
{
case Node::simple_selector:
case Node::attribute_selector:
case Node::simple_selector_sequence: {
Node new_ext(new_Node(Node::selector, extendee.path(), extendee.line(), extendee.size()));
for (size_t i = 0, S = extendee.size() - 1; i < S; ++i) {
new_ext << extendee[i];
}
new_ext << extender;
new_group << new_ext;
return new_group;
} break;
case Node::selector: {
Node new_ext1(new_Node(Node::selector, extendee.path(), extendee.line(), extendee.size() + extender.size() - 1));
Node new_ext2(new_Node(Node::selector, extendee.path(), extendee.line(), extendee.size() + extender.size() - 1));
new_ext1 += selector_prefix(extendee, new_Node);
new_ext1 += extender;
new_ext2 += selector_prefix(extender, new_Node);
new_ext2 += selector_prefix(extendee, new_Node);
new_ext2 << extender.back();
new_group << new_ext1 << new_ext2;
return new_group;
} break;
default: {
// something
} break;
}
}
return Node();
}
// Helpers for extracting subsets of selectors
Node selector_prefix(Node sel, Node_Factory& new_Node)
{
switch (sel.type())
{
case Node::selector: {
Node pre(new_Node(Node::selector, sel.path(), sel.line(), sel.size() - 1));
for (size_t i = 0, S = sel.size() - 1; i < S; ++i) {
pre << sel[i];
}
return pre;
} break;
default: {
return new_Node(Node::selector, sel.path(), sel.line(), 0);
} break;
}
}
Node selector_base(Node sel)
{
switch (sel.type())
{
case Node::selector: {
return sel.back();
} break;
default: {
return sel;
} break;
}
}
static Node selector_but(Node sel, Node_Factory& new_Node, size_t start, size_t from_end)
{
switch (sel.type())
{
case Node::selector: {
Node bf(new_Node(Node::selector, sel.path(), sel.line(), sel.size() - 1));
for (size_t i = start, S = sel.size() - from_end; i < S; ++i) {
bf << sel[i];
}
return bf;
} break;
default: {
return new_Node(Node::selector, sel.path(), sel.line(), 0);
} break;
}
}
Node selector_butfirst(Node sel, Node_Factory& new_Node)
{ return selector_but(sel, new_Node, 1, 0); }
Node selector_butlast(Node sel, Node_Factory& new_Node)
{ return selector_but(sel, new_Node, 0, 1); }
void to_lowercase(string& s)
{ for (size_t i = 0, L = s.length(); i < L; ++i) s[i] = tolower(s[i]); }
}
#define SASS_EVAL_APPLY
#include <map>
#ifndef SASS_NODE
#include "node.hpp"
#endif
#ifndef SASS_CONTEXT
#include "context.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, bool function_name = false);
Node eval(Node expr, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool function_name = false);
Node eval_arguments(Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx);
Node eval_function(string name, Node stm, Environment& bindings, Node_Factory& new_Node, Context& ctx, bool toplevel = false);
Node reduce(Node list, size_t head, Node acc, Node_Factory& new_Node);
Node accumulate(Node::Type op, Node acc, Node rhs, Node_Factory& new_Node);
double operate(Node op, double lhs, double rhs);
Node apply_mixin(Node mixin, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, bool dynamic_scope = false);
Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, string& path, size_t line);
Node 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")
#include <iostream>
#include <sstream>
#include <cmath>
#include <algorithm>
#include "functions.hpp"
#include "constants.hpp"
#include "node_factory.hpp"
#include "context.hpp"
#include "document.hpp"
#include "eval_apply.hpp"
#include "error.hpp"
#ifndef SASS_PRELEXER
#include "prelexer.hpp"
#endif
using std::cerr; using std::endl; using std::stringstream;
namespace Sass {
using namespace Constants;
// this constructor needs context.hpp, so it can't be defined in functions.hpp
// because including context.hpp in functions.hpp would be circular
Function::Function(char* signature, Primitive ip, Context& ctx)
: definition(Node()),
primitive(ip),
overloaded(false)
{
Document sig_doc(Document::make_from_source_chars(ctx, signature));
sig_doc.lex<Prelexer::identifier>();
name = sig_doc.lexed.to_string();
parameters = sig_doc.parse_parameters();
parameter_names = ctx.new_Node(Node::parameters, "[PRIMITIVE FUNCTIONS]", 0, parameters.size());
for (size_t i = 0, S = parameters.size(); i < S; ++i) {
Node param(parameters[i]);
if (param.type() == Node::variable) {
parameter_names << param;
}
else {
parameter_names << param[0];
// assume it's safe to evaluate default args just once at initialization
param[1] = eval(param[1], Node(), ctx.global_env, ctx.function_env, ctx.new_Node, ctx);
}
}
}
namespace Functions {
static void throw_eval_error(string message, string& path, size_t line)
{
if (!path.empty() && Prelexer::string_constant(path.c_str()))
path = path.substr(1, path.length() - 1);
throw Error(Error::evaluation, path, line, message);
}
static const char* nameof(Node::Type t) {
switch (t)
{
case Node::numeric: {
return numeric_name;
} break;
case Node::number: {
return number_name;
} break;
case Node::numeric_percentage: {
return percentage_name;
} break;
case Node::numeric_dimension: {
return dimension_name;
} break;
case Node::string_t:
case Node::identifier:
case Node::value_schema:
case Node::identifier_schema:
case Node::string_constant:
case Node::string_schema:
case Node::concatenation: {
return string_name;
} break;
case Node::boolean: {
return bool_name;
} break;
case Node::numeric_color: {
return color_name;
} break;
case Node::list: {
return list_name;
} break;
default: {
return empty_str;
} break;
}
// unreachable statement
return empty_str;
}
// Functions for fetching and checking arguments.
static Node arg(Signature sig, string& path, size_t line, const Node parameter_names, Environment& bindings, size_t param_num, Node::Type param_type) {
Node the_arg(bindings[parameter_names[param_num].token()]);
Node::Type arg_type = the_arg.type();
switch (param_type)
{
case Node::any: {
return the_arg;
} break;
case Node::numeric: {
if (the_arg.is_numeric()) return the_arg;
} break;
case Node::string_t: {
switch (arg_type)
{
case Node::identifier:
case Node::value_schema:
case Node::identifier_schema:
case Node::string_constant:
case Node::string_schema:
case Node::concatenation: return the_arg;
default: break;
} break;
} break;
default: {
if (arg_type == param_type) return the_arg;
} break;
}
stringstream msg;
msg << nameof(param_type) << " required for argument " << param_num+1 << " in call to '" << sig << "'";
throw_eval_error(msg.str(), path, line);
// unreachable statement
return Node();
}
static Node arg(Signature sig, string& path, size_t line, const Node parameter_names, Environment& bindings, size_t param_num, Node::Type t, double low, double high) {
Node the_arg(arg(sig, path, line, parameter_names, bindings, param_num, t));
if (!the_arg.is_numeric()) {
stringstream msg;
msg << "numeric value required for argument " << param_num+1 << " in call to '" << sig << "'";
throw_eval_error(msg.str(), path, line);
}
double val = the_arg.numeric_value();
if (val < low || high < val) {
stringstream msg;
msg << "argument " << param_num+1 << " must be between " << low << " and " << high << " in call to '" << sig << "'";
throw_eval_error(msg.str(), path, line);
}
return the_arg;
}
////////////////////////////////////////////////////////////////////////
// RGB Functions ///////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
extern Signature rgb_sig = "rgb($red, $green, $blue)";
Node rgb(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
double r = arg(rgb_sig, path, line, parameter_names, bindings, 0, Node::numeric, 0, 255).numeric_value();
double g = arg(rgb_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 255).numeric_value();
double b = arg(rgb_sig, path, line, parameter_names, bindings, 2, Node::numeric, 0, 255).numeric_value();
return new_Node(path, line, std::floor(r), std::floor(g), std::floor(b), 1.0);
}
extern Signature rgba_4_sig = "rgba($red, $green, $blue, $alpha)";
Node rgba_4(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
double r = arg(rgba_4_sig, path, line, parameter_names, bindings, 0, Node::numeric, 0, 255).numeric_value();
double g = arg(rgba_4_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 255).numeric_value();
double b = arg(rgba_4_sig, path, line, parameter_names, bindings, 2, Node::numeric, 0, 255).numeric_value();
double a = arg(rgba_4_sig, path, line, parameter_names, bindings, 3, Node::numeric, 0, 1).numeric_value();
return new_Node(path, line, std::floor(r), std::floor(g), std::floor(b), a);
}
extern Signature rgba_2_sig = "rgba($color, $alpha)";
Node rgba_2(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color_arg(arg(rgba_2_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node alpha_arg(arg(rgba_2_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 1));
double r = color_arg[0].numeric_value();
double g = color_arg[1].numeric_value();
double b = color_arg[2].numeric_value();
double a = alpha_arg.numeric_value();
return new_Node(path, line, r, g, b, a);
}
extern Signature red_sig = "red($color)";
Node red(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(red_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
return new_Node(path, line, color[0]);
}
extern Signature green_sig = "green($color)";
Node green(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(green_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
return new_Node(path, line, color[1]);
}
extern Signature blue_sig = "blue($color)";
Node blue(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(blue_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
return new_Node(path, line, color[2]);
}
extern Signature mix_sig = "mix($color-1, $color-2, $weight: 50%)";
Node mix(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color1(arg(mix_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node color2(arg(mix_sig, path, line, parameter_names, bindings, 1, Node::numeric_color));
Node weight(arg(mix_sig, path, line, parameter_names, bindings, 2, Node::numeric, 0, 100));
double p = weight.numeric_value()/100;
double w = 2*p - 1;
double a = color1[3].numeric_value() - color2[3].numeric_value();
double w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0;
double w2 = 1 - w1;
Node mixed(new_Node(Node::numeric_color, path, line, 4));
for (int i = 0; i < 3; ++i) {
mixed << new_Node(path, line, std::floor(w1*color1[i].numeric_value() + w2*color2[i].numeric_value()));
}
double alpha = color1[3].numeric_value()*p + color2[3].numeric_value()*(1-p);
mixed << new_Node(path, line, alpha);
return mixed;
}
////////////////////////////////////////////////////////////////////////
// HSL Functions ///////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// RGB to HSL helper function so we can do hsl operations.
// (taken from http://www.easyrgb.com)
Node rgb_to_hsl(double r, double g, double b, Node_Factory& new_Node, string& path, size_t line) {
r /= 255.0; g /= 255.0; b /= 255.0;
double max = std::max(r, std::max(g, b));
double min = std::min(r, std::min(g, b));
double del = max - min;
double h = 0, s = 0, l = (max + min)/2;
if (max == min) {
h = s = 0; // achromatic
}
else {
if (l < 0.5) s = del / (max + min);
else s = del / (2.0 - max - min);
double dr = (((max - r)/6.0) + (del/2.0))/del;
double dg = (((max - g)/6.0) + (del/2.0))/del;
double db = (((max - b)/6.0) + (del/2.0))/del;
if (r == max) h = db - dg;
else if (g == max) h = (1.0/3.0) + dr - db;
else if (b == max) h = (2.0/3.0) + dg - dr;
if (h < 0) h += 1;
else if (h > 1) h -= 1;
}
return new_Node(path, line, static_cast<int>(h*360)%360, s*100, l*100);
}
// Hue to RGB helper function
double h_to_rgb(double m1, double m2, double h) {
if (h < 0) h += 1;
if (h > 1) h -= 1;
if (h*6.0 < 1) return m1 + (m2 - m1)*h*6;
if (h*2.0 < 1) return m2;
if (h*3.0 < 2) return m1 + (m2 - m1) * (2.0/3.0 - h)*6;
return m1;
}
Node hsla_impl(double h, double s, double l, double a, Node_Factory& new_Node, string& path, size_t line) {
h = static_cast<double>(((static_cast<int>(h) % 360) + 360) % 360) / 360.0;
s = (s < 0) ? 0 :
(s > 100) ? 100 :
s;
l = (l < 0) ? 0 :
(l > 100) ? 100 :
l;
s /= 100.0;
l /= 100.0;
double m2;
if (l <= 0.5) m2 = l*(s+1.0);
else m2 = l+s-l*s;
double m1 = l*2-m2;
// round the results -- consider moving this into the Node constructors
double r = std::floor(h_to_rgb(m1, m2, h+1.0/3.0) * 255.0 + 0.5);
double g = std::floor(h_to_rgb(m1, m2, h) * 255.0 + 0.5);
double b = std::floor(h_to_rgb(m1, m2, h-1.0/3.0) * 255.0 + 0.5);
return new_Node(path, line, r, g, b, a);
}
extern Signature hsl_sig = "hsl($hue, $saturation, $lightness)";
Node hsl(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
double h = arg(hsl_sig, path, line, parameter_names, bindings, 0, Node::numeric).numeric_value();
double s = arg(hsl_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 100).numeric_value();
double l = arg(hsl_sig, path, line, parameter_names, bindings, 2, Node::numeric, 0, 100).numeric_value();
return hsla_impl(h, s, l, 1.0, new_Node, path, line);
}
extern Signature hsla_sig = "hsla($hue, $saturation, $lightness, $alpha)";
Node hsla(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
double h = arg(hsla_sig, path, line, parameter_names, bindings, 0, Node::numeric).numeric_value();
double s = arg(hsla_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 100).numeric_value();
double l = arg(hsla_sig, path, line, parameter_names, bindings, 2, Node::numeric, 0, 100).numeric_value();
double a = arg(hsla_sig, path, line, parameter_names, bindings, 3, Node::numeric, 0, 1).numeric_value();
return hsla_impl(h, s, l, a, new_Node, path, line);
}
extern Signature hue_sig = "hue($color)";
Node hue(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node rgb_color(arg(hue_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node hsl_color(rgb_to_hsl(rgb_color[0].numeric_value(),
rgb_color[1].numeric_value(),
rgb_color[2].numeric_value(),
new_Node, path, line));
return new_Node(path, line, hsl_color[0].numeric_value(), Token::make(deg_kwd));
}
extern Signature saturation_sig = "saturation($color)";
Node saturation(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node rgb_color(arg(saturation_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node hsl_color(rgb_to_hsl(rgb_color[0].numeric_value(),
rgb_color[1].numeric_value(),
rgb_color[2].numeric_value(),
new_Node, path, line));
return new_Node(path, line, hsl_color[1].numeric_value(), Token::make(percent_str));
}
extern Signature lightness_sig = "lightness($color)";
Node lightness(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node rgb_color(arg(lightness_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node hsl_color(rgb_to_hsl(rgb_color[0].numeric_value(),
rgb_color[1].numeric_value(),
rgb_color[2].numeric_value(),
new_Node, path, line));
return new_Node(path, line, hsl_color[2].numeric_value(), Token::make(percent_str));
}
extern Signature adjust_hue_sig = "adjust-hue($color, $degrees)";
Node adjust_hue(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node rgb_col(arg(adjust_hue_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node degrees(arg(adjust_hue_sig, path, line, parameter_names, bindings, 1, Node::numeric));
Node hsl_col(rgb_to_hsl(rgb_col[0].numeric_value(),
rgb_col[1].numeric_value(),
rgb_col[2].numeric_value(),
new_Node, path, line));
return hsla_impl(hsl_col[0].numeric_value() + degrees.numeric_value(),
hsl_col[1].numeric_value(),
hsl_col[2].numeric_value(),
rgb_col[3].numeric_value(),
new_Node, path, line);
}
extern Signature lighten_sig = "lighten($color, $amount)";
Node lighten(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node rgb_col(arg(lighten_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node amount(arg(lighten_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 100));
Node hsl_col(rgb_to_hsl(rgb_col[0].numeric_value(),
rgb_col[1].numeric_value(),
rgb_col[2].numeric_value(),
new_Node, path, line));
return hsla_impl(hsl_col[0].numeric_value(),
hsl_col[1].numeric_value(),
hsl_col[2].numeric_value() + amount.numeric_value(),
rgb_col[3].numeric_value(),
new_Node, path, line);
}
extern Signature darken_sig = "darken($color, $amount)";
Node darken(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node rgb_col(arg(darken_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node amount(arg(darken_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 100));
Node hsl_col(rgb_to_hsl(rgb_col[0].numeric_value(),
rgb_col[1].numeric_value(),
rgb_col[2].numeric_value(),
new_Node, path, line));
return hsla_impl(hsl_col[0].numeric_value(),
hsl_col[1].numeric_value(),
hsl_col[2].numeric_value() - amount.numeric_value(),
rgb_col[3].numeric_value(),
new_Node, path, line);
}
extern Signature saturate_sig = "saturate($color, $amount)";
Node saturate(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node rgb_col(arg(saturate_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node amount(arg(saturate_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 100));
Node hsl_col(rgb_to_hsl(rgb_col[0].numeric_value(),
rgb_col[1].numeric_value(),
rgb_col[2].numeric_value(),
new_Node, path, line));
return hsla_impl(hsl_col[0].numeric_value(),
hsl_col[1].numeric_value() + amount.numeric_value(),
hsl_col[2].numeric_value(),
rgb_col[3].numeric_value(),
new_Node, path, line);
}
extern Signature desaturate_sig = "desaturate($color, $amount)";
Node desaturate(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node rgb_col(arg(desaturate_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node amount(arg(desaturate_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 100));
Node hsl_col(rgb_to_hsl(rgb_col[0].numeric_value(),
rgb_col[1].numeric_value(),
rgb_col[2].numeric_value(),
new_Node, path, line));
return hsla_impl(hsl_col[0].numeric_value(),
hsl_col[1].numeric_value() - amount.numeric_value(),
hsl_col[2].numeric_value(),
rgb_col[3].numeric_value(),
new_Node, path, line);
}
extern Signature grayscale_sig = "grayscale($color)";
Node grayscale(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(grayscale_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node hsl_color(rgb_to_hsl(color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
new_Node, path, line));
return hsla_impl(hsl_color[0].numeric_value(),
0.0, // desaturate completely
hsl_color[2].numeric_value(),
color[3].numeric_value(),
new_Node, path, line);
}
extern Signature complement_sig = "complement($color)";
Node complement(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(complement_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
Node hsl_color(rgb_to_hsl(color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
new_Node, path, line));
return hsla_impl(hsl_color[0].numeric_value() - 180, // other side of the color wheel
hsl_color[1].numeric_value(),
hsl_color[2].numeric_value(),
color[3].numeric_value(),
new_Node, path, line);
}
extern Signature invert_sig = "invert($color)";
Node invert(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(invert_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
return new_Node(path, line,
255 - color[0].numeric_value(),
255 - color[1].numeric_value(),
255 - color[2].numeric_value(),
color[3].numeric_value());
}
////////////////////////////////////////////////////////////////////////
// Opacity Functions ///////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
extern Signature alpha_sig = "alpha($color)";
Node alpha(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(alpha_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
return new_Node(path, line, color[3]);
}
extern Signature opacity_sig = "opacity($color)";
Node opacity(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(opacity_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
return new_Node(path, line, color[3]);
}
extern Signature opacify_sig = "opacify($color, $amount)";
Node opacify(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(opacify_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
double delta = arg(opacify_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 1).numeric_value();
delta += color[3].numeric_value();
if (delta > 1) delta = 1;
return new_Node(path, line,
color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
delta);
}
extern Signature fade_in_sig = "fade-in($color, $amount)";
Node fade_in(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(fade_in_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
double delta = arg(fade_in_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 1).numeric_value();
delta += color[3].numeric_value();
if (delta > 1) delta = 1;
return new_Node(path, line,
color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
delta);
}
extern Signature transparentize_sig = "transparentize($color, $amount)";
Node transparentize(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(transparentize_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
double delta = arg(transparentize_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 1).numeric_value();
double alpha = color[3].numeric_value() - delta;
if (alpha < 0) alpha = 0;
return new_Node(path, line,
color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
alpha);
}
extern Signature fade_out_sig = "fade-out($color, $amount)";
Node fade_out(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(arg(fade_out_sig, path, line, parameter_names, bindings, 0, Node::numeric_color));
double delta = arg(fade_out_sig, path, line, parameter_names, bindings, 1, Node::numeric, 0, 1).numeric_value();
double alpha = color[3].numeric_value() - delta;
if (alpha < 0) alpha = 0;
return new_Node(path, line,
color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
alpha);
}
////////////////////////////////////////////////////////////////////////
// Other Color Functions ///////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// not worth using the arg(...) functions
extern Signature adjust_color_sig = "adjust-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)";
Node adjust_color(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(bindings[parameter_names[0].token()]);
Node r(bindings[parameter_names[1].token()]);
Node g(bindings[parameter_names[2].token()]);
Node b(bindings[parameter_names[3].token()]);
Node h(bindings[parameter_names[4].token()]);
Node s(bindings[parameter_names[5].token()]);
Node l(bindings[parameter_names[6].token()]);
Node a(bindings[parameter_names[7].token()]);
bool no_rgb = r.is_false() && g.is_false() && b.is_false();
bool no_hsl = h.is_false() && s.is_false() && l.is_false();
if (color.type() != Node::numeric_color) {
throw_eval_error("first argument to 'adjust-color' must be a color", color.path(), color.line());
}
else if (!no_rgb && !no_hsl) {
throw_eval_error("cannot specify RGB and HSL values for a color at the same time for 'adjust-color'", r.path(), r.line());
}
else if (!no_rgb) {
if (!r.is_false() && !r.is_numeric()) throw_eval_error("argument $red of 'adjust-color' must be numeric", r.path(), r.line());
if (!g.is_false() && !g.is_numeric()) throw_eval_error("argument $green of 'adjust-color' must be numeric", g.path(), g.line());
if (!b.is_false() && !b.is_numeric()) throw_eval_error("argument $blue of 'adjust-color' must be numeric", b.path(), b.line());
if (!a.is_false() && !a.is_numeric()) throw_eval_error("argument $alpha of 'adjust-color' must be numeric", a.path(), a.line());
double new_r = color[0].numeric_value() + (r.is_false() ? 0 : r.numeric_value());
double new_g = color[1].numeric_value() + (g.is_false() ? 0 : g.numeric_value());
double new_b = color[2].numeric_value() + (b.is_false() ? 0 : b.numeric_value());
double new_a = color[3].numeric_value() + (a.is_false() ? 0 : a.numeric_value());
return new_Node(path, line, new_r, new_g, new_b, new_a);
}
else if (!no_hsl) {
Node hsl_node(rgb_to_hsl(color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
new_Node, path, line));
if (!h.is_false() && !h.is_numeric()) throw_eval_error("argument $hue of 'adjust-color' must be numeric", h.path(), h.line());
if (!s.is_false() && !s.is_numeric()) throw_eval_error("argument $saturation of 'adjust-color' must be numeric", s.path(), s.line());
if (!l.is_false() && !l.is_numeric()) throw_eval_error("argument $lightness of 'adjust-color' must be numeric", l.path(), l.line());
if (!a.is_false() && !a.is_numeric()) throw_eval_error("argument $alpha of 'adjust-color' must be numeric", a.path(), a.line());
double new_h = (h.is_false() ? 0 : h.numeric_value()) + hsl_node[0].numeric_value();
double new_s = (s.is_false() ? 0 : s.numeric_value()) + hsl_node[1].numeric_value();
double new_l = (l.is_false() ? 0 : l.numeric_value()) + hsl_node[2].numeric_value();
double new_a = (a.is_false() ? 0 : a.numeric_value()) + color[3].numeric_value();
return hsla_impl(new_h, new_s, new_l, new_a, new_Node, path, line);
}
else if (!a.is_false()) {
if (!a.is_numeric()) throw_eval_error("argument $alpha of 'adjust-color' must be numeric", a.path(), a.line());
return new_Node(path, line,
color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
color[3].numeric_value() + a.numeric_value());
}
else {
throw_eval_error("not enough arguments for 'adjust-color'", color.path(), color.line());
}
// unreachable statement
return Node();
}
extern Signature scale_color_sig = "scale-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)";
Node scale_color(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(bindings[parameter_names[0].token()]);
Node r(bindings[parameter_names[1].token()]);
Node g(bindings[parameter_names[2].token()]);
Node b(bindings[parameter_names[3].token()]);
Node h(bindings[parameter_names[4].token()]);
Node s(bindings[parameter_names[5].token()]);
Node l(bindings[parameter_names[6].token()]);
Node a(bindings[parameter_names[7].token()]);
bool no_rgb = r.is_false() && g.is_false() && b.is_false();
bool no_hsl = h.is_false() && s.is_false() && l.is_false();
size_t low, high;
bool is_hsl = false;
if (color.type() != Node::numeric_color) {
throw_eval_error("first argument to 'scale-color' must be a color", path, line);
}
if (!no_rgb && !no_hsl) {
throw_eval_error("cannot specify RGB and HSL values for a color at the same time for 'scale-color'", path, line);
}
else if (!no_rgb) {
low = 1; high = 4;
}
else if (!no_hsl) {
is_hsl = true;
low = 4; high = 7;
Node alpha(color[3]);
color = rgb_to_hsl(color[0].numeric_value(), color[1].numeric_value(), color[2].numeric_value(), new_Node, path, line);
color << alpha;
}
else if (!a.is_false()) {
Node result(new_Node(Node::numeric_color, path, line, 4));
for (size_t i = 0; i < 3; ++i) {
result << new_Node(path, line, color[i].numeric_value());
}
double current = color[3].numeric_value();
double scale = arg(scale_color_sig, path, line, parameter_names, bindings, 7, Node::numeric_percentage, -100, 100).numeric_value() / 100;
double diff = scale > 0 ? 1 - current : current;
result << new_Node(path, line, current + diff*scale);
return result;
}
else {
throw_eval_error("not enough arguments for 'scale-color'", color.path(), color.line());
}
Node result(new_Node(Node::numeric_color, path, line, 4));
for (size_t i = low, j = 0; i < high; ++i, ++j) {
double current = color[j].numeric_value();
if (!bindings[parameter_names[i].token()].is_false()) {
double scale = arg(scale_color_sig, path, line, parameter_names, bindings, i, Node::numeric_percentage, -100, 100).numeric_value() / 100;
double diff = scale > 0 ? (is_hsl ? 100 : 255) - current : current;
result << new_Node(path, line, current + diff*scale);
}
else {
result << new_Node(path, line, current);
}
}
if (!a.is_false()) {
double current = color[3].numeric_value();
double scale = arg(scale_color_sig, path, line, parameter_names, bindings, 7, Node::numeric_percentage, -100, 100).numeric_value() / 100;
double diff = scale > 0 ? 1 - current : current;
result << new_Node(path, line, current + diff*scale);
}
else {
result << new_Node(path, line, color[3].numeric_value());
}
if (is_hsl) {
result = hsla_impl(result[0].numeric_value(),
result[1].numeric_value(),
result[2].numeric_value(),
result[3].numeric_value(),
new_Node, path, line);
}
return result;
}
extern Signature change_color_sig = "change-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)";
Node change_color(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node color(bindings[parameter_names[0].token()]);
Node r(bindings[parameter_names[1].token()]);
Node g(bindings[parameter_names[2].token()]);
Node b(bindings[parameter_names[3].token()]);
Node h(bindings[parameter_names[4].token()]);
Node s(bindings[parameter_names[5].token()]);
Node l(bindings[parameter_names[6].token()]);
Node a(bindings[parameter_names[7].token()]);
bool no_rgb = r.is_false() && g.is_false() && b.is_false();
bool no_hsl = h.is_false() && s.is_false() && l.is_false();
if (color.type() != Node::numeric_color) {
throw_eval_error("first argument to 'change-color' must be a color", color.path(), color.line());
}
if (!no_rgb && !no_hsl) {
throw_eval_error("cannot specify RGB and HSL values for a color at the same time for 'change-color'", r.path(), r.line());
}
else if (!no_rgb) {
if (!r.is_false() && !r.is_numeric()) throw_eval_error("argument $red of 'change-color' must be numeric", r.path(), r.line());
if (!g.is_false() && !g.is_numeric()) throw_eval_error("argument $green of 'change-color' must be numeric", g.path(), g.line());
if (!b.is_false() && !b.is_numeric()) throw_eval_error("argument $blue of 'change-color' must be numeric", b.path(), b.line());
if (!a.is_false() && !a.is_numeric()) throw_eval_error("argument $alpha of 'change-color' must be numeric", a.path(), a.line());
double new_r = (r.is_false() ? color[0] : r).numeric_value();
double new_g = (g.is_false() ? color[1] : g).numeric_value();
double new_b = (b.is_false() ? color[2] : b).numeric_value();
double new_a = (a.is_false() ? color[3] : a).numeric_value();
return new_Node(path, line, new_r, new_g, new_b, new_a);
}
else if (!no_hsl) {
Node hsl_node(rgb_to_hsl(color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
new_Node, path, line));
if (!h.is_false() && !h.is_numeric()) throw_eval_error("argument $hue of 'change-color' must be numeric", h.path(), h.line());
if (!s.is_false() && !s.is_numeric()) throw_eval_error("argument $saturation of 'change-color' must be numeric", s.path(), s.line());
if (!l.is_false() && !l.is_numeric()) throw_eval_error("argument $lightness of 'change-color' must be numeric", l.path(), l.line());
if (!a.is_false() && !a.is_numeric()) throw_eval_error("argument $alpha of 'change-color' must be numeric", a.path(), a.line());
double new_h = (h.is_false() ? hsl_node[0].numeric_value() : h.numeric_value());
double new_s = (s.is_false() ? hsl_node[1].numeric_value() : s.numeric_value());
double new_l = (l.is_false() ? hsl_node[2].numeric_value() : l.numeric_value());
double new_a = (a.is_false() ? color[3].numeric_value() : a.numeric_value());
return hsla_impl(new_h, new_s, new_l, new_a, new_Node, path, line);
}
else if (!a.is_false()) {
if (!a.is_numeric()) throw_eval_error("argument $alpha of 'change-color' must be numeric", a.path(), a.line());
return new_Node(path, line,
color[0].numeric_value(),
color[1].numeric_value(),
color[2].numeric_value(),
a.numeric_value());
}
else {
throw_eval_error("not enough arguments for 'change-color'", color.path(), color.line());
}
// unreachable statement
return Node();
}
////////////////////////////////////////////////////////////////////////
// String Functions ////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
extern Signature unquote_sig = "unquote($string)";
Node unquote(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node cpy(new_Node(path, line, bindings[parameter_names[0].token()]));
cpy.is_quoted() = false;
return cpy;
}
extern Signature quote_sig = "quote($string)";
Node quote(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node orig(arg(quote_sig, path, line, parameter_names, bindings, 0, Node::string_t));
Node copy(new_Node(path, line, orig));
copy.is_quoted() = true;
return copy;
}
////////////////////////////////////////////////////////////////////////
// Number Functions ////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
extern Signature percentage_sig = "percentage($value)";
Node percentage(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node orig(arg(percentage_sig, path, line, parameter_names, bindings, 0, Node::number));
return new_Node(path, line, orig.numeric_value() * 100, Node::numeric_percentage);
}
extern Signature round_sig = "round($value)";
Node round(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node orig(arg(round_sig, path, line, parameter_names, bindings, 0, Node::numeric));
switch (orig.type())
{
case Node::numeric_dimension: {
return new_Node(path, line,
std::floor(orig.numeric_value() + 0.5),
orig.unit());
} break;
case Node::number: {
return new_Node(path, line,
std::floor(orig.numeric_value() + 0.5));
} break;
case Node::numeric_percentage: {
return new_Node(path, line,
std::floor(orig.numeric_value() + 0.5),
Node::numeric_percentage);
} break;
default: {
// unreachable
throw_eval_error("argument to round must be numeric", path, line);
} break;
}
// unreachable statement
return Node();
}
extern Signature ceil_sig = "ceil($value)";
Node ceil(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node orig(arg(ceil_sig, path, line, parameter_names, bindings, 0, Node::numeric));
switch (orig.type())
{
case Node::numeric_dimension: {
return new_Node(path, line,
std::ceil(orig.numeric_value()),
orig.unit());
} break;
case Node::number: {
return new_Node(path, line,
std::ceil(orig.numeric_value()));
} break;
case Node::numeric_percentage: {
return new_Node(path, line,
std::ceil(orig.numeric_value()),
Node::numeric_percentage);
} break;
default: {
// unreachable
throw_eval_error("argument to ceil must be numeric", path, line);
} break;
}
// unreachable statement
return Node();
}
extern Signature floor_sig = "floor($value)";
Node floor(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node orig(arg(floor_sig, path, line, parameter_names, bindings, 0, Node::numeric));
switch (orig.type())
{
case Node::numeric_dimension: {
return new_Node(path, line,
std::floor(orig.numeric_value()),
orig.unit());
} break;
case Node::number: {
return new_Node(path, line,
std::floor(orig.numeric_value()));
} break;
case Node::numeric_percentage: {
return new_Node(path, line,
std::floor(orig.numeric_value()),
Node::numeric_percentage);
} break;
default: {
// unreachable
throw_eval_error("argument to floor must be numeric", path, line);
} break;
}
// unreachable statement
return Node();
}
extern Signature abs_sig = "abs($value)";
Node abs(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node orig(arg(abs_sig, path, line, parameter_names, bindings, 0, Node::numeric));
switch (orig.type())
{
case Node::numeric_dimension: {
return new_Node(path, line,
std::abs(orig.numeric_value()),
orig.unit());
} break;
case Node::number: {
return new_Node(path, line,
std::abs(orig.numeric_value()));
} break;
case Node::numeric_percentage: {
return new_Node(path, line,
std::abs(orig.numeric_value()),
Node::numeric_percentage);
} break;
default: {
// unreachable
throw_eval_error("argument to abs must be numeric", path, line);
} break;
}
// unreachable statement
return Node();
}
////////////////////////////////////////////////////////////////////////
// List Functions //////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
extern Signature length_sig = "length($list)";
Node length(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node arg(bindings[parameter_names[0].token()]);
return new_Node(path, line, arg.type() == Node::list ? arg.size() : 1);
}
extern Signature nth_sig = "nth($list, $n)";
Node nth(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node l(bindings[parameter_names[0].token()]);
// wrap the first arg if it isn't a list
if (l.type() != Node::list) {
l = new_Node(Node::list, path, line, 1) << l;
}
if (l.size() == 0) {
throw_eval_error("cannot index into an empty list", path, line);
}
// just truncate the index if it's not an integer ... more permissive than Ruby Sass
size_t n = std::floor(arg(nth_sig, path, line, parameter_names, bindings, 1, Node::numeric, 1, l.size()).numeric_value());
return l[n - 1];
}
extern Signature index_sig = "index($list, $value)";
Node index(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node lst(bindings[parameter_names[0].token()]);
Node val(bindings[parameter_names[1].token()]);
// if $list isn't a list, wrap it in a singleton list
if (lst.type() != Node::list) lst = (new_Node(Node::list, path, line, 1) << lst);
for (size_t i = 0, S = lst.size(); i < S; ++i) {
if (lst[i] == val) return new_Node(path, line, i + 1);
}
return new_Node(Node::boolean, path, line, false);
}
extern Signature join_sig = "join($list1, $list2, $separator: auto)";
Node join(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
// if the args aren't lists, turn them into singleton lists
Node l1(bindings[parameter_names[0].token()]);
if (l1.type() != Node::list) {
l1 = (new_Node(Node::list, path, line, 1) << l1);
}
Node l2(bindings[parameter_names[1].token()]);
if (l2.type() != Node::list) {
l2 = (new_Node(Node::list, path, line, 1) << l2);
}
// figure out the combined size in advance
size_t size = l1.size() + l2.size();
// figure out the result type in advance
bool comma_sep;
string sep(bindings[parameter_names[2].token()].token().unquote());
if (sep == "comma") comma_sep = true;
else if (sep == "space") comma_sep = false;
else if (sep == "auto") comma_sep = l1.is_comma_separated();
else throw_eval_error("third argument to 'join' must be 'space', 'comma', or 'auto'", path, line);
if (l1.size() == 0) comma_sep = l2.is_comma_separated();
// accumulate the result
Node lr(new_Node(Node::list, path, line, size));
lr += l1;
lr += l2;
lr.is_comma_separated() = comma_sep;
return lr;
}
extern Signature append_sig = "append($list1, $list2, $separator: auto)";
Node append(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node list(bindings[parameter_names[0].token()]);
// if the first arg isn't a list, wrap it in a singleton
if (list.type() != Node::list) list = (new_Node(Node::list, path, line, 1) << list);
bool comma_sep;
string sep(bindings[parameter_names[2].token()].token().unquote());
if (sep == "comma") comma_sep = true;
else if (sep == "space") comma_sep = false;
else if (sep == "auto") comma_sep = list.is_comma_separated();
else throw_eval_error("third argument to 'append' must be 'space', 'comma', or 'auto'", path, line);
Node new_list(new_Node(Node::list, path, line, list.size() + 1));
new_list += list;
new_list << bindings[parameter_names[1].token()];
new_list.is_comma_separated() = comma_sep;
return new_list;
}
extern Signature compact_1_sig = "compact($arg1)";
Node compact_1(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node the_arg(bindings[parameter_names[0].token()]);
if (the_arg.type() == Node::list) {
Node non_nils(new_Node(Node::list, path, line, 0));
for (size_t i = 0, S = the_arg.size(); i < S; ++i) {
Node elt(the_arg[i]);
if (!elt.is_false()) non_nils << elt;
}
return non_nils;
}
return new_Node(Node::list, path, line, 1) << the_arg;
}
extern Signature compact_n_sig = "compact($arg1: false, $arg2: false, $arg3: false, $arg4: false, $arg5: false, $arg6: false, $arg7: false, $arg8: false, $arg9: false, $arg10: false, $arg11: false, $arg12: false)";
Node compact_n(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node non_nils(new_Node(Node::list, path, line, 0));
non_nils.is_comma_separated() = true;
for (size_t i = 0, S = bindings.current_frame.size(); i < S; ++i) {
Node the_arg(bindings[parameter_names[i].token()]);
if (!the_arg.is_false()) non_nils << the_arg;
}
return non_nils;
}
////////////////////////////////////////////////////////////////////////
// Introspection Functions /////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
extern Signature type_of_sig = "type-of($value)";
Node type_of(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node val(bindings[parameter_names[0].token()]);
Token type_name;
switch (val.type())
{
case Node::number:
case Node::numeric_dimension:
case Node::numeric_percentage: {
type_name = Token::make(number_name);
} break;
case Node::boolean: {
type_name = Token::make(bool_name);
} break;
case Node::string_constant:
case Node::value_schema: {
type_name = Token::make(string_name);
} break;
case Node::numeric_color: {
type_name = Token::make(color_name);
} break;
case Node::list: {
type_name = Token::make(list_name);
} break;
default: {
type_name = Token::make(string_name);
} break;
}
return new_Node(Node::identifier, path, line, type_name);
}
extern Signature unit_sig = "unit($number)";
Node unit(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node val(arg(unit_sig, path, line, parameter_names, bindings, 0, Node::numeric));
switch (val.type())
{
case Node::number: {
Node u(new_Node(Node::string_constant, path, line, Token::make(empty_str)));
u.is_quoted() = true;
return u;
} break;
case Node::numeric_dimension:
case Node::numeric_percentage: {
Node u(new_Node(Node::string_constant, path, line, val.unit()));
u.is_quoted() = true;
return u;
} break;
// unreachable
default: {
throw_eval_error("argument to 'unit' must be numeric", path, line);
} break;
}
// unreachable statement
return Node();
}
extern Signature unitless_sig = "unitless($number)";
Node unitless(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node val(arg(unitless_sig, path, line, parameter_names, bindings, 0, Node::numeric));
switch (val.type())
{
case Node::number: {
return new_Node(Node::boolean, path, line, true);
} break;
case Node::numeric_percentage:
case Node::numeric_dimension: {
return new_Node(Node::boolean, path, line, false);
} break;
// unreachable
default: {
throw_eval_error("argument to 'unitless' must be numeric", path, line);
} break;
}
// unreachable statement
return Node();
}
extern Signature comparable_sig = "comparable($number-1, $number-2)";
Node comparable(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node n1(arg(comparable_sig, path, line, parameter_names, bindings, 0, Node::numeric));
Node n2(arg(comparable_sig, path, line, parameter_names, bindings, 1, Node::numeric));
Node::Type t1 = n1.type();
Node::Type t2 = n2.type();
if ((t1 == Node::number && n2.is_numeric()) ||
(n1.is_numeric() && t2 == Node::number)) {
return new_Node(Node::boolean, path, line, true);
}
else if (t1 == Node::numeric_percentage && t2 == Node::numeric_percentage) {
return new_Node(Node::boolean, path, line, true);
}
else if (t1 == Node::numeric_dimension && t2 == Node::numeric_dimension) {
string u1(n1.unit().to_string());
string u2(n2.unit().to_string());
if ((u1 == "ex" && u2 == "ex") ||
(u1 == "em" && u2 == "em") ||
((u1 == "in" || u1 == "cm" || u1 == "mm" || u1 == "pt" || u1 == "pc" || u1 == "px") &&
(u2 == "in" || u2 == "cm" || u2 == "mm" || u2 == "pt" || u2 == "pc" || u2 == "px"))) {
return new_Node(Node::boolean, path, line, true);
}
else {
return new_Node(Node::boolean, path, line, false);
}
}
// default to false if we missed anything
return new_Node(Node::boolean, path, line, false);
}
////////////////////////////////////////////////////////////////////////
// Boolean Functions ///////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
extern Signature not_sig = "not($value)";
Node not_impl(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node val(bindings[parameter_names[0].token()]);
if (val.is_false()) return new_Node(Node::boolean, path, line, true);
return new_Node(Node::boolean, path, line, false);
}
extern Signature if_sig = "if($condition, $if-true, $if-false)";
Node if_impl(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node predicate(bindings[parameter_names[0].token()]);
Node consequent(bindings[parameter_names[1].token()]);
Node alternative(bindings[parameter_names[2].token()]);
if (predicate.is_false()) return alternative;
return consequent;
}
////////////////////////////////////////////////////////////////////////
// Path Functions //////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
extern Signature image_url_sig = "image-url($path, $only-path: false, $cache-buster: false)";
Node image_url(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
Node base_path(bindings[parameter_names[0].token()]);
bool only_path = !bindings[parameter_names[1].token()].is_false();
Node image_path_val(bindings[Token::make(image_path_var)]);
Node result(new_Node(Node::concatenation, path, line, 2));
result << image_path_val;
result << base_path;
result.is_quoted() = true;
if (!only_path) result = (new_Node(Node::uri, path, line, 1) << result);
return result;
}
}
}
#define SASS_FUNCTIONS
#include <cstring>
#include <map>
#ifndef SASS_NODE
#include "node.hpp"
#endif
namespace Sass {
struct Environment;
struct Context;
struct Node_Factory;
using std::map;
typedef Node (*Primitive)(const Node, Environment&, Node_Factory&, 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, string& path, size_t line) const
{
if (primitive) return primitive(parameters, bindings, new_Node, path, line);
else return Node();
}
};
namespace Functions {
// RGB Functions ///////////////////////////////////////////////////////
extern Signature rgb_sig;
Node rgb(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature rgba_4_sig;
Node rgba_4(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature rgba_2_sig;
Node rgba_2(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature red_sig;
Node red(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature green_sig;
Node green(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature blue_sig;
Node blue(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature mix_sig;
Node mix(const Node, Environment&, Node_Factory&, string& path, size_t line);
// HSL Functions ///////////////////////////////////////////////////////
extern Signature hsl_sig;
Node hsl(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature hsla_sig;
Node hsla(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature hue_sig;
Node hue(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature saturation_sig;
Node saturation(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature lightness_sig;
Node lightness(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature adjust_hue_sig;
Node adjust_hue(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature lighten_sig;
Node lighten(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature darken_sig;
Node darken(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature saturate_sig;
Node saturate(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature desaturate_sig;
Node desaturate(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature grayscale_sig;
Node grayscale(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature complement_sig;
Node complement(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature invert_sig;
Node invert(const Node, Environment&, Node_Factory&, string& path, size_t line);
// Opacity Functions ///////////////////////////////////////////////////
extern Signature alpha_sig;
Node alpha(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature opacity_sig;
Node opacity(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature opacify_sig;
Node opacify(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature fade_in_sig;
Node fade_in(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature transparentize_sig;
Node transparentize(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature fade_out_sig;
Node fade_out(const Node, Environment&, Node_Factory&, string& path, size_t line);
// Other Color Functions ///////////////////////////////////////////////
extern Signature adjust_color_sig;
Node adjust_color(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature scale_color_sig;
Node scale_color(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature change_color_sig;
Node change_color(const Node, Environment&, Node_Factory&, string& path, size_t line);
// String Functions ////////////////////////////////////////////////////
extern Signature unquote_sig;
Node unquote(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature quote_sig;
Node quote(const Node, Environment&, Node_Factory&, string& path, size_t line);
// Number Functions ////////////////////////////////////////////////////
extern Signature percentage_sig;
Node percentage(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature round_sig;
Node round(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature ceil_sig;
Node ceil(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature floor_sig;
Node floor(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature abs_sig;
Node abs(const Node, Environment&, Node_Factory&, string& path, size_t line);
// List Functions //////////////////////////////////////////////////////
extern Signature length_sig;
Node length(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature nth_sig;
Node nth(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature index_sig;
Node index(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature join_sig;
Node join(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature append_sig;
Node append(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature compact_1_sig;
Node compact_1(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature compact_n_sig;
Node compact_n(const Node, Environment&, Node_Factory&, string& path, size_t line);
// Introspection Functions /////////////////////////////////////////////
extern Signature type_of_sig;
Node type_of(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature unit_sig;
Node unit(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature unitless_sig;
Node unitless(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature comparable_sig;
Node comparable(const Node, Environment&, Node_Factory&, string& path, size_t line);
// Boolean Functions ///////////////////////////////////////////////////
extern Signature not_sig;
Node not_impl(const Node, Environment&, Node_Factory&, string& path, size_t line);
extern Signature if_sig;
Node if_impl(const Node, Environment&, Node_Factory&, string& path, size_t line);
// Path Functions //////////////////////////////////////////////////////
extern Signature image_url_sig;
Node image_url(const Node, Environment&, Node_Factory&, string& path, size_t line);
}
}
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-01-19.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# 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
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for `test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
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.
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004, 2005, 2007, 2008, 2009 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 7 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option `$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl `shared' nor `disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the `shared' and
# `disable-shared' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the `static' and
# `disable-static' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the `fast-install'
# and `disable-fast-install' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
# LT_INIT options.
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for lt_pkg in $withval; do
IFS="$lt_save_ifs"
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])
# 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])])
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2012-01-06.13; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;
makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
#include <sstream>
#include <algorithm>
#include <iostream>
#include "node.hpp"
#include "constants.hpp"
#include "error.hpp"
namespace Sass {
using namespace std;
using namespace Constants;
// ------------------------------------------------------------------------
// Node method implementations
// ------------------------------------------------------------------------
void Node::flatten()
{
switch (type())
{
case block:
case mixin_call:
case root:
case if_directive:
case for_through_directive:
case for_to_directive:
case each_directive:
case while_directive:
break;
default:
return;
}
// size can change during flattening, so we need to call size() on each pass
for (size_t i = 0; i < size(); ++i) {
switch (at(i).type())
{
case mixin_call:
case block:
case if_directive:
case for_through_directive:
case for_to_directive:
case each_directive:
case while_directive: {
Node expn(at(i));
if (expn.has_expansions()) expn.flatten();
ip_->has_statements |= expn.has_statements();
ip_->has_blocks |= expn.has_blocks();
ip_->has_expansions |= expn.has_expansions();
// TO DO: make this more efficient -- replace with a dummy node instead of erasing
ip_->children.erase(begin() + i);
insert(begin() + i, expn.begin(), expn.end());
// skip over what we just spliced in
i += expn.size() - 1;
} break;
default: {
} break;
}
}
}
string Node::unquote() const
{
switch (type())
{
case string_constant:
case identifier: {
return token().unquote();
} break;
default: {
// do nothing; fall though to the rest
} break;
}
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(), 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();
// }
if (is_string() && rhs.is_string()) {
return unquote() == rhs.unquote();
}
else if (t != u) {
return false;
}
switch (t)
{
case list:
case expression:
case term:
case numeric_color: {
if (size() != rhs.size()) return false;
if ((t == list) && (is_comma_separated() != rhs.is_comma_separated())) return false;
for (size_t i = 0, L = size(); i < L; ++i) {
if (at(i) == rhs[i]) continue;
else return false;
}
return true;
} break;
case variable:
case identifier:
case uri:
case textual_percentage:
case textual_dimension:
case textual_number:
case textual_hex:
case string_constant: {
return token().unquote() == rhs.token().unquote();
} break;
case number:
case numeric_percentage: {
return numeric_value() == rhs.numeric_value();
} break;
case numeric_dimension: {
if (unit() == rhs.unit()) {
return numeric_value() == rhs.numeric_value();
}
else {
return false;
}
} break;
case boolean: {
return boolean_value() == rhs.boolean_value();
} break;
case selector: {
if (has_children() && rhs.has_children() && (size() == rhs.size())) {
for (size_t i = 0, S = size(); i < S; ++i) {
if (at(i) == rhs[i]) continue;
else return false;
}
return true;
}
else {
return false;
}
} break;
case simple_selector: {
if (token() == rhs.token()) return true;
} break;
default: {
return false;
} break;
}
return false;
}
bool Node::operator!=(Node rhs) const
{ return !(*this == rhs); }
bool Node::operator<(Node rhs) const
{
Type lhs_type = type();
Type rhs_type = rhs.type();
// comparing atomic numbers
if ((lhs_type == number && rhs_type == number) ||
(lhs_type == numeric_percentage && rhs_type == numeric_percentage)) {
return numeric_value() < rhs.numeric_value();
}
// comparing numbers with units
else if (lhs_type == numeric_dimension && rhs_type == numeric_dimension) {
if (unit() == rhs.unit()) {
return numeric_value() < rhs.numeric_value();
}
else {
throw Error(Error::evaluation, path(), line(), "incompatible units");
}
}
// comparing colors
else if (lhs_type == numeric_color && rhs_type == numeric_color) {
return lexicographical_compare(begin(), end(), rhs.begin(), rhs.end());
}
// comparing identifiers and strings (treat them as comparable)
else if ((is_string() && rhs.is_string()) ||
(lhs_type == value && rhs_type == value)) {
return unquote() < rhs.unquote();
}
// else if ((lhs_type == identifier || lhs_type == string_constant || lhs_type == value) &&
// (rhs_type == identifier || lhs_type == string_constant || rhs_type == value)) {
// return token().unquote() < rhs.token().unquote();
// }
// COMPARING SELECTORS -- IMPORTANT FOR ORDERING AND NORMALIZING
else if ((type() >= selector_group && type() <=selector_schema) &&
(rhs.type() >= selector_group && rhs.type() <=selector_schema)) {
// if they're not the same kind, just compare type tags
if (type() != rhs.type()) return type() < rhs.type();
// otherwise we have to do more work
switch (type())
{
case simple_selector:
case pseudo: {
return token() < rhs.token();
} break;
// assumes selectors are normalized by the time they're compared
case selector:
case simple_selector_sequence:
case attribute_selector:
case functional_pseudo:
case pseudo_negation: {
return lexicographical_compare(begin(), end(), rhs.begin(), rhs.end());
} break;
default: {
return false;
} break;
}
}
// END OF SELECTOR COMPARISON
// catch-all
else {
throw Error(Error::evaluation, path(), line(), "incomparable types");
}
}
bool Node::operator<=(Node rhs) const
{ return *this < rhs || *this == rhs; }
bool Node::operator>(Node rhs) const
{ return !(*this <= rhs); }
bool Node::operator>=(Node rhs) const
{ return !(*this < rhs); }
// ------------------------------------------------------------------------
// Token method implementations
// ------------------------------------------------------------------------
string Token::unquote() const
{
string result;
const char* p = begin;
if (*begin == '\'' || *begin == '"') {
++p;
while (p < end) {
if (*p == '\\') {
switch (*(++p)) {
case 'n': result += '\n'; break;
case 't': result += '\t'; break;
case 'b': result += '\b'; break;
case 'r': result += '\r'; break;
case 'f': result += '\f'; break;
case 'v': result += '\v'; break;
case 'a': result += '\a'; break;
case '\\': result += '\\'; break;
default: result += *p; break;
}
}
else if (p == end - 1) {
return result;
}
else {
result += *p;
}
++p;
}
return result;
}
else {
while (p < end) {
result += *(p++);
}
return result;
}
}
void Token::unquote_to_stream(std::stringstream& buf) const
{
const char* p = begin;
if (*begin == '\'' || *begin == '"') {
++p;
while (p < end) {
if (*p == '\\') {
switch (*(++p)) {
case 'n': buf << '\n'; break;
case 't': buf << '\t'; break;
case 'b': buf << '\b'; break;
case 'r': buf << '\r'; break;
case 'f': buf << '\f'; break;
case 'v': buf << '\v'; break;
case 'a': buf << '\a'; break;
case '\\': buf << '\\'; break;
default: buf << *p; break;
}
}
else if (p == end - 1) {
return;
}
else {
buf << *p;
}
++p;
}
return;
}
else {
while (p < end) {
buf << *(p++);
}
return;
}
}
bool Token::operator<(const Token& rhs) const
{
const char* first1 = begin;
const char* last1 = end;
const char* first2 = rhs.begin;
const char* last2 = rhs.end;
while (first1!=last1)
{
if (first2 == last2 || *first2 < *first1) return false;
else if (*first1 < *first2) return true;
++first1; ++first2;
}
return (first2 != last2);
}
bool Token::operator==(const Token& rhs) const
{
if (length() != rhs.length()) return false;
if ((begin[0] == '"' || begin[0] == '\'') &&
(rhs.begin[0] == '"' || rhs.begin[0] == '\''))
{ return unquote() == rhs.unquote(); }
const char* p = begin;
const char* q = rhs.begin;
for (; p < end; ++p, ++q) if (*p != *q) return false;
return true;
}
// ------------------------------------------------------------------------
// Node_Impl method implementations
// ------------------------------------------------------------------------
double Node_Impl::numeric_value()
{
switch (type)
{
case Node::number:
case Node::numeric_percentage:
return value.numeric;
case Node::numeric_dimension:
return value.dimension.numeric;
default:
break;
// throw an exception?
}
// if you reach this point, you've got a logic error somewhere
return 0;
}
Token Node_Impl::unit()
{
switch (type)
{
case Node::numeric_percentage: {
return Token::make(percent_str);
} break;
case Node::numeric_dimension: {
return value.dimension.unit;
} break;
default: break;
}
return Token::make(empty_str);
}
}
\ No newline at end of file
#define SASS_NODE
#include <cstring>
#include <string>
#include <vector>
#include <iostream>
namespace Sass {
using namespace std;
// Token type for representing lexed chunks of text
struct Token {
const char* begin;
const char* end;
// Need Token::make(...) because tokens are union members, and hence they
// can't have non-trivial constructors.
static Token make()
{
Token t;
t.begin = 0;
t.end = 0;
return t;
}
static Token make(const char* s)
{
Token t;
t.begin = s;
t.end = s + std::strlen(s);
return t;
}
static Token make(const char* b, const char* e)
{
Token t;
t.begin = b;
t.end = e;
return t;
}
size_t length() const
{ return end - begin; }
string to_string() const
{ return string(begin, end - begin); }
string unquote() const;
void unquote_to_stream(std::stringstream& buf) const;
operator bool()
{ return begin && end && begin >= end; }
bool operator<(const Token& rhs) const;
bool operator==(const Token& rhs) const;
};
struct Dimension {
double numeric;
Token unit;
};
struct Node_Impl;
// Node type for representing SCSS expression nodes. Really just a handle.
class Node {
private:
friend class Node_Factory;
Node_Impl* ip_;
public:
enum Type {
none,
any,
numeric, // number, numeric_percentage, or numeric_dimension
string_t, // string_constant, identifier, concatenation, schemata
comment,
root,
ruleset,
propset,
media_query,
selector_group,
selector,
selector_combinator,
simple_selector_sequence,
backref,
simple_selector,
type_selector,
class_selector,
id_selector,
pseudo,
pseudo_negation,
functional_pseudo,
attribute_selector,
selector_schema,
media_expression_group,
media_expression,
block,
rule,
property,
list,
disjunction,
conjunction,
relation,
eq,
neq,
gt,
gte,
lt,
lte,
expression,
add,
sub,
term,
mul,
div,
factor,
unary_plus,
unary_minus,
values,
value,
identifier,
uri,
textual_percentage,
textual_dimension,
textual_number,
textual_hex,
color_name,
string_constant,
concatenation,
number,
numeric_percentage,
numeric_dimension,
numeric_color,
boolean,
important,
value_schema,
string_schema,
identifier_schema,
css_import,
function,
function_call,
mixin,
mixin_call,
parameters,
arguments,
extend_directive,
if_directive,
for_through_directive,
for_to_directive,
each_directive,
while_directive,
return_directive,
content_directive,
warning,
block_directive,
blockless_directive,
variable,
assignment
};
Node(Node_Impl* ip = 0);
Type type() const;
Type type(Type);
bool has_children() const;
bool has_statements() const;
bool has_blocks() const;
bool has_expansions() const;
bool has_backref() const;
bool from_variable() const;
bool& should_eval() const;
bool& is_quoted() const;
bool is_numeric() const;
bool is_string() const; // for all string-like types
bool is_schema() const; // for all interpolated data
bool is_guarded() const;
bool& has_been_extended() const;
bool is_false() const;
bool& is_comma_separated() const;
string& path() const;
size_t line() const;
size_t size() const;
bool empty() const;
Node& at(size_t i) const;
Node& back() const;
Node& operator[](size_t i) const;
void pop_back();
void pop_all();
Node& push_back(Node n);
Node& push_front(Node n);
Node& operator<<(Node n);
Node& operator+=(Node n);
vector<Node>::iterator begin() const;
vector<Node>::iterator end() const;
void insert(vector<Node>::iterator position,
vector<Node>::iterator first,
vector<Node>::iterator last);
bool boolean_value() const;
double numeric_value() const;
Token token() const;
Token unit() const;
bool is_null() const { return !ip_; }
bool is(Node n) const { return ip_ == n.ip_; }
void flatten();
string unquote() const;
bool operator==(Node rhs) const;
bool operator!=(Node rhs) const;
bool operator<(Node rhs) const;
bool operator<=(Node rhs) const;
bool operator>(Node rhs) const;
bool operator>=(Node rhs) const;
string to_string(Type inside_of = none) const;
void emit_nested_css(stringstream& buf, size_t depth, bool at_toplevel = false, bool in_media_query = false);
void emit_propset(stringstream& buf, size_t depth, const string& prefix);
void echo(stringstream& buf, size_t depth = 0);
void emit_expanded_css(stringstream& buf, const string& prefix);
};
// The actual implementation object for Nodes; Node handles point at these.
struct Node_Impl {
union value_t {
bool boolean;
double numeric;
Token token;
Dimension dimension;
} value;
// TO DO: look into using a custom allocator in the Node_Factory class
vector<Node> children; // Can't be in the union because it has non-trivial constructors!
string path;
size_t line;
Node::Type type;
bool has_children;
bool has_statements;
bool has_blocks;
bool has_expansions;
bool has_backref;
bool from_variable;
bool should_eval;
bool is_quoted;
bool has_been_extended;
bool is_comma_separated;
Node_Impl()
: /* value(value_t()),
children(vector<Node>()),
path(string()),
line(0),
type(Node::none), */
has_children(false),
has_statements(false),
has_blocks(false),
has_expansions(false),
has_backref(false),
from_variable(false),
should_eval(false),
is_quoted(false),
has_been_extended(false),
is_comma_separated(false)
{ }
bool is_numeric()
{ return type >= Node::number && type <= Node::numeric_dimension; }
bool is_string()
{
switch (type)
{
case Node::string_t:
case Node::identifier:
case Node::value_schema:
case Node::identifier_schema:
case Node::string_constant:
case Node::string_schema:
case Node::concatenation: {
return true;
} break;
default: {
return false;
} break;
}
return false;
}
bool is_schema()
{
switch (type)
{
case Node::selector_schema:
case Node::value_schema:
case Node::string_schema:
case Node::identifier_schema: {
return true;
} break;
default: {
return false;
} break;
}
return false;
}
size_t size()
{ return children.size(); }
bool empty()
{ return children.empty(); }
Node& at(size_t i)
{ return children.at(i); }
Node& back()
{ return children.back(); }
void push_back(const Node& n)
{
children.push_back(n);
has_children = true;
switch (n.type())
{
case Node::comment:
case Node::css_import:
case Node::rule:
case Node::propset:
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::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::mixin_call: {
has_expansions = true;
} break;
case Node::backref: {
has_backref = true;
} break;
default: break;
}
if (n.has_backref()) has_backref = true;
}
void push_front(const Node& n)
{
children.insert(children.begin(), n);
has_children = true;
switch (n.type())
{
case Node::comment:
case Node::css_import:
case Node::rule:
case Node::propset: has_statements = true; break;
case Node::media_query:
case Node::ruleset: has_blocks = true; break;
case Node::if_directive:
case Node::for_through_directive:
case Node::for_to_directive:
case Node::each_directive:
case Node::while_directive:
case Node::mixin_call: has_expansions = true; break;
case Node::backref: has_backref = true; break;
default: break;
}
if (n.has_backref()) has_backref = true;
}
void pop_back()
{ children.pop_back(); }
void pop_all()
{ for (size_t i = 0, S = size(); i < S; ++i) pop_back(); }
bool& boolean_value()
{ return value.boolean; }
double numeric_value();
Token unit();
};
// ------------------------------------------------------------------------
// Node method implementations
// -- in the header file so they can easily be declared inline
// -- outside of their class definition to get the right declaration order
// ------------------------------------------------------------------------
inline Node::Node(Node_Impl* ip) : ip_(ip) { }
inline Node::Type Node::type() const { return ip_->type; }
inline Node::Type Node::type(Type t) { return ip_->type = t; }
inline bool Node::has_children() const { return ip_->has_children; }
inline bool Node::has_statements() const { return ip_->has_statements; }
inline bool Node::has_blocks() const { return ip_->has_blocks; }
inline bool Node::has_expansions() const { return ip_->has_expansions; }
inline bool Node::has_backref() const { return ip_->has_backref; }
inline bool Node::from_variable() const { return ip_->from_variable; }
inline bool& Node::should_eval() const { return ip_->should_eval; }
inline bool& Node::is_quoted() const { return ip_->is_quoted; }
inline bool Node::is_numeric() const { return ip_->is_numeric(); }
inline bool Node::is_string() const { return ip_->is_string(); }
inline bool Node::is_schema() const { return ip_->is_schema(); }
inline bool Node::is_guarded() const { return (type() == assignment) && (size() == 3); }
inline bool& Node::has_been_extended() const { return ip_->has_been_extended; }
inline bool Node::is_false() const { return (type() == boolean) && (boolean_value() == false); }
inline bool& Node::is_comma_separated() const { return ip_->is_comma_separated; }
inline string& Node::path() const { return ip_->path; }
inline size_t Node::line() const { return ip_->line; }
inline size_t Node::size() const { return ip_->size(); }
inline bool Node::empty() const { return ip_->empty(); }
inline Node& Node::at(size_t i) const { return ip_->at(i); }
inline Node& Node::back() const { return ip_->back(); }
inline Node& Node::operator[](size_t i) const { return at(i); }
inline void Node::pop_back() { ip_->pop_back(); }
inline void Node::pop_all() { ip_->pop_all(); }
inline Node& Node::push_back(Node n)
{
ip_->push_back(n);
return *this;
}
inline Node& Node::push_front(Node n)
{
ip_->push_front(n);
return *this;
}
inline Node& Node::operator<<(Node n) { return push_back(n); }
inline Node& Node::operator+=(Node n)
{
for (size_t i = 0, L = n.size(); i < L; ++i) push_back(n[i]);
return *this;
}
inline vector<Node>::iterator Node::begin() const
{ return ip_->children.begin(); }
inline vector<Node>::iterator Node::end() const
{ return ip_->children.end(); }
inline void Node::insert(vector<Node>::iterator position,
vector<Node>::iterator first,
vector<Node>::iterator last)
{ ip_->children.insert(position, first, last); }
inline bool Node::boolean_value() const { return ip_->boolean_value(); }
inline double Node::numeric_value() const { return ip_->numeric_value(); }
inline Token Node::token() const { return ip_->value.token; }
inline Token Node::unit() const { return ip_->unit(); }
}
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include "node.hpp"
using std::string;
using std::stringstream;
using std::cout;
using std::cerr;
using std::endl;
namespace Sass {
string Node::to_string(Type inside_of) const
{
switch (type())
{
case none: {
return "";
} break;
case selector_group:
case media_expression_group: { // really only needed for arg to :not
string result(at(0).to_string());
for (size_t i = 1, S = size(); i < S; ++i) {
result += ", ";
result += at(i).to_string();
}
return result;
} break;
case media_expression: {
string result;
if (at(0).type() == rule) {
result += "(";
result += at(0).to_string();
result += ")";
}
else {
result += at(0).to_string();
}
for (size_t i = 1, S = size(); i < S; ++i) {
result += " ";
if (at(i).type() == rule) {
result += "(";
result += at(i).to_string();
result += ")";
}
else {
result += at(i).to_string();
}
}
return result;
} break;
case selector: {
string result;
result += at(0).to_string();
for (size_t i = 1, S = size(); i < S; ++i) {
result += " ";
result += at(i).to_string();
}
return result;
} break;
case selector_combinator: {
return token().to_string();
} break;
case simple_selector_sequence: {
string result;
for (size_t i = 0, S = size(); i < S; ++i) {
result += at(i).to_string();
}
return result;
} break;
case pseudo:
case simple_selector: {
return token().to_string();
} break;
case pseudo_negation: {
string result;
result += at(0).to_string();
result += at(1).to_string();
result += ')';
return result;
} break;
case functional_pseudo: {
string result;
result += at(0).to_string();
for (size_t i = 1, S = size(); i < S; ++i) {
result += at(i).to_string();
}
result += ')';
return result;
} break;
case attribute_selector: {
string result;
result += "[";
for (size_t i = 0, S = size(); i < S; ++i) {
result += at(i).to_string();
}
result += ']';
return result;
} break;
case rule: {
string result(at(0).to_string(property));
result += ": ";
result += at(1).to_string();
return result;
} break;
case list: {
if (size() == 0) return "";
string result(at(0).to_string());
for (size_t i = 1, S = size(); i < S; ++i) {
if (at(i).is_null()) continue;
if (at(i).type() == list && at(i).size() == 0) continue;
result += is_comma_separated() ? ", " : " ";
result += at(i).to_string();
}
return result;
} break;
// still necessary for unevaluated expressions
case expression:
case term: {
string result(at(0).to_string());
for (size_t i = 1, S = size(); i < S; ++i) {
if (at(i).type() != add && at(i).type() != mul) {
result += at(i).to_string();
}
}
return result;
} break;
//edge case
case sub: {
return "-";
} break;
case div: {
return "/";
} break;
case css_import: {
stringstream ss;
ss << "@import url(";
ss << at(0).to_string();
ss << ")";
return ss.str();
}
case function_call: {
stringstream ss;
ss << at(0).to_string();
ss << "(";
ss << at(1).to_string();
ss << ")";
return ss.str();
}
case arguments: {
stringstream ss;
size_t S = size();
if (S > 0) {
ss << at(0).to_string();
for (size_t i = 1; i < S; ++i) {
ss << ", ";
ss << at(i).to_string();
}
}
return ss.str();
}
case unary_plus: {
stringstream ss;
ss << "+";
ss << at(0).to_string();
return ss.str();
}
case unary_minus: {
stringstream ss;
ss << "-";
ss << at(0).to_string();
return ss.str();
}
case numeric_percentage: {
stringstream ss;
ss << numeric_value();
ss << '%';
return ss.str();
}
case numeric_dimension: {
stringstream ss;
ss << numeric_value() << unit().to_string();
return ss.str();
} break;
case number: {
stringstream ss;
ss << numeric_value();
return ss.str();
} break;
case numeric_color: {
if (at(3).numeric_value() >= 1.0)
{
double a = at(0).numeric_value();
double b = at(1).numeric_value();
double c = at(2).numeric_value();
if (a >= 0xff && b >= 0xff && c >= 0xff)
{ return "white"; }
else if (a >= 0xff && b >= 0xff && c == 0)
{ return "yellow"; }
else if (a == 0 && b >= 0xff && c >= 0xff)
{ return "aqua"; }
else if (a >= 0xff && b == 0 && c >= 0xff)
{ return "fuchsia"; }
else if (a >= 0xff && b == 0 && c == 0)
{ return "red"; }
else if (a == 0 && b >= 0xff && c == 0)
{ return "lime"; }
else if (a == 0 && b == 0 && c >= 0xff)
{ return "blue"; }
else if (a <= 0 && b <= 0 && c <= 0)
{ return "black"; }
else
{
stringstream ss;
ss << '#' << std::setw(2) << std::setfill('0') << std::hex;
for (size_t i = 0; i < 3; ++i) {
double x = at(i).numeric_value();
if (x > 0xff) x = 0xff;
else if (x < 0) x = 0;
ss << std::hex << std::setw(2) << static_cast<unsigned long>(std::floor(x+0.5));
}
return ss.str();
}
}
else
{
stringstream ss;
ss << "rgba(" << static_cast<unsigned long>(at(0).numeric_value());
for (size_t i = 1; i < 3; ++i) {
ss << ", " << static_cast<unsigned long>(at(i).numeric_value());
}
ss << ", " << at(3).numeric_value() << ')';
return ss.str();
}
} break;
case uri: {
string result("url(");
// result += token().to_string();
result += at(0).to_string();
result += ")";
return result;
} break;
case mixin_call: {
// ignore it
return "";
} break;
case string_constant: {
if (!is_quoted()) return token().unquote();
else {
string result(token().to_string());
if (result[0] != '"' && result[0] != '\'') return "\"" + result + "\"";
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";
else return "false";
} break;
case important: {
return "!important";
} break;
case value_schema:
case identifier_schema: {
string result;
for (size_t i = 0, S = size(); i < S; ++i) {
if (at(i).type() == string_constant) {
result += at(i).token().unquote();
}
else {
result += at(i).to_string(identifier_schema);
}
}
if (is_quoted()) result = "\"" + result + "\"";
return result;
} break;
case string_schema: {
string result;
for (size_t i = 0, S = size(); i < S; ++i) {
string chunk(at(i).to_string());
if (at(i).type() == string_constant) {
result += chunk.substr(1, chunk.size()-2);
}
else {
result += chunk;
}
}
if (!is_quoted()) result = result.substr(1, result.length() - 2);
return result;
} break;
case concatenation: {
string result;
for (size_t i = 0, S = size(); i < S; ++i) {
result += at(i).unquote();
}
if (!(inside_of == identifier_schema || inside_of == property) && is_quoted()) {
result = "\"" + result + "\"";
}
return result;
} break;
case warning: {
return "";
} break;
default: {
// return content.token.to_string();
if (!has_children()) return token().to_string();
else return "";
} break;
}
}
void Node::emit_nested_css(stringstream& buf, size_t depth, bool at_toplevel, bool in_media_query)
{
switch (type())
{
case root: {
if (has_expansions()) flatten();
for (size_t i = 0, S = size(); i < S; ++i) {
at(i).emit_nested_css(buf, depth, true);
}
} break;
case ruleset: {
Node sel_group(at(2));
Node block(at(1));
if (block.has_expansions()) block.flatten();
if (block.has_statements()) {
buf << string(2*depth, ' ');
buf << sel_group.to_string();
buf << " {";
for (size_t i = 0, S = block.size(); i < S; ++i) {
Type stm_type = block[i].type();
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 << " }";
if (!in_media_query || (in_media_query && block.has_blocks())) buf << endl;
++depth; // if we printed content at this level, we need to indent any nested rulesets
}
if (block.has_blocks()) {
for (size_t i = 0, S = block.size(); i < S; ++i) {
if (block[i].type() == ruleset || block[i].type() == media_query) {
block[i].emit_nested_css(buf, depth, false, in_media_query);
}
}
}
if (block.has_statements()) --depth; // see previous comment
if ((depth == 0) && at_toplevel && !in_media_query) buf << endl;
} break;
case media_query: {
buf << string(2*depth, ' ');
buf << "@media " << at(0).to_string() << " {" << endl;
at(1).emit_nested_css(buf, depth+1, false, true);
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;
case rule: {
buf << endl << string(2*depth, ' ');
buf << to_string();
// at(0).emit_nested_css(buf, depth); // property
// at(1).emit_nested_css(buf, depth); // values
buf << ";";
} break;
case css_import: {
buf << string(2*depth, ' ');
buf << to_string();
buf << ";" << endl;
} break;
case property: {
buf << token().to_string() << ": ";
} break;
case values: {
for (size_t i = 0, S = size(); i < S; ++i) {
buf << " " << at(i).token().to_string();
}
} break;
case comment: {
if (depth != 0) buf << endl;
buf << string(2*depth, ' ') << token().to_string();
if (depth == 0) buf << endl;
} break;
default: {
buf << to_string();
} break;
}
}
void Node::emit_propset(stringstream& buf, size_t depth, const string& prefix)
{
string new_prefix(prefix);
// bool has_prefix = false;
if (new_prefix.empty()) {
new_prefix += "\n";
new_prefix += string(2*depth, ' ');
new_prefix += at(0).token().to_string();
}
else {
new_prefix += "-";
new_prefix += at(0).token().to_string();
// has_prefix = true;
}
Node rules(at(1));
for (size_t i = 0, S = rules.size(); i < S; ++i) {
if (rules[i].type() == propset) {
rules[i].emit_propset(buf, depth+1, new_prefix);
}
else {
buf << new_prefix;
if (rules[i][0].token().to_string() != "") buf << '-';
rules[i][0].emit_nested_css(buf, depth);
rules[i][1].emit_nested_css(buf, depth);
buf << ';';
}
}
}
void Node::echo(stringstream& buf, size_t depth) { }
void Node::emit_expanded_css(stringstream& buf, const string& prefix) { }
}
\ No newline at end of file
#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 boolean values
// Node operator()(Node::Type type, string file, size_t line, bool b);
// for making nodes representing numbers
Node operator()(string file, size_t line, double v, Node::Type type = Node::number);
// 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
#include <cctype>
#include <iostream>
#include "constants.hpp"
#include "prelexer.hpp"
namespace Sass {
using namespace Constants;
namespace Prelexer {
using std::cerr; using std::endl;
// Matches zero characters (always succeeds without consuming input).
const char* epsilon(char *src) {
return src;
}
// Matches the empty string.
const char* empty(char *src) {
return *src ? 0 : src;
}
// Match any single character.
const char* any_char(const char* src) { return *src ? src++ : src; }
// Match a single character satisfying the ctype predicates.
const char* space(const char* src) { return std::isspace(*src) ? src+1 : 0; }
const char* alpha(const char* src) { return std::isalpha(*src) ? src+1 : 0; }
const char* digit(const char* src) { return std::isdigit(*src) ? src+1 : 0; }
const char* xdigit(const char* src) { return std::isxdigit(*src) ? src+1 : 0; }
const char* alnum(const char* src) { return std::isalnum(*src) ? src+1 : 0; }
const char* punct(const char* src) { return std::ispunct(*src) ? src+1 : 0; }
// Match multiple ctype characters.
const char* spaces(const char* src) { return one_plus<space>(src); }
const char* alphas(const char* src) { return one_plus<alpha>(src); }
const char* digits(const char* src) { return one_plus<digit>(src); }
const char* xdigits(const char* src) { return one_plus<xdigit>(src); }
const char* alnums(const char* src) { return one_plus<alnum>(src); }
const char* puncts(const char* src) { return one_plus<punct>(src); }
// Match a line comment.
const char* line_comment(const char* src) { return to_endl<slash_slash>(src); }
// Match a block comment.
const char* block_comment(const char* src) {
return sequence< optional_spaces, delimited_by<slash_star, star_slash, false> >(src);
}
// Match either comment.
const char* comment(const char* src) {
return alternatives<block_comment, line_comment>(src);
}
// Match double- and single-quoted strings.
const char* double_quoted_string(const char* src) {
return delimited_by<'"', '"', true>(src);
}
const char* single_quoted_string(const char* src) {
return delimited_by<'\'', '\'', true>(src);
}
const char* string_constant(const char* src) {
return alternatives<double_quoted_string, single_quoted_string>(src);
}
// Match interpolants.
const char* interpolant(const char* src) {
return delimited_by<hash_lbrace, rbrace, false>(src);
}
// Whitespace handling.
const char* optional_spaces(const char* src) { return optional<spaces>(src); }
const char* optional_comment(const char* src) { return optional<comment>(src); }
const char* spaces_and_comments(const char* src) {
return zero_plus< alternatives<spaces, comment> >(src);
}
const char* no_spaces(const char* src) {
return negate< spaces >(src);
}
// Match CSS identifiers.
const char* identifier(const char* src) {
return sequence< optional< exactly<'-'> >,
alternatives< alpha, exactly<'_'> >,
zero_plus< alternatives< alnum,
exactly<'-'>,
exactly<'_'> > > >(src);
}
// Match interpolant schemas
const char* identifier_schema(const char* src) {
// follows this pattern: (x*ix*)+ ... well, not quite
return one_plus< sequence< zero_plus< alternatives< identifier, exactly<'-'> > >,
interpolant,
zero_plus< alternatives< identifier, number, exactly<'-'> > > > >(src);
}
const char* value_schema(const char* src) {
// follows this pattern: ([xyz]*i[xyz]*)+
return one_plus< sequence< zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant > >,
interpolant,
zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant > > > >(src);
}
const char* filename_schema(const char* src) {
return one_plus< sequence< zero_plus< alternatives< identifier, number, exactly<'.'>, exactly<'/'> > >,
interpolant,
zero_plus< alternatives< identifier, number, exactly<'.'>, exactly<'/'> > > > >(src);
}
const char* filename(const char* src) {
return one_plus< alternatives< identifier, number, exactly<'.'> > >(src);
}
// Match CSS '@' keywords.
const char* at_keyword(const char* src) {
return sequence<exactly<'@'>, identifier>(src);
}
const char* import(const char* src) {
return exactly<import_kwd>(src);
}
const char* media(const char* src) {
return exactly<media_kwd>(src);
}
const char* mixin(const char* src) {
return exactly<mixin_kwd>(src);
}
const char* function(const char* src) {
return exactly<function_kwd>(src);
}
const char* return_directive(const char* src) {
return exactly<return_kwd>(src);
}
const char* include(const char* src) {
return exactly<include_kwd>(src);
}
const char* extend(const char* src) {
return exactly<extend_kwd>(src);
}
const char* if_directive(const char* src) {
return exactly<if_kwd>(src);
}
const char* else_directive(const char* src) {
return exactly<else_kwd>(src);
}
const char* elseif_directive(const char* src) {
return sequence< else_directive,
spaces_and_comments,
exactly< if_after_else_kwd > >(src);
}
const char* for_directive(const char* src) {
return exactly<for_kwd>(src);
}
const char* from(const char* src) {
return exactly<from_kwd>(src);
}
const char* to(const char* src) {
return exactly<to_kwd>(src);
}
const char* through(const char* src) {
return exactly<through_kwd>(src);
}
const char* each_directive(const char* src) {
return exactly<each_kwd>(src);
}
const char* in(const char* src) {
return exactly<in_kwd>(src);
}
const char* while_directive(const char* src) {
return exactly<while_kwd>(src);
}
const char* name(const char* src) {
return one_plus< alternatives< alnum,
exactly<'-'>,
exactly<'_'> > >(src);
}
const char* warn(const char* src) {
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<'*'> > >,
exactly<'|'> >(src);
}
const char* type_selector(const char* src) {
return sequence< optional<namespace_prefix>, identifier>(src);
}
const char* universal(const char* src) {
return sequence< optional<namespace_prefix>, exactly<'*'> >(src);
}
// Match CSS id names.
const char* id_name(const char* src) {
return sequence<exactly<'#'>, name>(src);
}
// Match CSS class names.
const char* class_name(const char* src) {
return sequence<exactly<'.'>, identifier>(src);
}
// Match CSS numeric constants.
const char* sign(const char* src) {
return class_char<sign_chars>(src);
}
const char* unsigned_number(const char* src) {
return alternatives<sequence< zero_plus<digits>,
exactly<'.'>,
one_plus<digits> >,
digits>(src);
}
const char* number(const char* src) {
return sequence< optional<sign>, unsigned_number>(src);
}
const char* coefficient(const char* src) {
return alternatives< sequence< optional<sign>, digits >,
sign >(src);
}
const char* binomial(const char* src) {
return sequence< optional<sign>,
optional<digits>,
exactly<'n'>, optional_spaces,
sign, optional_spaces,
digits >(src);
}
const char* percentage(const char* src) {
return sequence< number, exactly<'%'> >(src);
}
const char* em(const char* src) {
return sequence< number, exactly<em_kwd> >(src);
}
const char* dimension(const char* src) {
return sequence<number, identifier>(src);
}
const char* hex(const char* src) {
const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);
int len = p - src;
return (len != 4 && len != 7) ? 0 : p;
}
const char* rgb_prefix(const char* src) {
return exactly<rgb_kwd>(src);
}
// Match CSS uri specifiers.
const char* uri_prefix(const char* src) {
return exactly<url_kwd>(src);
}
// TODO: rename the following two functions
const char* uri(const char* src) {
return sequence< exactly<url_kwd>,
optional<spaces>,
string_constant,
optional<spaces>,
exactly<')'> >(src);
}
const char* url_value(const char* src) {
return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
one_plus< sequence< zero_plus< exactly<'/'> >, filename > >, // one or more folders and/or trailing filename
optional< exactly<'/'> > >(src);
}
const char* url_schema(const char* src) {
return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
filename_schema >(src); // optional trailing slash
}
// Match CSS "!important" keyword.
const char* important(const char* src) {
return sequence< exactly<'!'>,
spaces_and_comments,
exactly<important_kwd> >(src);
}
// Match Sass "!default" keyword.
const char* default_flag(const char* src) {
return sequence< exactly<'!'>,
spaces_and_comments,
exactly<default_kwd> >(src);
}
// Match CSS pseudo-class/element prefixes.
const char* pseudo_prefix(const char* src) {
return sequence< exactly<':'>, optional< exactly<':'> > >(src);
}
// Match CSS function call openers.
const char* functional(const char* src) {
return sequence< alternatives< identifier_schema, identifier >, exactly<'('> >(src);
}
// Match the CSS negation pseudo-class.
const char* pseudo_not(const char* src) {
return exactly< pseudo_not_kwd >(src);
}
// Match CSS 'odd' and 'even' keywords for functional pseudo-classes.
const char* even(const char* src) {
return exactly<even_kwd>(src);
}
const char* odd(const char* src) {
return exactly<odd_kwd>(src);
}
// Match CSS attribute-matching operators.
const char* exact_match(const char* src) { return exactly<'='>(src); }
const char* class_match(const char* src) { return exactly<tilde_equal>(src); }
const char* dash_match(const char* src) { return exactly<pipe_equal>(src); }
const char* prefix_match(const char* src) { return exactly<caret_equal>(src); }
const char* suffix_match(const char* src) { return exactly<dollar_equal>(src); }
const char* substring_match(const char* src) { return exactly<star_equal>(src); }
// Match CSS combinators.
const char* adjacent_to(const char* src) {
return sequence< optional_spaces, exactly<'+'> >(src);
}
const char* precedes(const char* src) {
return sequence< optional_spaces, exactly<'~'> >(src);
}
const char* parent_of(const char* src) {
return sequence< optional_spaces, exactly<'>'> >(src);
}
const char* ancestor_of(const char* src) {
return sequence< spaces, negate< exactly<'{'> > >(src);
}
// Match SCSS variable names.
const char* variable(const char* src) {
return sequence<exactly<'$'>, name>(src);
}
// Match Sass boolean keywords.
const char* true_val(const char* src) {
return exactly<true_kwd>(src);
}
const char* false_val(const char* src) {
return exactly<false_kwd>(src);
}
const char* and_op(const char* src) {
return exactly<and_kwd>(src);
}
const char* or_op(const char* src) {
return exactly<or_kwd>(src);
}
const char* not_op(const char* src) {
return exactly<not_kwd>(src);
}
const char* eq_op(const char* src) {
return exactly<eq>(src);
}
const char* neq_op(const char* src) {
return exactly<neq>(src);
}
const char* gt_op(const char* src) {
return exactly<gt>(src);
}
const char* gte_op(const char* src) {
return exactly<gte>(src);
}
const char* lt_op(const char* src) {
return exactly<lt>(src);
}
const char* lte_op(const char* src) {
return exactly<lte>(src);
}
// Path matching functions.
const char* folder(const char* src) {
return sequence< zero_plus< any_char_except<'/'> >,
exactly<'/'> >(src);
}
const char* folders(const char* src) {
return zero_plus< folder >(src);
}
}
}
\ No newline at end of file
#define SASS_PRELEXER
namespace Sass {
namespace Prelexer {
typedef int (*ctype_predicate)(int);
typedef const char* (*prelexer)(const char*);
// Match a single character literal.
template <char pre>
const char* exactly(const char* src) {
return *src == pre ? src + 1 : 0;
}
// Match a string constant.
template <const char* prefix>
const char* exactly(const char* src) {
const char* pre = prefix;
while (*pre && *src == *pre) ++src, ++pre;
return *pre ? 0 : src;
}
// Match a single character that satifies the supplied ctype predicate.
template <ctype_predicate pred>
const char* class_char(const char* src) {
return pred(*src) ? src + 1 : 0;
}
// Match a single character that is a member of the supplied class.
template <const char* char_class>
const char* class_char(const char* src) {
const char* cc = char_class;
while (*cc && *src != *cc) ++cc;
return *cc ? src + 1 : 0;
}
// Match a sequence of characters that all satisfy the supplied ctype predicate.
template <ctype_predicate pred>
const char* class_chars(const char* src) {
const char* p = src;
while (pred(*p)) ++p;
return p == src ? 0 : p;
}
// Match a sequence of characters that are all members of the supplied class.
template <const char* char_class>
const char* class_chars(const char* src) {
const char* p = src;
while (class_char<char_class>(p)) ++p;
return p == src ? 0 : p;
}
// Match a sequence of characters up to the next newline.
template <const char* prefix>
const char* to_endl(const char* src) {
if (!(src = exactly<prefix>(src))) return 0;
while (*src && *src != '\n') ++src;
return src;
}
// Match a sequence of characters delimited by the supplied chars.
template <char beg, char end, bool esc>
const char* delimited_by(const char* src) {
src = exactly<beg>(src);
if (!src) return 0;
const char* stop;
while (1) {
if (!*src) return 0;
stop = exactly<end>(src);
if (stop && (!esc || *(src - 1) != '\\')) return stop;
src = stop ? stop : src + 1;
}
}
// Match a sequence of characters delimited by the supplied strings.
template <const char* beg, const char* end, bool esc>
const char* delimited_by(const char* src) {
src = exactly<beg>(src);
if (!src) return 0;
const char* stop;
while (1) {
if (!*src) return 0;
stop = exactly<end>(src);
if (stop && (!esc || *(src - 1) != '\\')) return stop;
src = stop ? stop : src + 1;
}
}
// Match any single character.
const char* any_char(const char* src);
// Match any single character except the supplied one.
template <char c>
const char* any_char_except(const char* src) {
return (*src && *src != c) ? src+1 : 0;
}
// Matches zero characters (always succeeds without consuming input).
const char* epsilon(const char*);
// Matches the empty string.
const char* empty(const char*);
// Succeeds of the supplied matcher fails, and vice versa.
template <prelexer mx>
const char* negate(const char* src) {
return mx(src) ? 0 : src;
}
// Tries the matchers in sequence and returns the first match (or none)
template <prelexer mx1, prelexer mx2>
const char* alternatives(const char* src) {
const char* rslt;
(rslt = mx1(src)) || (rslt = mx2(src));
return rslt;
}
// Same as above, but with 3 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3>
const char* alternatives(const char* src) {
const char* rslt;
(rslt = mx1(src)) || (rslt = mx2(src)) || (rslt = mx3(src));
return rslt;
}
// Same as above, but with 4 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3, prelexer mx4>
const char* alternatives(const char* src) {
const char* rslt;
(rslt = mx1(src)) || (rslt = mx2(src)) ||
(rslt = mx3(src)) || (rslt = mx4(src));
return rslt;
}
// Same as above, but with 5 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3,
prelexer mx4, prelexer mx5>
const char* alternatives(const char* src) {
const char* rslt;
(rslt = mx1(src)) || (rslt = mx2(src)) || (rslt = mx3(src)) ||
(rslt = mx4(src)) || (rslt = mx5(src));
return rslt;
}
// Same as above, but with 6 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3,
prelexer mx4, prelexer mx5, prelexer mx6>
const char* alternatives(const char* src) {
const char* rslt;
(rslt = mx1(src)) || (rslt = mx2(src)) || (rslt = mx3(src)) ||
(rslt = mx4(src)) || (rslt = mx5(src)) || (rslt = mx6(src));
return rslt;
}
// Same as above, but with 7 arguments.
template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4,
prelexer mx5, prelexer mx6,
prelexer mx7>
const char* alternatives(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) || (rslt = mx2(rslt)) ||
(rslt = mx3(rslt)) || (rslt = mx4(rslt)) ||
(rslt = mx5(rslt)) || (rslt = mx6(rslt)) ||
(rslt = mx7(rslt));
return rslt;
}
// Same as above, but with 8 arguments.
template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4,
prelexer mx5, prelexer mx6,
prelexer mx7, prelexer mx8>
const char* alternatives(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) || (rslt = mx2(rslt)) ||
(rslt = mx3(rslt)) || (rslt = mx4(rslt)) ||
(rslt = mx5(rslt)) || (rslt = mx6(rslt)) ||
(rslt = mx7(rslt)) || (rslt = mx8(rslt));
return rslt;
}
// Tries the matchers in sequence and succeeds if they all succeed.
template <prelexer mx1, prelexer mx2>
const char* sequence(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) && (rslt = mx2(rslt));
return rslt;
}
// Same as above, but with 3 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3>
const char* sequence(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) && (rslt = mx2(rslt)) && (rslt = mx3(rslt));
return rslt;
}
// Same as above, but with 4 arguments.
template <prelexer mx1, prelexer mx2, prelexer mx3, prelexer mx4>
const char* sequence(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) && (rslt = mx2(rslt)) &&
(rslt = mx3(rslt)) && (rslt = mx4(rslt));
return rslt;
}
// Same as above, but with 5 arguments.
template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4,
prelexer mx5>
const char* sequence(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) && (rslt = mx2(rslt)) &&
(rslt = mx3(rslt)) && (rslt = mx4(rslt)) &&
(rslt = mx5(rslt));
return rslt;
}
// Same as above, but with 6 arguments.
template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4,
prelexer mx5, prelexer mx6>
const char* sequence(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) && (rslt = mx2(rslt)) &&
(rslt = mx3(rslt)) && (rslt = mx4(rslt)) &&
(rslt = mx5(rslt)) && (rslt = mx6(rslt));
return rslt;
}
// Same as above, but with 7 arguments.
template <prelexer mx1, prelexer mx2,
prelexer mx3, prelexer mx4,
prelexer mx5, prelexer mx6,
prelexer mx7>
const char* sequence(const char* src) {
const char* rslt = src;
(rslt = mx1(rslt)) && (rslt = mx2(rslt)) &&
(rslt = mx3(rslt)) && (rslt = mx4(rslt)) &&
(rslt = mx5(rslt)) && (rslt = mx6(rslt)) &&
(rslt = mx7(rslt));
return rslt;
}
// Match a pattern or not. Always succeeds.
template <prelexer mx>
const char* optional(const char* src) {
const char* p = mx(src);
return p ? p : src;
}
// Match zero or more of the supplied pattern
template <prelexer mx>
const char* zero_plus(const char* src) {
const char* p = mx(src);
while (p) src = p, p = mx(src);
return src;
}
// Match one or more of the supplied pattern
template <prelexer mx>
const char* one_plus(const char* src) {
const char* p = mx(src);
if (!p) return 0;
while (p) src = p, p = mx(src);
return src;
}
// Match a single character satisfying the ctype predicates.
const char* space(const char* src);
const char* alpha(const char* src);
const char* digit(const char* src);
const char* xdigit(const char* src);
const char* alnum(const char* src);
const char* punct(const char* src);
// Match multiple ctype characters.
const char* spaces(const char* src);
const char* alphas(const char* src);
const char* digits(const char* src);
const char* xdigits(const char* src);
const char* alnums(const char* src);
const char* puncts(const char* src);
// Match a line comment.
const char* line_comment(const char* src);
// Match a block comment.
const char* block_comment(const char* src);
// Match either.
const char* comment(const char* src);
// Match double- and single-quoted strings.
const char* double_quoted_string(const char* src);
const char* single_quoted_string(const char* src);
const char* string_constant(const char* src);
// Match interpolants.
const char* interpolant(const char* src);
// Whitespace handling.
const char* optional_spaces(const char* src);
const char* optional_comment(const char* src);
const char* spaces_and_comments(const char* src);
const char* no_spaces(const char* src);
// Match a CSS identifier.
const char* identifier(const char* src);
// Match interpolant schemas
const char* identifier_schema(const char* src);
const char* value_schema(const char* src);
const char* filename(const char* src);
const char* filename_schema(const char* src);
const char* url_schema(const char* src);
const char* url_value(const char* src);
// Match CSS '@' keywords.
const char* at_keyword(const char* src);
const char* import(const char* src);
const char* media(const char* src);
const char* mixin(const char* src);
const char* function(const char* src);
const char* return_directive(const char* src);
const char* include(const char* src);
const char* extend(const char* src);
const char* if_directive(const char* src);
const char* else_directive(const char* src);
const char* elseif_directive(const char* src);
const char* for_directive(const char* src);
const char* from(const char* src);
const char* to(const char* src);
const char* through(const char* src);
const char* each_directive(const char* src);
const char* in(const char* src);
const char* while_directive(const char* src);
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);
const char* universal(const char* src);
// Match CSS id names.
const char* id_name(const char* src);
// Match CSS class names.
const char* class_name(const char* src);
// Match CSS numeric constants.
const char* sign(const char* src);
const char* unsigned_number(const char* src);
const char* number(const char* src);
const char* coefficient(const char* src);
const char* binomial(const char* src);
const char* percentage(const char* src);
const char* dimension(const char* src);
const char* hex(const char* src);
const char* rgb_prefix(const char* src);
// Match CSS uri specifiers.
const char* uri_prefix(const char* src);
const char* uri(const char* src);
const char* url(const char* src);
// Match CSS "!important" keyword.
const char* important(const char* src);
// Match Sass "!default" keyword.
const char* default_flag(const char* src);
// Match CSS pseudo-class/element prefixes
const char* pseudo_prefix(const char* src);
// Match CSS function call openers.
const char* functional(const char* src);
const char* pseudo_not(const char* src);
// Match CSS 'odd' and 'even' keywords for functional pseudo-classes.
const char* even(const char* src);
const char* odd(const char* src);
// Match CSS attribute-matching operators.
const char* exact_match(const char* src);
const char* class_match(const char* src);
const char* dash_match(const char* src);
const char* prefix_match(const char* src);
const char* suffix_match(const char* src);
const char* substring_match(const char* src);
// Match CSS combinators.
const char* adjacent_to(const char* src);
const char* precedes(const char* src);
const char* parent_of(const char* src);
const char* ancestor_of(const char* src);
// Match SCSS variable names.
const char* variable(const char* src);
// Match Sass boolean keywords.
const char* true_val(const char* src);
const char* false_val(const char* src);
const char* and_op(const char* src);
const char* or_op(const char* src);
const char* not_op(const char* src);
const char* eq_op(const char* src);
const char* neq_op(const char* src);
const char* gt_op(const char* src);
const char* gte_op(const char* src);
const char* lt_op(const char* src);
const char* lte_op(const char* src);
// Path matching functions.
const char* folder(const char* src);
const char* folders(const char* src);
// Utility functions for finding and counting characters in a string.
template<char c>
const char* find_first(const char* src) {
while (*src && *src != c) ++src;
return *src ? src : 0;
}
template<prelexer mx>
const char* find_first(const char* src) {
while (*src && !mx(src)) ++src;
return *src ? src : 0;
}
template<prelexer mx>
const char* find_first_in_interval(const char* beg, const char* end) {
while ((beg < end) && *beg) {
if (mx(beg)) return beg;
++beg;
}
return 0;
}
template <char c>
unsigned int count_interval(const char* beg, const char* end) {
unsigned int counter = 0;
while (beg < end && *beg) {
if (*beg == c) ++counter;
++beg;
}
return counter;
}
template <prelexer mx>
unsigned int count_interval(const char* beg, const char* end) {
unsigned int counter = 0;
while (beg < end && *beg) {
const char* p;
if (p = mx(beg)) {
++counter;
beg = p;
}
else {
++beg;
}
}
return counter;
}
}
}
#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;
doc.parse_scss();
expand(doc.root,
Node(),
doc.context.global_env,
doc.context.function_env,
doc.context.new_Node,
doc.context);
// 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);
// 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 << "ERROR -- " << e.path << ", line " << e.line << ": " << e.message << endl;
string msg(msg_stream.str());
char* msg_str = (char*) malloc(msg.size() + 1);
strcpy(msg_str, msg.c_str());
c_ctx->error_status = 1;
c_ctx->output_string = 0;
c_ctx->error_message = msg_str;
}
catch(bad_alloc& ba) {
stringstream msg_stream;
msg_stream << "ERROR -- unable to allocate memory: " << ba.what() << endl;
string msg(msg_stream.str());
char* msg_str = (char*) malloc(msg.size() + 1);
strcpy(msg_str, msg.c_str());
c_ctx->error_status = 1;
c_ctx->output_string = 0;
c_ctx->error_message = msg_str;
}
// TO DO: CATCH EVERYTHING ELSE
return 0;
}
int sass_compile_file(sass_file_context* c_ctx)
{
using namespace Sass;
try {
Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path);
// Document doc(c_ctx->input_path, 0, cpp_ctx);
// string path_string(c_ctx->options.image_path);
// path_string = "'" + path_string + "/";
// cpp_ctx.image_path = c_ctx->options.image_path;
Document doc(Document::make_from_file(cpp_ctx, string(c_ctx->input_path)));
// cerr << "MADE A DOC AND CONTEXT OBJ" << endl;
// cerr << "REGISTRY: " << doc.context.registry.size() << endl;
c_ctx->output_string = process_document(doc, c_ctx->options.output_style);
c_ctx->error_message = 0;
c_ctx->error_status = 0;
}
catch (Error& e) {
stringstream msg_stream;
msg_stream << "ERROR -- " << e.path << ", line " << e.line << ": " << e.message << endl;
string msg(msg_stream.str());
char* msg_str = (char*) malloc(msg.size() + 1);
strcpy(msg_str, msg.c_str());
c_ctx->error_status = 1;
c_ctx->output_string = 0;
c_ctx->error_message = msg_str;
}
catch(bad_alloc& ba) {
stringstream msg_stream;
msg_stream << "ERROR -- unable to allocate memory: " << ba.what() << endl;
string msg(msg_stream.str());
char* msg_str = (char*) malloc(msg.size() + 1);
strcpy(msg_str, msg.c_str());
c_ctx->error_status = 1;
c_ctx->output_string = 0;
c_ctx->error_message = msg_str;
}
// TO DO: CATCH EVERYTHING ELSE
return 0;
}
int sass_compile_folder(sass_folder_context* c_ctx)
{
return 1;
}
}
#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;
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
\ No newline at end of file
#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
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
"main": "./sass.js", "main": "./sass.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/andrew/node-sass.git" "url": "git://github.com/gonghao/node-sass.git"
}, },
"scripts": { "scripts": {
"install": "node rebuild.js" "install": "node rebuild.js"
......
...@@ -13,6 +13,22 @@ try { ...@@ -13,6 +13,22 @@ try {
if (binding === null) { if (binding === null) {
throw new Error('Cannot find appropriate binary library for node-sass'); throw new Error('Cannot find appropriate binary library for node-sass');
} }
var toString = Object.prototype.toString;
exports.render = binding.render SASS_OUTPUT_STYLE = {
nested: 0,
expanded: 1,
compact: 2,
compressed: 3
};
exports.render = function(css, callback, options) {
var paths, style;
if (toString.call(options) !== '[object Object]') {
options = {};
}
paths = options.include_paths || [];
if (!((style = options.output_style) in SASS_OUTPUT_STYLE)) {
style = 'nested';
}
return binding.render(css, callback, paths.join(':'), SASS_OUTPUT_STYLE[style]);
};
exports.middleware = require('./lib/middleware'); exports.middleware = require('./lib/middleware');
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