Skip to content

Commit e974ddd

Browse files
committed
Merge pull request #1330 from mgreter/refactoring/parser-for-3.3-B
Additional fixes for 3.3 release
2 parents d94ca1f + cb34953 commit e974ddd

22 files changed

+157
-83
lines changed

ast.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -911,21 +911,38 @@ namespace Sass {
911911
}
912912
}
913913

914-
/* not used anymore - remove?
915-
vector<Compound_Selector*> Complex_Selector::to_vector()
914+
void Arguments::adjust_after_pushing(Argument* a)
916915
{
917-
vector<Compound_Selector*> result;
918-
Compound_Selector* h = head();
919-
Complex_Selector* t = tail();
920-
if (h) result.push_back(h);
921-
while (t)
922-
{
923-
h = t->head();
924-
t = t->tail();
925-
if (h) result.push_back(h);
916+
if (!a->name().empty()) {
917+
if (/* has_rest_argument_ || */ has_keyword_argument_) {
918+
error("named arguments must precede variable-length argument", a->pstate());
919+
}
920+
has_named_arguments_ = true;
926921
}
927-
return result;
928-
}*/
922+
else if (a->is_rest_argument()) {
923+
if (has_rest_argument_) {
924+
error("functions and mixins may only be called with one variable-length argument", a->pstate());
925+
}
926+
if (has_keyword_argument_) {
927+
error("only keyword arguments may follow variable arguments", a->pstate());
928+
}
929+
has_rest_argument_ = true;
930+
}
931+
else if (a->is_keyword_argument()) {
932+
if (has_keyword_argument_) {
933+
error("functions and mixins may only be called with one keyword argument", a->pstate());
934+
}
935+
has_keyword_argument_ = true;
936+
}
937+
else {
938+
if (has_rest_argument_) {
939+
error("ordinal arguments must precede variable-length arguments", a->pstate());
940+
}
941+
if (has_named_arguments_) {
942+
error("ordinal arguments must precede named arguments", a->pstate());
943+
}
944+
}
945+
}
929946

930947
Number::Number(ParserState pstate, double val, string u, bool zero)
931948
: Expression(pstate),

ast.hpp

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,38 +1015,7 @@ namespace Sass {
10151015
ADD_PROPERTY(bool, has_rest_argument)
10161016
ADD_PROPERTY(bool, has_keyword_argument)
10171017
protected:
1018-
void adjust_after_pushing(Argument* a)
1019-
{
1020-
if (!a->name().empty()) {
1021-
if (has_rest_argument_ || has_keyword_argument_) {
1022-
error("named arguments must precede variable-length argument", a->pstate());
1023-
}
1024-
has_named_arguments_ = true;
1025-
}
1026-
else if (a->is_rest_argument()) {
1027-
if (has_rest_argument_) {
1028-
error("functions and mixins may only be called with one variable-length argument", a->pstate());
1029-
}
1030-
if (has_keyword_argument_) {
1031-
error("only keyword arguments may follow variable arguments", a->pstate());
1032-
}
1033-
has_rest_argument_ = true;
1034-
}
1035-
else if (a->is_keyword_argument()) {
1036-
if (has_keyword_argument_) {
1037-
error("functions and mixins may only be called with one keyword argument", a->pstate());
1038-
}
1039-
has_keyword_argument_ = true;
1040-
}
1041-
else {
1042-
if (has_rest_argument_) {
1043-
error("ordinal arguments must precede variable-length arguments", a->pstate());
1044-
}
1045-
if (has_named_arguments_) {
1046-
error("ordinal arguments must precede named arguments", a->pstate());
1047-
}
1048-
}
1049-
}
1018+
void adjust_after_pushing(Argument* a);
10501019
public:
10511020
Arguments(ParserState pstate)
10521021
: Expression(pstate),
@@ -2010,11 +1979,12 @@ namespace Sass {
20101979
////////////////////////////////////////////////////////////////////////////
20111980
class Complex_Selector : public Selector {
20121981
public:
2013-
enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO };
1982+
enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO, REFERENCE };
20141983
private:
20151984
ADD_PROPERTY(Combinator, combinator)
20161985
ADD_PROPERTY(Compound_Selector*, head)
20171986
ADD_PROPERTY(Complex_Selector*, tail)
1987+
ADD_PROPERTY(String*, reference);
20181988
public:
20191989
bool contains_placeholder() {
20201990
if (head() && head()->contains_placeholder()) return true;
@@ -2025,7 +1995,7 @@ namespace Sass {
20251995
Combinator c = ANCESTOR_OF,
20261996
Compound_Selector* h = 0,
20271997
Complex_Selector* t = 0)
2028-
: Selector(pstate), combinator_(c), head_(h), tail_(t)
1998+
: Selector(pstate), combinator_(c), head_(h), tail_(t), reference_(0)
20291999
{
20302000
if ((h && h->has_reference()) || (t && t->has_reference())) has_reference(true);
20312001
if ((h && h->has_placeholder()) || (t && t->has_placeholder())) has_placeholder(true);

bind.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@ namespace Sass {
121121
while (ia < LA) {
122122
// get and post inc
123123
a = (*as)[ia++];
124-
// wrap current argument into new object
124+
// maybe we have another list as argument
125+
List* ls = dynamic_cast<List*>(a->value());
126+
// skip any list completely if empty
127+
if (ls && ls->empty()) continue;
128+
// check if we have rest argument
125129
(*arglist) << new (ctx.mem) Argument(a->pstate(),
126130
a->value(),
127131
a->name(),

configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@ AC_CONFIG_AUX_DIR([script])
1313
# Though they look like gcc flags!
1414
AM_INIT_AUTOMAKE([foreign parallel-tests -Wall])
1515
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])])
16+
# would fail with mingw otherwise
17+
m4_pattern_allow([AM_PROG_AR])
1618

1719
# Checks for programs.
1820
AC_PROG_CXX
1921
AC_LANG([C++])
22+
AM_PROG_AR([])
2023
LT_INIT([dlopen])
2124

2225
# Checks for header files.

context.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ namespace Sass {
5858
c_options (initializers.c_options()),
5959
c_compiler (initializers.c_compiler()),
6060
source_c_str (initializers.source_c_str()),
61-
sources (vector<const char*>()),
61+
sources (vector<char*>()),
62+
strings (vector<char*>()),
6263
plugin_paths (initializers.plugin_paths()),
6364
include_paths (initializers.include_paths()),
6465
queue (vector<Sass_Queued>()),
@@ -148,12 +149,16 @@ namespace Sass {
148149

149150
Context::~Context()
150151
{
151-
// everything that gets put into sources will be freed by us
152-
for (size_t n = 0; n < import_stack.size(); ++n) sass_delete_import(import_stack[n]);
152+
// make sure we free the source even if not processed!
153+
if (sources.size() == 0 && source_c_str) free(source_c_str);
153154
// sources are allocated by strdup or malloc (overtaken from C code)
154-
for (size_t i = 0; i < sources.size(); ++i) free((void*)sources[i]);
155-
// clear inner structures (vectors)
156-
sources.clear(); import_stack.clear();
155+
for (size_t i = 0; i < sources.size(); ++i) free(sources[i]);
156+
// free all strings we kept alive during compiler execution
157+
for (size_t n = 0; n < strings.size(); ++n) free(strings[n]);
158+
// everything that gets put into sources will be freed by us
159+
for (size_t m = 0; m < import_stack.size(); ++m) sass_delete_import(import_stack[m]);
160+
// clear inner structures (vectors) and input source
161+
sources.clear(); import_stack.clear(); source_c_str = 0;
157162
}
158163

159164
void Context::setup_color_map()
@@ -245,7 +250,7 @@ namespace Sass {
245250
}
246251
}
247252
}
248-
void Context::add_source(string load_path, string abs_path, const char* contents)
253+
void Context::add_source(string load_path, string abs_path, char* contents)
249254
{
250255
sources.push_back(contents);
251256
included_files.push_back(abs_path);
@@ -317,8 +322,10 @@ namespace Sass {
317322
0, 0
318323
);
319324
import_stack.push_back(import);
320-
const char* path = sass_strdup(queue[i].abs_path.c_str());
321-
Parser p(Parser::from_c_str(queue[i].source, *this, ParserState(path, queue[i].source, i)));
325+
// keep a copy of the path around (for parser states)
326+
strings.push_back(sass_strdup(queue[i].abs_path.c_str()));
327+
ParserState pstate(strings.back(), queue[i].source, i);
328+
Parser p(Parser::from_c_str(queue[i].source, *this, pstate));
322329
Block* ast = p.parse();
323330
sass_delete_import(import_stack.back());
324331
import_stack.pop_back();
@@ -369,7 +376,7 @@ namespace Sass {
369376
if(is_indented_syntax_src) {
370377
char * contents = sass2scss(source_c_str, SASS2SCSS_PRETTIFY_1 | SASS2SCSS_KEEP_COMMENT);
371378
add_source(input_path, input_path, contents);
372-
delete [] source_c_str;
379+
free(source_c_str);
373380
return parse_file();
374381
}
375382
add_source(input_path, input_path, source_c_str);

context.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ namespace Sass {
3737

3838
struct Sass_Options* c_options;
3939
struct Sass_Compiler* c_compiler;
40-
const char* source_c_str;
40+
char* source_c_str;
4141

4242
// c-strs containing Sass file contents
4343
// we will overtake ownership of memory
44-
vector<const char*> sources;
44+
vector<char*> sources;
45+
// strings get freed with context
46+
vector<char*> strings;
4547
// absolute paths to includes
4648
vector<string> included_files;
4749
// relative links to includes
@@ -87,7 +89,7 @@ namespace Sass {
8789
KWD_ARG_SET(Data) {
8890
KWD_ARG(Data, struct Sass_Options*, c_options)
8991
KWD_ARG(Data, struct Sass_Compiler*, c_compiler)
90-
KWD_ARG(Data, const char*, source_c_str)
92+
KWD_ARG(Data, char*, source_c_str)
9193
KWD_ARG(Data, string, entry_point)
9294
KWD_ARG(Data, string, input_path)
9395
KWD_ARG(Data, string, output_path)
@@ -117,7 +119,7 @@ namespace Sass {
117119

118120
Block* parse_file();
119121
Block* parse_string();
120-
void add_source(string, string, const char*);
122+
void add_source(string, string, char*);
121123

122124
string add_file(const string& file);
123125
string add_file(const string& base, const string& file);

debugger.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
123123
case Complex_Selector::PRECEDES: del = "~"; break;
124124
case Complex_Selector::ADJACENT_TO: del = "+"; break;
125125
case Complex_Selector::ANCESTOR_OF: del = " "; break;
126+
case Complex_Selector::REFERENCE: del = "//"; break;
126127
}
128+
// if (del = "/") del += selector->reference()->perform(&to_string) + "/";
127129
cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
128130
debug_ast(selector->head(), ind + " " /* + "[" + del + "]" */, env);
129131
if (selector->tail()) {

eval.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,11 @@ namespace Sass {
890890
} else if (dynamic_cast<Unary_Expression*>(s)) {
891891
Expression* ex = s->perform(this);
892892
return evacuate_quotes(interpolation(ex));
893+
} else if (dynamic_cast<Map*>(s)) {
894+
To_String to_string(&ctx);
895+
string dbg(s->perform(&to_string));
896+
error(dbg + " isn't a valid CSS value.", s->pstate());
897+
return dbg;
893898
} else {
894899
To_String to_string(&ctx);
895900
return evacuate_quotes(s->perform(&to_string));
@@ -1397,8 +1402,11 @@ namespace Sass {
13971402
bool parentized = false;
13981403
Complex_Selector* tail = s->tail();
13991404
Compound_Selector* head = s->head();
1405+
String* reference = s->reference();
14001406
Complex_Selector::Combinator combinator = s->combinator();
14011407
Selector_List* sl = new (ctx.mem) Selector_List(s->pstate());
1408+
if (reference) reference = (String*) reference->perform(this);
1409+
14021410
if (head) {
14031411
// check if we have a parent selector reference (expands to list)
14041412
if (head->length() > 1 && dynamic_cast<Parent_Selector*>((*head)[0])) {
@@ -1413,6 +1421,7 @@ namespace Sass {
14131421
for (size_t i = 1, L = head->length(); i < L; ++i) *lst_h << (*head)[i];
14141422
lst_t->tail(tail); // now connect old tail back to new intermediate
14151423
lst_t->combinator(combinator); // and dont forget the combinator
1424+
lst_t->reference(reference);
14161425
// if (s->has_line_feed()) lst_t->has_line_feed(true); // and dont forget the combinator
14171426
}
14181427
return ns;
@@ -1445,6 +1454,7 @@ namespace Sass {
14451454
lst->tail(ins);
14461455
} else {
14471456
lst->combinator(combinator);
1457+
lst->reference(reference);
14481458
}
14491459
}
14501460
if (s->has_line_feed()) (*ns)[n]->has_line_feed(true);

extend.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ namespace Sass {
7676
case Complex_Selector::PARENT_OF: os << "\">\""; break;
7777
case Complex_Selector::PRECEDES: os << "\"~\""; break;
7878
case Complex_Selector::ADJACENT_TO: os << "\"+\""; break;
79+
case Complex_Selector::REFERENCE: os << "\"/\""; break;
7980
}
8081

8182
return os;

functions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ namespace Sass {
210210

211211
inline double color_num(Number* n) {
212212
if (n->unit() == "%") {
213-
return std::min(std::max(n->value(), 0.0), 1.0) * 255;
213+
return std::min(std::max(n->value(), 0.0), 100.0) * 2.55;
214214
} else {
215215
return std::min(std::max(n->value(), 0.0), 255.0);
216216
}

0 commit comments

Comments
 (0)