Skip to content

Commit 9910a86

Browse files
committed
Merge tag 'v2.0' into python
2 parents ff85c66 + e1599c7 commit 9910a86

13 files changed

+337
-30
lines changed

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CXX ?= g++
2-
CXXFLAGS = -Wall -O2 -fPIC -g
2+
CXXFLAGS = -Wall -O2 -fPIC
33
LDFLAGS = -fPIC
44

55
PREFIX = /usr/local
@@ -35,7 +35,8 @@ SOURCES = \
3535
source_map.cpp \
3636
to_c.cpp \
3737
to_string.cpp \
38-
units.cpp
38+
units.cpp \
39+
utf8_string.cpp
3940

4041
OBJECTS = $(SOURCES:.cpp=.o)
4142

context.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ namespace Sass {
4545
: mem(Memory_Manager<AST_Node>()),
4646
source_c_str (initializers.source_c_str()),
4747
sources (vector<const char*>()),
48-
c_functions (vector<Sass_C_Function_Descriptor>()),
4948
include_paths (initializers.include_paths()),
5049
queue (vector<pair<string, const char*> >()),
5150
style_sheets (map<string, Block*>()),
5251
source_map(File::base_name(initializers.output_path())),
52+
c_functions (vector<Sass_C_Function_Descriptor>()),
5353
image_path (initializers.image_path()),
5454
source_comments (initializers.source_comments()),
5555
source_maps (initializers.source_maps()),
@@ -362,6 +362,11 @@ namespace Sass {
362362
register_function(ctx, unquote_sig, sass_unquote, env);
363363
register_function(ctx, quote_sig, sass_quote, env);
364364
register_function(ctx, str_length_sig, str_length, env);
365+
register_function(ctx, str_insert_sig, str_insert, env);
366+
register_function(ctx, str_index_sig, str_index, env);
367+
register_function(ctx, str_slice_sig, str_slice, env);
368+
register_function(ctx, to_upper_case_sig, to_upper_case, env);
369+
register_function(ctx, to_lower_case_sig, to_lower_case, env);
365370
// Number Functions
366371
register_function(ctx, percentage_sig, percentage, env);
367372
register_function(ctx, round_sig, round, env);

expand.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,13 @@ namespace Sass {
141141
return 0;
142142
}
143143

144-
Statement* Expand::operator()(Import* i)
144+
Statement* Expand::operator()(Import* imp)
145145
{
146-
return i; // TODO: eval i->urls()
146+
Import* result = new (ctx.mem) Import(imp->path(), imp->position());
147+
for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
148+
result->urls().push_back(imp->urls()[i]->perform(eval->with(env, backtrace)));
149+
}
150+
return result;
147151
}
148152

149153
Statement* Expand::operator()(Import_Stub* i)

extend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,4 @@ namespace Sass {
310310
return results;
311311
}
312312

313-
}
313+
}

functions.cpp

Lines changed: 120 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "to_string.hpp"
88
#include "inspect.hpp"
99
#include "eval.hpp"
10+
#include "utf8_string.hpp"
1011

1112
#include <cmath>
1213
#include <cctype>
@@ -695,7 +696,6 @@ namespace Sass {
695696
{
696697
String_Constant* s = ARG("$string", String_Constant);
697698
string str = s->value();
698-
size_t len = 0;
699699
size_t length_of_s = str.size();
700700
size_t i = 0;
701701

@@ -704,27 +704,128 @@ namespace Sass {
704704
--length_of_s;
705705
}
706706

707-
while (i < length_of_s) {
708-
unsigned char c = static_cast<unsigned char>(str[i]);
709-
if (c < 128) {
710-
// it's a single-byte character
711-
++len;
712-
++i;
713-
}
714-
// it's a multi bit sequence and presumably it's a leading bit
715-
else {
716-
++i; // go to the next byte
717-
// see if it's still part of the sequence
718-
while ((i < length_of_s) && ((static_cast<unsigned char>(str[i]) & 0b11000000) == 0b10000000)) {
719-
++i;
720-
}
721-
// when it's not [aka a new leading bit], increment and move on
722-
++len;
723-
}
724-
}
707+
size_t len = UTF_8::code_point_count(str, i, length_of_s);
708+
725709
return new (ctx.mem) Number(path, position, len);
726710
}
727711

712+
Signature str_insert_sig = "str-insert($string, $insert, $index)";
713+
BUILT_IN(str_insert)
714+
{
715+
String_Constant* s = ARG("$string", String_Constant);
716+
string str = s->value();
717+
char quotemark = s->quote_mark();
718+
str = unquote(str);
719+
String_Constant* i = ARG("$insert", String_Constant);
720+
string ins = i->value();
721+
ins = unquote(ins);
722+
Number* ind = ARG("$index", Number);
723+
double index = ind->value();
724+
size_t len = UTF_8::code_point_count(str, 0, str.size());
725+
726+
if (index > 0 && index <= len) {
727+
// positive and within string length
728+
str.insert(UTF_8::code_point_offset_to_byte_offset(str, index-1), ins);
729+
}
730+
else if (index > len) {
731+
// positive and past string length
732+
str += ins;
733+
}
734+
else if (index == 0) {
735+
str = ins + str;
736+
}
737+
else if (std::abs(index) <= len) {
738+
// negative and within string length
739+
index += len + 1;
740+
str.insert(UTF_8::code_point_offset_to_byte_offset(str, index), ins);
741+
}
742+
else {
743+
// negative and past string length
744+
str = ins + str;
745+
}
746+
747+
if (quotemark) {
748+
str = quote(str, quotemark);
749+
}
750+
751+
return new (ctx.mem) String_Constant(path, position, str);
752+
753+
}
754+
755+
Signature str_index_sig = "str-index($string, $substring)";
756+
BUILT_IN(str_index)
757+
{
758+
String_Constant* s = ARG("$string", String_Constant);
759+
String_Constant* t = ARG("$substring", String_Constant);
760+
string str = s->value();
761+
str = unquote(str);
762+
string substr = t->value();
763+
substr = unquote(substr);
764+
765+
size_t c_index = str.find(substr);
766+
if(c_index == string::npos) {
767+
return new (ctx.mem) Null(path, position);
768+
}
769+
size_t index = UTF_8::code_point_count(str, 0, c_index + 1);
770+
771+
return new (ctx.mem) Number(path, position, index);
772+
}
773+
774+
Signature str_slice_sig = "str-slice($string, $start-at, $end-at:-1)";
775+
BUILT_IN(str_slice)
776+
{
777+
String_Constant* s = ARG("$string", String_Constant);
778+
Number* n = ARG("$start-at", Number);
779+
Number* m = ARG("$end-at", Number);
780+
781+
string str = s->value();
782+
char quotemark = s->quote_mark();
783+
str = unquote(str);
784+
785+
// normalize into 0-based indices
786+
size_t start = UTF_8::code_point_offset_to_byte_offset(str, UTF_8::normalize_index(n->value(), UTF_8::code_point_count(str)));
787+
size_t end = UTF_8::code_point_offset_to_byte_offset(str, UTF_8::normalize_index(m->value(), UTF_8::code_point_count(str)));
788+
789+
string newstr;
790+
if(start - end == 0) {
791+
newstr = str.substr(start, end - start);
792+
} else {
793+
newstr = str.substr(start, end - start + UTF_8::length_of_code_point_at(str, end));
794+
}
795+
if(quotemark) {
796+
newstr = quote(newstr, quotemark);
797+
}
798+
799+
return new (ctx.mem) String_Constant(path, position, newstr);
800+
801+
}
802+
803+
Signature to_upper_case_sig = "to-upper-case($string)";
804+
BUILT_IN(to_upper_case)
805+
{
806+
String_Constant* s = ARG("$string", String_Constant);
807+
string str = s->value();
808+
809+
for (size_t i = 0, L = str.length(); i < L; ++i) {
810+
str[i] = std::toupper(str[i]);
811+
}
812+
813+
return new (ctx.mem) String_Constant(path, position, str);
814+
}
815+
816+
Signature to_lower_case_sig = "to-lower-case($string)";
817+
BUILT_IN(to_lower_case)
818+
{
819+
String_Constant* s = ARG("$string", String_Constant);
820+
string str = s->value();
821+
822+
for (size_t i = 0, L = str.length(); i < L; ++i) {
823+
str[i] = std::tolower(str[i]);
824+
}
825+
826+
return new (ctx.mem) String_Constant(path, position, str);
827+
}
828+
728829
///////////////////
729830
// NUMBER FUNCTIONS
730831
///////////////////

functions.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ namespace Sass {
6565
extern Signature unquote_sig;
6666
extern Signature quote_sig;
6767
extern Signature str_length_sig;
68+
extern Signature str_insert_sig;
69+
extern Signature str_index_sig;
70+
extern Signature str_slice_sig;
71+
extern Signature to_upper_case_sig;
72+
extern Signature to_lower_case_sig;
6873
extern Signature percentage_sig;
6974
extern Signature round_sig;
7075
extern Signature ceil_sig;
@@ -117,6 +122,11 @@ namespace Sass {
117122
BUILT_IN(sass_unquote);
118123
BUILT_IN(sass_quote);
119124
BUILT_IN(str_length);
125+
BUILT_IN(str_insert);
126+
BUILT_IN(str_index);
127+
BUILT_IN(str_slice);
128+
BUILT_IN(to_upper_case);
129+
BUILT_IN(to_lower_case);
120130
BUILT_IN(percentage);
121131
BUILT_IN(round);
122132
BUILT_IN(ceil);

output_compressed.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "inspect.hpp"
33
#include "ast.hpp"
44
#include "context.hpp"
5+
#include "to_string.hpp"
56

67
namespace Sass {
78
using namespace std;
@@ -183,7 +184,16 @@ namespace Sass {
183184

184185
void Output_Compressed::operator()(Comment* c)
185186
{
186-
return;
187+
To_String to_string;
188+
string txt = c->text()->perform(&to_string);
189+
if(txt[2] != '!') {
190+
return;
191+
}
192+
else {
193+
Inspect i(ctx);
194+
c->perform(&i);
195+
buffer += i.get_buffer();
196+
}
187197
}
188198

189199
void Output_Compressed::operator()(List* list)

parser.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,14 +411,26 @@ namespace Sass {
411411
Compound_Selector* Parser::parse_simple_selector_sequence()
412412
{
413413
Compound_Selector* seq = new (ctx.mem) Compound_Selector(path, source_position);
414-
// check for backref or type selector, which are only allowed at the front
414+
bool sawsomething = false;
415415
if (lex< exactly<'&'> >()) {
416+
// if you see a &
416417
(*seq) << new (ctx.mem) Selector_Reference(path, source_position);
418+
sawsomething = true;
419+
// if you see a space after a &, then you're done
420+
if(lex< spaces >()) {
421+
return seq;
422+
}
417423
}
418-
else if (lex< sequence< negate< functional >, alternatives< type_selector, universal, string_constant, dimension, percentage, number > > >()) {
424+
if (sawsomething && lex< sequence< negate< functional >, alternatives< hyphens_and_identifier, universal, string_constant, dimension, percentage, number > > >()) {
425+
// saw an ampersand, then allow type selectors with arbitrary number of hyphens at the beginning
426+
(*seq) << new (ctx.mem) Type_Selector(path, source_position, lexed);
427+
} else if (lex< sequence< negate< functional >, alternatives< type_selector, universal, string_constant, dimension, percentage, number > > >()) {
428+
// if you see a type selector
419429
(*seq) << new (ctx.mem) Type_Selector(path, source_position, lexed);
430+
sawsomething = true;
420431
}
421-
else {
432+
if (!sawsomething) {
433+
// don't blindly do this if you saw a & or selector
422434
(*seq) << parse_simple_selector();
423435
}
424436

@@ -1475,6 +1487,7 @@ namespace Sass {
14751487
bool saw_interpolant = false;
14761488

14771489
while ((q = peek< identifier >(p)) ||
1490+
(q = peek< hyphens_and_identifier >(p)) ||
14781491
(q = peek< type_selector >(p)) ||
14791492
(q = peek< id_name >(p)) ||
14801493
(q = peek< class_name >(p)) ||

prelexer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ namespace Sass {
245245
const char* type_selector(const char* src) {
246246
return sequence< optional<namespace_prefix>, identifier>(src);
247247
}
248+
const char* hyphens_and_identifier(const char* src) {
249+
return sequence< zero_plus< exactly< '-' > >, identifier >(src);
250+
}
248251
const char* universal(const char* src) {
249252
return sequence< optional<namespace_prefix>, exactly<'*'> >(src);
250253
}

prelexer.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ namespace Sass {
369369
// Match CSS type selectors
370370
const char* namespace_prefix(const char* src);
371371
const char* type_selector(const char* src);
372+
const char* hyphens_and_identifier(const char* src);
372373
const char* universal(const char* src);
373374
// Match CSS id names.
374375
const char* id_name(const char* src);

subset_map.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,4 @@ namespace Sass {
141141
return results;
142142
}
143143

144-
}
144+
}

0 commit comments

Comments
 (0)