This repository has been archived by the owner on Jul 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move string functions to own compile unit
- Loading branch information
Showing
8 changed files
with
303 additions
and
263 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
#include "ast.hpp" | ||
#include "fn_utils.hpp" | ||
#include "fn_strings.hpp" | ||
|
||
namespace Sass { | ||
|
||
namespace Functions { | ||
|
||
void handle_utf8_error (const ParserState& pstate, Backtraces traces) | ||
{ | ||
try { | ||
throw; | ||
} | ||
catch (utf8::invalid_code_point) { | ||
std::string msg("utf8::invalid_code_point"); | ||
error(msg, pstate, traces); | ||
} | ||
catch (utf8::not_enough_room) { | ||
std::string msg("utf8::not_enough_room"); | ||
error(msg, pstate, traces); | ||
} | ||
catch (utf8::invalid_utf8) { | ||
std::string msg("utf8::invalid_utf8"); | ||
error(msg, pstate, traces); | ||
} | ||
catch (...) { throw; } | ||
} | ||
|
||
/////////////////// | ||
// STRING FUNCTIONS | ||
/////////////////// | ||
|
||
Signature unquote_sig = "unquote($string)"; | ||
BUILT_IN(sass_unquote) | ||
{ | ||
AST_Node_Obj arg = env["$string"]; | ||
if (String_Quoted_Ptr string_quoted = Cast<String_Quoted>(arg)) { | ||
String_Constant_Ptr result = SASS_MEMORY_NEW(String_Constant, pstate, string_quoted->value()); | ||
// remember if the string was quoted (color tokens) | ||
result->is_delayed(true); // delay colors | ||
return result; | ||
} | ||
else if (String_Constant_Ptr str = Cast<String_Constant>(arg)) { | ||
return str; | ||
} | ||
else if (Value_Ptr ex = Cast<Value>(arg)) { | ||
Sass_Output_Style oldstyle = ctx.c_options.output_style; | ||
ctx.c_options.output_style = SASS_STYLE_NESTED; | ||
std::string val(arg->to_string(ctx.c_options)); | ||
val = Cast<Null>(arg) ? "null" : val; | ||
ctx.c_options.output_style = oldstyle; | ||
|
||
deprecated_function("Passing " + val + ", a non-string value, to unquote()", pstate); | ||
return ex; | ||
} | ||
throw std::runtime_error("Invalid Data Type for unquote"); | ||
} | ||
|
||
Signature quote_sig = "quote($string)"; | ||
BUILT_IN(sass_quote) | ||
{ | ||
AST_Node_Obj arg = env["$string"]; | ||
// only set quote mark to true if already a string | ||
if (String_Quoted_Ptr qstr = Cast<String_Quoted>(arg)) { | ||
qstr->quote_mark('*'); | ||
return qstr; | ||
} | ||
// all other nodes must be converted to a string node | ||
std::string str(quote(arg->to_string(ctx.c_options), String_Constant::double_quote())); | ||
String_Quoted_Ptr result = SASS_MEMORY_NEW(String_Quoted, pstate, str); | ||
result->quote_mark('*'); | ||
return result; | ||
} | ||
|
||
|
||
Signature str_length_sig = "str-length($string)"; | ||
BUILT_IN(str_length) | ||
{ | ||
size_t len = std::string::npos; | ||
try { | ||
String_Constant_Ptr s = ARG("$string", String_Constant); | ||
len = UTF_8::code_point_count(s->value(), 0, s->value().size()); | ||
|
||
} | ||
// handle any invalid utf8 errors | ||
// other errors will be re-thrown | ||
catch (...) { handle_utf8_error(pstate, traces); } | ||
// return something even if we had an error (-1) | ||
return SASS_MEMORY_NEW(Number, pstate, (double)len); | ||
} | ||
|
||
Signature str_insert_sig = "str-insert($string, $insert, $index)"; | ||
BUILT_IN(str_insert) | ||
{ | ||
std::string str; | ||
try { | ||
String_Constant_Ptr s = ARG("$string", String_Constant); | ||
str = s->value(); | ||
str = unquote(str); | ||
String_Constant_Ptr i = ARG("$insert", String_Constant); | ||
std::string ins = i->value(); | ||
ins = unquote(ins); | ||
double index = ARGVAL("$index"); | ||
size_t len = UTF_8::code_point_count(str, 0, str.size()); | ||
|
||
if (index > 0 && index <= len) { | ||
// positive and within string length | ||
str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index) - 1), ins); | ||
} | ||
else if (index > len) { | ||
// positive and past string length | ||
str += ins; | ||
} | ||
else if (index == 0) { | ||
str = ins + str; | ||
} | ||
else if (std::abs(index) <= len) { | ||
// negative and within string length | ||
index += len + 1; | ||
str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index)), ins); | ||
} | ||
else { | ||
// negative and past string length | ||
str = ins + str; | ||
} | ||
|
||
if (String_Quoted_Ptr ss = Cast<String_Quoted>(s)) { | ||
if (ss->quote_mark()) str = quote(str); | ||
} | ||
} | ||
// handle any invalid utf8 errors | ||
// other errors will be re-thrown | ||
catch (...) { handle_utf8_error(pstate, traces); } | ||
return SASS_MEMORY_NEW(String_Quoted, pstate, str); | ||
} | ||
|
||
Signature str_index_sig = "str-index($string, $substring)"; | ||
BUILT_IN(str_index) | ||
{ | ||
size_t index = std::string::npos; | ||
try { | ||
String_Constant_Ptr s = ARG("$string", String_Constant); | ||
String_Constant_Ptr t = ARG("$substring", String_Constant); | ||
std::string str = s->value(); | ||
str = unquote(str); | ||
std::string substr = t->value(); | ||
substr = unquote(substr); | ||
|
||
size_t c_index = str.find(substr); | ||
if(c_index == std::string::npos) { | ||
return SASS_MEMORY_NEW(Null, pstate); | ||
} | ||
index = UTF_8::code_point_count(str, 0, c_index) + 1; | ||
} | ||
// handle any invalid utf8 errors | ||
// other errors will be re-thrown | ||
catch (...) { handle_utf8_error(pstate, traces); } | ||
// return something even if we had an error (-1) | ||
return SASS_MEMORY_NEW(Number, pstate, (double)index); | ||
} | ||
|
||
Signature str_slice_sig = "str-slice($string, $start-at, $end-at:-1)"; | ||
BUILT_IN(str_slice) | ||
{ | ||
std::string newstr; | ||
try { | ||
String_Constant_Ptr s = ARG("$string", String_Constant); | ||
double start_at = ARGVAL("$start-at"); | ||
double end_at = ARGVAL("$end-at"); | ||
String_Quoted_Ptr ss = Cast<String_Quoted>(s); | ||
|
||
std::string str = unquote(s->value()); | ||
|
||
size_t size = utf8::distance(str.begin(), str.end()); | ||
|
||
if (!Cast<Number>(env["$end-at"])) { | ||
end_at = -1; | ||
} | ||
|
||
if (end_at == 0 || (end_at + size) < 0) { | ||
if (ss && ss->quote_mark()) newstr = quote(""); | ||
return SASS_MEMORY_NEW(String_Quoted, pstate, newstr); | ||
} | ||
|
||
if (end_at < 0) { | ||
end_at += size + 1; | ||
if (end_at == 0) end_at = 1; | ||
} | ||
if (end_at > size) { end_at = (double)size; } | ||
if (start_at < 0) { | ||
start_at += size + 1; | ||
if (start_at < 0) start_at = 0; | ||
} | ||
else if (start_at == 0) { ++ start_at; } | ||
|
||
if (start_at <= end_at) | ||
{ | ||
std::string::iterator start = str.begin(); | ||
utf8::advance(start, start_at - 1, str.end()); | ||
std::string::iterator end = start; | ||
utf8::advance(end, end_at - start_at + 1, str.end()); | ||
newstr = std::string(start, end); | ||
} | ||
if (ss) { | ||
if(ss->quote_mark()) newstr = quote(newstr); | ||
} | ||
} | ||
// handle any invalid utf8 errors | ||
// other errors will be re-thrown | ||
catch (...) { handle_utf8_error(pstate, traces); } | ||
return SASS_MEMORY_NEW(String_Quoted, pstate, newstr); | ||
} | ||
|
||
Signature to_upper_case_sig = "to-upper-case($string)"; | ||
BUILT_IN(to_upper_case) | ||
{ | ||
String_Constant_Ptr s = ARG("$string", String_Constant); | ||
std::string str = s->value(); | ||
|
||
for (size_t i = 0, L = str.length(); i < L; ++i) { | ||
if (Sass::Util::isAscii(str[i])) { | ||
str[i] = std::toupper(str[i]); | ||
} | ||
} | ||
|
||
if (String_Quoted_Ptr ss = Cast<String_Quoted>(s)) { | ||
String_Quoted_Ptr cpy = SASS_MEMORY_COPY(ss); | ||
cpy->value(str); | ||
return cpy; | ||
} else { | ||
return SASS_MEMORY_NEW(String_Quoted, pstate, str); | ||
} | ||
} | ||
|
||
Signature to_lower_case_sig = "to-lower-case($string)"; | ||
BUILT_IN(to_lower_case) | ||
{ | ||
String_Constant_Ptr s = ARG("$string", String_Constant); | ||
std::string str = s->value(); | ||
|
||
for (size_t i = 0, L = str.length(); i < L; ++i) { | ||
if (Sass::Util::isAscii(str[i])) { | ||
str[i] = std::tolower(str[i]); | ||
} | ||
} | ||
|
||
if (String_Quoted_Ptr ss = Cast<String_Quoted>(s)) { | ||
String_Quoted_Ptr cpy = SASS_MEMORY_COPY(ss); | ||
cpy->value(str); | ||
return cpy; | ||
} else { | ||
return SASS_MEMORY_NEW(String_Quoted, pstate, str); | ||
} | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef SASS_FN_STRINGS_H | ||
#define SASS_FN_STRINGS_H | ||
|
||
#include "fn_utils.hpp" | ||
|
||
namespace Sass { | ||
|
||
namespace Functions { | ||
|
||
extern Signature unquote_sig; | ||
extern Signature quote_sig; | ||
extern Signature str_length_sig; | ||
extern Signature str_insert_sig; | ||
extern Signature str_index_sig; | ||
extern Signature str_slice_sig; | ||
extern Signature to_upper_case_sig; | ||
extern Signature to_lower_case_sig; | ||
extern Signature length_sig; | ||
|
||
BUILT_IN(sass_unquote); | ||
BUILT_IN(sass_quote); | ||
BUILT_IN(str_length); | ||
BUILT_IN(str_insert); | ||
BUILT_IN(str_index); | ||
BUILT_IN(str_slice); | ||
BUILT_IN(to_upper_case); | ||
BUILT_IN(to_lower_case); | ||
BUILT_IN(length); | ||
|
||
} | ||
|
||
} | ||
|
||
#endif |
Oops, something went wrong.