/home/arjun/llvm-project/llvm/lib/Support/StringExtras.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- StringExtras.cpp - Implement the StringExtras header --------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file implements the StringExtras.h header |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "llvm/ADT/StringExtras.h" |
14 | | #include "llvm/ADT/SmallVector.h" |
15 | | #include "llvm/Support/raw_ostream.h" |
16 | | #include <cctype> |
17 | | |
18 | | using namespace llvm; |
19 | | |
20 | | /// StrInStrNoCase - Portable version of strcasestr. Locates the first |
21 | | /// occurrence of string 's1' in string 's2', ignoring case. Returns |
22 | | /// the offset of s2 in s1 or npos if s2 cannot be found. |
23 | 0 | StringRef::size_type llvm::StrInStrNoCase(StringRef s1, StringRef s2) { |
24 | 0 | size_t N = s2.size(), M = s1.size(); |
25 | 0 | if (N > M) |
26 | 0 | return StringRef::npos; |
27 | 0 | for (size_t i = 0, e = M - N + 1; i != e; ++i) |
28 | 0 | if (s1.substr(i, N).equals_lower(s2)) |
29 | 0 | return i; |
30 | 0 | return StringRef::npos; |
31 | 0 | } |
32 | | |
33 | | /// getToken - This function extracts one token from source, ignoring any |
34 | | /// leading characters that appear in the Delimiters string, and ending the |
35 | | /// token at any of the characters that appear in the Delimiters string. If |
36 | | /// there are no tokens in the source string, an empty string is returned. |
37 | | /// The function returns a pair containing the extracted token and the |
38 | | /// remaining tail string. |
39 | | std::pair<StringRef, StringRef> llvm::getToken(StringRef Source, |
40 | 0 | StringRef Delimiters) { |
41 | 0 | // Figure out where the token starts. |
42 | 0 | StringRef::size_type Start = Source.find_first_not_of(Delimiters); |
43 | 0 |
|
44 | 0 | // Find the next occurrence of the delimiter. |
45 | 0 | StringRef::size_type End = Source.find_first_of(Delimiters, Start); |
46 | 0 |
|
47 | 0 | return std::make_pair(Source.slice(Start, End), Source.substr(End)); |
48 | 0 | } |
49 | | |
50 | | /// SplitString - Split up the specified string according to the specified |
51 | | /// delimiters, appending the result fragments to the output list. |
52 | | void llvm::SplitString(StringRef Source, |
53 | | SmallVectorImpl<StringRef> &OutFragments, |
54 | 0 | StringRef Delimiters) { |
55 | 0 | std::pair<StringRef, StringRef> S = getToken(Source, Delimiters); |
56 | 0 | while (!S.first.empty()) { |
57 | 0 | OutFragments.push_back(S.first); |
58 | 0 | S = getToken(S.second, Delimiters); |
59 | 0 | } |
60 | 0 | } |
61 | | |
62 | 0 | void llvm::printEscapedString(StringRef Name, raw_ostream &Out) { |
63 | 0 | for (unsigned i = 0, e = Name.size(); i != e; ++i) { |
64 | 0 | unsigned char C = Name[i]; |
65 | 0 | if (C == '\\') |
66 | 0 | Out << '\\' << C; |
67 | 0 | else if (isPrint(C) && C != '"') |
68 | 0 | Out << C; |
69 | 0 | else |
70 | 0 | Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); |
71 | 0 | } |
72 | 0 | } |
73 | | |
74 | 0 | void llvm::printHTMLEscaped(StringRef String, raw_ostream &Out) { |
75 | 0 | for (char C : String) { |
76 | 0 | if (C == '&') |
77 | 0 | Out << "&"; |
78 | 0 | else if (C == '<') |
79 | 0 | Out << "<"; |
80 | 0 | else if (C == '>') |
81 | 0 | Out << ">"; |
82 | 0 | else if (C == '\"') |
83 | 0 | Out << """; |
84 | 0 | else if (C == '\'') |
85 | 0 | Out << "'"; |
86 | 0 | else |
87 | 0 | Out << C; |
88 | 0 | } |
89 | 0 | } |
90 | | |
91 | 0 | void llvm::printLowerCase(StringRef String, raw_ostream &Out) { |
92 | 0 | for (const char C : String) |
93 | 0 | Out << toLower(C); |
94 | 0 | } |
95 | | |
96 | 0 | std::string llvm::convertToSnakeFromCamelCase(StringRef input) { |
97 | 0 | if (input.empty()) |
98 | 0 | return ""; |
99 | 0 | |
100 | 0 | std::string snakeCase; |
101 | 0 | snakeCase.reserve(input.size()); |
102 | 0 | for (char c : input) { |
103 | 0 | if (!std::isupper(c)) { |
104 | 0 | snakeCase.push_back(c); |
105 | 0 | continue; |
106 | 0 | } |
107 | 0 | |
108 | 0 | if (!snakeCase.empty() && snakeCase.back() != '_') |
109 | 0 | snakeCase.push_back('_'); |
110 | 0 | snakeCase.push_back(llvm::toLower(c)); |
111 | 0 | } |
112 | 0 | return snakeCase; |
113 | 0 | } |
114 | | |
115 | | std::string llvm::convertToCamelFromSnakeCase(StringRef input, |
116 | 0 | bool capitalizeFirst) { |
117 | 0 | if (input.empty()) |
118 | 0 | return ""; |
119 | 0 | |
120 | 0 | std::string output; |
121 | 0 | output.reserve(input.size()); |
122 | 0 |
|
123 | 0 | // Push the first character, capatilizing if necessary. |
124 | 0 | if (capitalizeFirst && std::islower(input.front())) |
125 | 0 | output.push_back(llvm::toUpper(input.front())); |
126 | 0 | else |
127 | 0 | output.push_back(input.front()); |
128 | 0 |
|
129 | 0 | // Walk the input converting any `*_[a-z]` snake case into `*[A-Z]` camelCase. |
130 | 0 | for (size_t pos = 1, e = input.size(); pos < e; ++pos) { |
131 | 0 | if (input[pos] == '_' && pos != (e - 1) && std::islower(input[pos + 1])) |
132 | 0 | output.push_back(llvm::toUpper(input[++pos])); |
133 | 0 | else |
134 | 0 | output.push_back(input[pos]); |
135 | 0 | } |
136 | 0 | return output; |
137 | 0 | } |