Skip to content

Commit 3a0e9d2

Browse files
committed
Improve compiler compatibility for early gcc versions
1 parent e45cd20 commit 3a0e9d2

File tree

9 files changed

+113
-49
lines changed

9 files changed

+113
-49
lines changed

src/ast.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,27 +47,23 @@ namespace Sass {
4747
return &lhs && &rhs && *lhs == *rhs;
4848
}
4949

50-
std::string & str_ltrim(std::string & str)
50+
void str_rtrim(std::string& s, const std::string& delimiters = " \f\n\r\t\v" )
5151
{
52-
auto it2 = std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
53-
str.erase( str.begin() , it2);
54-
return str;
52+
s.erase( s.find_last_not_of( delimiters ) + 1 );
5553
}
5654

57-
std::string & str_rtrim(std::string & str)
55+
void str_ltrim(std::string& s, const std::string& delimiters = " \f\n\r\t\v" )
5856
{
59-
auto it1 = std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
60-
str.erase( it1.base() , str.end() );
61-
return str;
57+
s.erase( 0, s.find_first_not_of( delimiters ) );
6258
}
6359

6460
void String_Constant::rtrim()
6561
{
66-
value_ = str_rtrim(value_);
62+
str_rtrim(value_);
6763
}
6864
void String_Constant::ltrim()
6965
{
70-
value_ = str_ltrim(value_);
66+
str_ltrim(value_);
7167
}
7268
void String_Constant::trim()
7369
{
@@ -175,15 +171,15 @@ namespace Sass {
175171

176172
bool Compound_Selector::has_parent_ref()
177173
{
178-
for (Simple_Selector_Obj s : *this) {
174+
for (Simple_Selector_Obj s : elements()) {
179175
if (s && s->has_parent_ref()) return true;
180176
}
181177
return false;
182178
}
183179

184180
bool Compound_Selector::has_real_parent_ref()
185181
{
186-
for (Simple_Selector_Obj s : *this) {
182+
for (Simple_Selector_Obj s : elements()) {
187183
if (s && s->has_real_parent_ref()) return true;
188184
}
189185
return false;

src/ast.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ namespace Sass {
344344
virtual void adjust_after_pushing(std::pair<Expression_Obj, Expression_Obj> p) { }
345345
public:
346346
Hashed(size_t s = 0) : elements_(ExpressionMap(s)), list_(std::vector<Expression_Obj>())
347-
{ elements_.reserve(s); list_.reserve(s); reset_duplicate_key(); }
347+
{ list_.reserve(s); reset_duplicate_key(); }
348348
virtual ~Hashed();
349349
size_t length() const { return list_.size(); }
350350
bool empty() const { return list_.empty(); }
@@ -1464,7 +1464,7 @@ namespace Sass {
14641464
if (hash_ == 0) {
14651465
hash_ = std::hash<std::string>()(name());
14661466
for (auto argument : arguments()->elements())
1467-
hash_combine(hash_, argument->hash());
1467+
{ hash_combine(hash_, argument->hash()); }
14681468
}
14691469
return hash_;
14701470
}
@@ -1619,9 +1619,9 @@ namespace Sass {
16191619
if (hash_ == 0) {
16201620
hash_ = std::hash<double>()(value_);
16211621
for (const auto numerator : numerator_units())
1622-
hash_combine(hash_, std::hash<std::string>()(numerator));
1622+
{ hash_combine(hash_, std::hash<std::string>()(numerator)); }
16231623
for (const auto denominator : denominator_units())
1624-
hash_combine(hash_, std::hash<std::string>()(denominator));
1624+
{ hash_combine(hash_, std::hash<std::string>()(denominator)); }
16251625
}
16261626
return hash_;
16271627
}
@@ -1809,7 +1809,7 @@ namespace Sass {
18091809
{
18101810
if (hash_ == 0) {
18111811
for (auto string : elements())
1812-
hash_combine(hash_, string->hash());
1812+
{ hash_combine(hash_, string->hash()); }
18131813
}
18141814
return hash_;
18151815
}

src/context.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ namespace Sass {
9898
collect_plugin_paths(c_options.plugin_paths);
9999

100100
// load plugins and register custom behaviors
101-
for(auto plug : plugin_paths) plugins.load_plugins(plug);
102-
for(auto fn : plugins.get_headers()) c_headers.push_back(fn);
103-
for(auto fn : plugins.get_importers()) c_importers.push_back(fn);
104-
for(auto fn : plugins.get_functions()) c_functions.push_back(fn);
101+
for(auto plug : plugin_paths) { plugins.load_plugins(plug); }
102+
for(auto fn : plugins.get_headers()) { c_headers.push_back(fn); }
103+
for(auto fn : plugins.get_importers()) { c_importers.push_back(fn); }
104+
for(auto fn : plugins.get_functions()) { c_functions.push_back(fn); }
105105

106106
// sort the items by priority (lowest first)
107107
sort (c_headers.begin(), c_headers.end(), sort_importers);

src/eval.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -335,15 +335,16 @@ namespace Sass {
335335
// try to use generic function
336336
if (env->has("@warn[f]")) {
337337

338-
// add call stack entry
339-
ctx.callee_stack.push_back({
338+
struct Sass_Callee callee = {
340339
"@warn",
341340
w->pstate().path,
342341
w->pstate().line + 1,
343342
w->pstate().column + 1,
344343
SASS_CALLEE_FUNCTION,
345344
{ env }
346-
});
345+
};
346+
// add call stack entry
347+
ctx.callee_stack.push_back(callee);
347348

348349
Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)["@warn[f]"]);
349350
// Block_Obj body = def->block();
@@ -382,15 +383,16 @@ namespace Sass {
382383
// try to use generic function
383384
if (env->has("@error[f]")) {
384385

385-
// add call stack entry
386-
ctx.callee_stack.push_back({
386+
struct Sass_Callee callee = {
387387
"@error",
388388
e->pstate().path,
389389
e->pstate().line + 1,
390390
e->pstate().column + 1,
391391
SASS_CALLEE_FUNCTION,
392392
{ env }
393-
});
393+
};
394+
// add call stack entry
395+
ctx.callee_stack.push_back(callee);
394396

395397
Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)["@error[f]"]);
396398
// Block_Obj body = def->block();
@@ -426,15 +428,16 @@ namespace Sass {
426428
// try to use generic function
427429
if (env->has("@debug[f]")) {
428430

429-
// add call stack entry
430-
ctx.callee_stack.push_back({
431+
struct Sass_Callee callee = {
431432
"@debug",
432433
d->pstate().path,
433434
d->pstate().line + 1,
434435
d->pstate().column + 1,
435436
SASS_CALLEE_FUNCTION,
436437
{ env }
437-
});
438+
};
439+
// add call stack entry
440+
ctx.callee_stack.push_back(callee);
438441

439442
Definition_Ptr def = SASS_MEMORY_CAST(Definition, (*env)["@debug[f]"]);
440443
// Block_Obj body = def->block();
@@ -908,14 +911,15 @@ namespace Sass {
908911
bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
909912
Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
910913
exp.backtrace_stack.push_back(&here);
911-
ctx.callee_stack.push_back({
914+
struct Sass_Callee callee = {
912915
c->name().c_str(),
913916
c->pstate().path,
914917
c->pstate().line + 1,
915918
c->pstate().column + 1,
916919
SASS_CALLEE_FUNCTION,
917920
{ env }
918-
});
921+
};
922+
ctx.callee_stack.push_back(callee);
919923

920924
// eval the body if user-defined or special, invoke underlying CPP function if native
921925
if (body /* && !Prelexer::re_special_fun(name.c_str()) */) {
@@ -949,14 +953,15 @@ namespace Sass {
949953

950954
Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
951955
exp.backtrace_stack.push_back(&here);
952-
ctx.callee_stack.push_back({
956+
struct Sass_Callee callee = {
953957
c->name().c_str(),
954958
c->pstate().path,
955959
c->pstate().line + 1,
956960
c->pstate().column + 1,
957961
SASS_CALLEE_C_FUNCTION,
958962
{ env }
959-
});
963+
};
964+
ctx.callee_stack.push_back(callee);
960965

961966
To_C to_c;
962967
union Sass_Value* c_args = sass_make_list(params->length(), SASS_COMMA, false);
@@ -1160,7 +1165,7 @@ namespace Sass {
11601165
List_Obj ll = SASS_MEMORY_NEW(List, l->pstate(), 0, l->separator());
11611166
// this fixes an issue with bourbon sample, not really sure why
11621167
// if (l->size() && dynamic_cast<Null_Ptr>((*l)[0])) { res += ""; }
1163-
for(Expression_Obj item : *l) {
1168+
for(Expression_Obj item : l->elements()) {
11641169
item->is_interpolant(l->is_interpolant());
11651170
std::string rl(""); interpolation(ctx, rl, &item, into_quotes, l->is_interpolant());
11661171
bool is_null = dynamic_cast<Null_Ptr>(&item) != 0; // rl != ""

src/expand.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,14 +708,15 @@ namespace Sass {
708708
Arguments_Obj args = SASS_MEMORY_CAST(Arguments, rv);
709709
Backtrace new_bt(backtrace(), c->pstate(), ", in mixin `" + c->name() + "`");
710710
backtrace_stack.push_back(&new_bt);
711-
ctx.callee_stack.push_back({
711+
struct Sass_Callee callee = {
712712
c->name().c_str(),
713713
c->pstate().path,
714714
c->pstate().line + 1,
715715
c->pstate().column + 1,
716716
SASS_CALLEE_MIXIN,
717717
{ env }
718-
});
718+
};
719+
ctx.callee_stack.push_back(callee);
719720

720721
Env new_env(def->environment());
721722
env_stack.push_back(&new_env);

src/extend.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,7 +1948,7 @@ namespace Sass {
19481948
recseen.insert(*cur->head());
19491949
// create a copy since we add multiple items if stuff get unwrapped
19501950
Compound_Selector_Obj cpy_head = SASS_MEMORY_NEW(Compound_Selector, cur->pstate());
1951-
for (Simple_Selector_Obj hs : *cur->head()) {
1951+
for (Simple_Selector_Obj hs : cur->head()->elements()) {
19521952
if (Wrapped_Selector_Obj ws = SASS_MEMORY_CAST(Wrapped_Selector, hs)) {
19531953
ws->selector(SASS_MEMORY_CLONE(ws->selector()));
19541954
if (Selector_List_Obj sl = SASS_MEMORY_CAST(Selector_List, ws->selector())) {
@@ -2079,7 +2079,8 @@ namespace Sass {
20792079
// we set `extended` flag on extended selectors
20802080
if (b->is_root()) {
20812081
// debug_subset_map(subset_map);
2082-
for(auto const &it : subset_map.values()) {
2082+
auto values = subset_map.values();
2083+
for(auto it : values) {
20832084
Complex_Selector_Ptr sel = it.first ? &it.first->first() : NULL;
20842085
Compound_Selector_Ptr ext = it.second ? &it.second : NULL;
20852086
if (ext && (ext->extended() || ext->is_optional())) continue;

src/functions.cpp

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,24 @@
3030
#include "wincrypt.h"
3131
#endif
3232

33+
#if defined __GNUC__ && ! defined __llvm__
34+
#define GCC_VERSION (__GNUC__ * 10000 \
35+
+ __GNUC_MINOR__ * 100 \
36+
+ __GNUC_PATCHLEVEL__)
37+
#if GCC_VERSION < 40500
38+
#include <tr1/random>
39+
#define IMPLEMENT_TR1
40+
#define tr1ns std::tr1
41+
#define uniform_real_distribution uniform_real
42+
#else
43+
#include <random>
44+
#define tr1ns std
45+
#endif
46+
#else
47+
#include <random>
48+
#define tr1ns std
49+
#endif
50+
3351
#define ARG(argname, argtype) get_arg<argtype>(argname, env, sig, pstate, backtrace)
3452
#define ARGR(argname, argtype, lo, hi) get_arg_r(argname, env, sig, pstate, lo, hi, backtrace)
3553
#define ARGM(argname, argtype, ctx) get_arg_m(argname, env, sig, pstate, backtrace, ctx)
@@ -212,9 +230,43 @@ namespace Sass {
212230
// random_device degrades sharply once the entropy pool
213231
// is exhausted. For practical use, random_device is
214232
// generally only used to seed a PRNG such as mt19937.
215-
static std::mt19937 rand(static_cast<unsigned int>(GetSeed()));
233+
static tr1ns::mt19937 rand(static_cast<unsigned int>(GetSeed()));
234+
235+
tr1ns::uniform_real_distribution<> std_dist(0, 1);
236+
#ifdef IMPLEMENT_TR1
237+
tr1ns::variate_generator <
238+
tr1ns::mt19937,
239+
tr1ns::uniform_real_distribution <double>
240+
> gen_std_dist(rand, std_dist);
241+
#endif
242+
243+
// Using ULONG_MAX here seems to fail on Mac OSX Clang!?
244+
tr1ns::uniform_real_distribution<> full_dist(0, 4294967296);
245+
#ifdef IMPLEMENT_TR1
246+
tr1ns::variate_generator <
247+
tr1ns::mt19937,
248+
tr1ns::uniform_real_distribution <double>
249+
> gen_full_dist(rand, full_dist);
250+
#endif
251+
252+
// helper function to retrieve a random number in interval
253+
// works around some compiler issues with older gcc versions
254+
static double random(double min, double max)
255+
{
256+
tr1ns::uniform_real_distribution<> distributor(min, max);
257+
#ifdef IMPLEMENT_TR1
258+
tr1ns::variate_generator <
259+
tr1ns::mt19937,
260+
tr1ns::uniform_real_distribution <>
261+
> gen(rand, distributor);
262+
distributor(rand);
263+
return gen();
264+
#else
265+
return distributor(rand);
266+
#endif
267+
}
216268

217-
// features
269+
// supported features lookup table
218270
static std::set<std::string> features {
219271
"global-variable-shadowing",
220272
"extend-selector-pseudoclass",
@@ -1199,13 +1251,19 @@ namespace Sass {
11991251
err << "Expected $limit to be an integer but got " << v << " for `random'";
12001252
error(err.str(), pstate);
12011253
}
1202-
std::uniform_real_distribution<> distributor(1, v + 1);
1203-
uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
1254+
// std::uniform_real_distribution<> distributor(1, v + 1);
1255+
// uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
1256+
uint_fast32_t distributed = random(1, v + 1);
12041257
return SASS_MEMORY_NEW(Number, pstate, (double)distributed);
12051258
}
12061259
else if (b) {
1207-
std::uniform_real_distribution<> distributor(0, 1);
1208-
double distributed = static_cast<double>(distributor(rand));
1260+
// std::uniform_real_distribution<> distributor(0, 1);
1261+
// double distributed = static_cast<double>(distributor(rand));
1262+
#ifdef IMPLEMENT_TR1
1263+
double distributed = gen_std_dist();
1264+
#else
1265+
double distributed = std_dist(rand);
1266+
#endif
12091267
return SASS_MEMORY_NEW(Number, pstate, distributed);
12101268
} else if (v) {
12111269
throw Exception::InvalidArgumentType(pstate, "random", "$limit", "number", v);
@@ -1989,8 +2047,11 @@ namespace Sass {
19892047
BUILT_IN(unique_id)
19902048
{
19912049
std::stringstream ss;
1992-
std::uniform_real_distribution<> distributor(0, 4294967296); // 16^8
1993-
uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
2050+
#ifdef IMPLEMENT_TR1
2051+
uint_fast32_t distributed = gen_full_dist();
2052+
#else
2053+
uint_fast32_t distributed = full_dist(rand);
2054+
#endif
19942055
ss << "u" << std::setfill('0') << std::setw(8) << std::hex << distributed;
19952056
return SASS_MEMORY_NEW(String_Quoted, pstate, ss.str());
19962057
}

src/parser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ namespace Sass {
307307
do {
308308
while (lex< block_comment >());
309309
if (lex< quoted_string >()) {
310-
to_import.push_back(std::pair<std::string,Function_Call_Obj>(std::string(lexed), 0));
310+
to_import.push_back(std::pair<std::string,Function_Call_Obj>(std::string(lexed), (Function_Call*) NULL));
311311
}
312312
else if (lex< uri_prefix >()) {
313313
Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);

src/subset_map.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace Sass {
2626
continue;
2727
}
2828
const std::vector<std::pair<Compound_Selector_Obj, size_t> >& subsets = hash_[(*sel)[i]];
29-
for (const std::pair<Compound_Selector_Obj, size_t>& item : subsets) {
29+
for (const auto& item : subsets) {
3030
bool include = true;
3131
for (const Simple_Selector_Obj& it : item.first->elements()) {
3232
auto found = dict.find(it);

0 commit comments

Comments
 (0)