Skip to content

Commit 925097a

Browse files
committed
Add utilities for lower- and sentence-casing camelCase strings.
Swift SVN r15815
1 parent 23bd9a1 commit 925097a

File tree

3 files changed

+72
-5
lines changed

3 files changed

+72
-5
lines changed

include/swift/Basic/StringExtras.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,24 @@ namespace swift {
177177
/// Retrieve the camelCase words in the given string.
178178
inline Words getWords(StringRef string) { return Words(string); }
179179

180-
/// Find the last preposition in the given camelCase string.
180+
/// Lowercase the first word within the given camelCase string.
181181
///
182-
/// \returns a pair containing the starting index of the last
183-
/// preposition as well as the kind of preposition found.
184-
std::pair<unsigned, PrepositionKind> findLastPreposition(StringRef string);
182+
/// \param string The string to lowercase.
183+
/// \param scratch Scratch buffer used to form the resulting string.
184+
///
185+
/// \returns the string with the first word lowercased. When the
186+
/// first word is an acronym, the string will be returned
187+
/// unchanged.
188+
StringRef toLowercaseWord(StringRef string, SmallVectorImpl<char> &scratch);
189+
190+
/// Sentence-case the given camelCase string by turning the first
191+
/// letter into an uppercase letter.
192+
///
193+
/// \param string The string to sentence-case.
194+
/// \param scratch Scratch buffer used to form the resulting string.
195+
///
196+
/// \returns the string in sentence case.
197+
StringRef toSentencecase(StringRef string, SmallVectorImpl<char> &scratch);
185198
} // end namespace camel_case
186199
}
187200

lib/Basic/StringExtras.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
//===----------------------------------------------------------------------===//
1717
#include "swift/Basic/StringExtras.h"
1818
#include "clang/Basic/CharInfo.h"
19+
#include "llvm/ADT/SmallVector.h"
1920
using namespace swift;
2021
using namespace camel_case;
2122

@@ -86,7 +87,6 @@ void WordIterator::computePrevPosition() const {
8687
PrevPositionValid = true;
8788
}
8889

89-
9090
StringRef camel_case::getFirstWord(StringRef string) {
9191
if (string.empty())
9292
return "";
@@ -101,3 +101,38 @@ StringRef camel_case::getLastWord(StringRef string) {
101101
return *--WordIterator(string, string.size());
102102
}
103103

104+
StringRef camel_case::toLowercaseWord(StringRef string,
105+
SmallVectorImpl<char> &scratch) {
106+
if (string.empty())
107+
return string;
108+
109+
// Already lowercase.
110+
if (!clang::isUppercase(string[0]))
111+
return string;
112+
113+
// Acronym doesn't get lowercased.
114+
if (string.size() > 1 && clang::isUppercase(string[1]))
115+
return string;
116+
117+
// Lowercase the first letter, append the rest.
118+
scratch.clear();
119+
scratch.push_back(clang::toLowercase(string[0]));
120+
scratch.append(string.begin() + 1, string.end());
121+
return StringRef(scratch.data(), scratch.size());
122+
}
123+
124+
StringRef camel_case::toSentencecase(StringRef string,
125+
SmallVectorImpl<char> &scratch) {
126+
if (string.empty())
127+
return string;
128+
129+
// Can't be uppercased.
130+
if (!clang::isLowercase(string[0]))
131+
return string;
132+
133+
// Uppercase the first letter, append the rest.
134+
scratch.clear();
135+
scratch.push_back(clang::toUppercase(string[0]));
136+
scratch.append(string.begin() + 1, string.end());
137+
return StringRef(scratch.data(), scratch.size());
138+
}

unittests/Basic/StringExtrasTest.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,22 @@ TEST(CamelCaseWordsTest, Iteration) {
5454
++iter;
5555
EXPECT_EQ(iter, words.end());
5656
}
57+
58+
TEST(ToLowercaseTest, Words) {
59+
llvm::SmallString<64> scratch;
60+
61+
EXPECT_EQ(camel_case::toLowercaseWord("By", scratch), "by");
62+
EXPECT_EQ(camel_case::toLowercaseWord("and", scratch), "and");
63+
EXPECT_EQ(camel_case::toLowercaseWord("A", scratch), "a");
64+
EXPECT_EQ(camel_case::toLowercaseWord("URL", scratch), "URL");
65+
EXPECT_EQ(camel_case::toLowercaseWord("", scratch), "");
66+
}
67+
68+
TEST(ToSentencecaseTest, Words) {
69+
llvm::SmallString<64> scratch;
70+
71+
EXPECT_EQ(camel_case::toSentencecase("by", scratch), "By");
72+
EXPECT_EQ(camel_case::toSentencecase("a", scratch), "A");
73+
EXPECT_EQ(camel_case::toSentencecase("URL", scratch), "URL");
74+
EXPECT_EQ(camel_case::toSentencecase("", scratch), "");
75+
}

0 commit comments

Comments
 (0)