1 #ifndef SASS_UTIL_H 2 #define SASS_UTIL_H 3 4 // sass.hpp must go before all system headers to get the 5 // __EXTENSIONS__ fix on Solaris. 6 #include "sass.hpp" 7 8 #include "sass/base.h" 9 #include "ast_fwd_decl.hpp" 10 11 #include <cmath> 12 #include <cstring> 13 #include <vector> 14 #include <string> 15 #include <assert.h> 16 17 #define SASS_ASSERT(cond, msg) assert(cond && msg) 18 19 namespace Sass { 20 21 template <typename T> clip(const T & n,const T & lower,const T & upper)22 T clip(const T& n, const T& lower, const T& upper) { 23 return std::max(lower, std::min(n, upper)); 24 } 25 26 template <typename T> absmod(const T & n,const T & r)27 T absmod(const T& n, const T& r) { 28 T m = std::fmod(n, r); 29 if (m < 0.0) m += r; 30 return m; 31 } 32 33 double round(double val, size_t precision = 0); 34 double sass_strtod(const char* str); 35 const char* safe_str(const char *, const char* = ""); 36 void free_string_array(char **); 37 char **copy_strings(const sass::vector<sass::string>&, char ***, int = 0); 38 sass::string read_css_string(const sass::string& str, bool css = true); 39 sass::string evacuate_escapes(const sass::string& str); 40 sass::string string_to_output(const sass::string& str); 41 sass::string comment_to_compact_string(const sass::string& text); 42 sass::string read_hex_escapes(const sass::string& str); 43 sass::string escape_string(const sass::string& str); 44 void newline_to_space(sass::string& str); 45 46 sass::string quote(const sass::string&, char q = 0); 47 sass::string unquote(const sass::string&, char* q = 0, bool keep_utf8_sequences = false, bool strict = true); 48 char detect_best_quotemark(const char* s, char qm = '"'); 49 50 bool is_hex_doublet(double n); 51 bool is_color_doublet(double r, double g, double b); 52 53 bool peek_linefeed(const char* start); 54 55 // Returns true iff `elements` ⊆ `container`. 56 template <typename C, typename T> contains_all(C container,T elements)57 bool contains_all(C container, T elements) { 58 for (const auto &el : elements) { 59 if (container.find(el) == container.end()) return false; 60 } 61 return true; 62 } 63 64 // C++20 `starts_with` equivalent. 65 // See https://en.cppreference.com/w/cpp/string/basic_string/starts_with starts_with(const sass::string & str,const char * prefix,size_t prefix_len)66 inline bool starts_with(const sass::string& str, const char* prefix, size_t prefix_len) { 67 return str.compare(0, prefix_len, prefix) == 0; 68 } 69 starts_with(const sass::string & str,const char * prefix)70 inline bool starts_with(const sass::string& str, const char* prefix) { 71 return starts_with(str, prefix, std::strlen(prefix)); 72 } 73 74 // C++20 `ends_with` equivalent. 75 // See https://en.cppreference.com/w/cpp/string/basic_string/ends_with ends_with(const sass::string & str,const sass::string & suffix)76 inline bool ends_with(const sass::string& str, const sass::string& suffix) { 77 return suffix.size() <= str.size() && std::equal(suffix.rbegin(), suffix.rend(), str.rbegin()); 78 } 79 ends_with(const sass::string & str,const char * suffix,size_t suffix_len)80 inline bool ends_with(const sass::string& str, const char* suffix, size_t suffix_len) { 81 if (suffix_len > str.size()) return false; 82 const char* suffix_it = suffix + suffix_len; 83 const char* str_it = str.c_str() + str.size(); 84 while (suffix_it != suffix) if (*(--suffix_it) != *(--str_it)) return false; 85 return true; 86 } 87 ends_with(const sass::string & str,const char * suffix)88 inline bool ends_with(const sass::string& str, const char* suffix) { 89 return ends_with(str, suffix, std::strlen(suffix)); 90 } 91 92 namespace Util { 93 94 bool isPrintable(StyleRule* r, Sass_Output_Style style = NESTED); 95 bool isPrintable(SupportsRule* r, Sass_Output_Style style = NESTED); 96 bool isPrintable(CssMediaRule* r, Sass_Output_Style style = NESTED); 97 bool isPrintable(Comment* b, Sass_Output_Style style = NESTED); 98 bool isPrintable(Block_Obj b, Sass_Output_Style style = NESTED); 99 bool isPrintable(String_Constant* s, Sass_Output_Style style = NESTED); 100 bool isPrintable(String_Quoted* s, Sass_Output_Style style = NESTED); 101 bool isPrintable(Declaration* d, Sass_Output_Style style = NESTED); 102 103 } 104 } 105 #endif 106