/src/libsass/src/util_string.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "util_string.hpp" |
2 | | |
3 | | #include <iostream> |
4 | | #include <algorithm> |
5 | | |
6 | | namespace Sass { |
7 | | namespace Util { |
8 | | |
9 | | // ########################################################################## |
10 | | // Special case insensitive string matcher. We can optimize |
11 | | // the more general compare case quite a bit by requiring |
12 | | // consumers to obey some rules (lowercase and no space). |
13 | | // - `literal` must only contain lower case ascii characters |
14 | | // there is one edge case where this could give false positives |
15 | | // test could contain a (non-ascii) char exactly 32 below literal |
16 | | // ########################################################################## |
17 | 23.2k | bool equalsLiteral(const char* lit, const sass::string& test) { |
18 | | // Work directly on characters |
19 | 23.2k | const char* src = test.c_str(); |
20 | | // There is a small chance that the search string |
21 | | // Is longer than the rest of the string to look at |
22 | 23.2k | while (*lit && (*src == *lit || *src + 32 == *lit)) { |
23 | 0 | ++src, ++lit; |
24 | 0 | } |
25 | | // True if literal is at end |
26 | | // If not test was too long |
27 | 23.2k | return *lit == 0; |
28 | 23.2k | } |
29 | | |
30 | 171k | void ascii_str_tolower(sass::string* s) { |
31 | 2.17M | for (auto& ch : *s) { |
32 | 2.17M | ch = ascii_tolower(static_cast<unsigned char>(ch)); |
33 | 2.17M | } |
34 | 171k | } |
35 | | |
36 | 0 | void ascii_str_toupper(sass::string* s) { |
37 | 0 | for (auto& ch : *s) { |
38 | 0 | ch = ascii_toupper(static_cast<unsigned char>(ch)); |
39 | 0 | } |
40 | 0 | } |
41 | | |
42 | 0 | sass::string rtrim(sass::string str) { |
43 | 0 | auto it = std::find_if_not(str.rbegin(), str.rend(), ascii_isspace); |
44 | 0 | str.erase(str.rend() - it); |
45 | 0 | return str; |
46 | 0 | } |
47 | | |
48 | | // ########################################################################### |
49 | | // Returns [name] without a vendor prefix. |
50 | | // If [name] has no vendor prefix, it's returned as-is. |
51 | | // ########################################################################### |
52 | | sass::string unvendor(const sass::string& name) |
53 | 6.03k | { |
54 | 6.03k | if (name.size() < 2) return name; |
55 | 3.79k | if (name[0] != '-') return name; |
56 | 0 | if (name[1] == '-') return name; |
57 | 0 | for (size_t i = 2; i < name.size(); i++) { |
58 | 0 | if (name[i] == '-') return name.substr(i + 1); |
59 | 0 | } |
60 | 0 | return name; |
61 | 0 | } |
62 | | // EO unvendor |
63 | | |
64 | 0 | sass::string normalize_newlines(const sass::string& str) { |
65 | 0 | sass::string result; |
66 | 0 | result.reserve(str.size()); |
67 | 0 | std::size_t pos = 0; |
68 | 0 | while (true) { |
69 | 0 | const std::size_t newline = str.find_first_of("\n\f\r", pos); |
70 | 0 | if (newline == sass::string::npos) break; |
71 | 0 | result.append(str, pos, newline - pos); |
72 | 0 | result += '\n'; |
73 | 0 | if (str[newline] == '\r' && str[newline + 1] == '\n') { |
74 | 0 | pos = newline + 2; |
75 | 0 | } |
76 | 0 | else { |
77 | 0 | pos = newline + 1; |
78 | 0 | } |
79 | 0 | } |
80 | 0 | result.append(str, pos, sass::string::npos); |
81 | 0 | return result; |
82 | 0 | } |
83 | | |
84 | 4.18k | sass::string normalize_underscores(const sass::string& str) { |
85 | 4.18k | sass::string normalized = str; |
86 | 4.18k | std::replace(normalized.begin(), normalized.end(), '_', '-'); |
87 | 4.18k | return normalized; |
88 | 4.18k | } |
89 | | |
90 | 2 | sass::string normalize_decimals(const sass::string& str) { |
91 | 2 | sass::string normalized; |
92 | 2 | if (!str.empty() && str[0] == '.') { |
93 | 0 | normalized.reserve(str.size() + 1); |
94 | 0 | normalized += '0'; |
95 | 0 | normalized += str; |
96 | 0 | } |
97 | 2 | else { |
98 | 2 | normalized = str; |
99 | 2 | } |
100 | 2 | return normalized; |
101 | 2 | } |
102 | | |
103 | 6 | char opening_bracket_for(char closing_bracket) { |
104 | 6 | switch (closing_bracket) { |
105 | 0 | case ')': return '('; |
106 | 0 | case ']': return '['; |
107 | 6 | case '}': return '{'; |
108 | 0 | default: return '\0'; |
109 | 6 | } |
110 | 6 | } |
111 | | |
112 | 0 | char closing_bracket_for(char opening_bracket) { |
113 | 0 | switch (opening_bracket) { |
114 | 0 | case '(': return ')'; |
115 | 0 | case '[': return ']'; |
116 | 0 | case '{': return '}'; |
117 | 0 | default: return '\0'; |
118 | 0 | } |
119 | 0 | } |
120 | | |
121 | | } |
122 | | // namespace Util |
123 | | |
124 | | } |
125 | | // namespace Sass |