1f22ef01cSRoman Divacky //===-- StringExtras.cpp - Implement the StringExtras header --------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements the StringExtras.h header
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky
14f22ef01cSRoman Divacky #include "llvm/ADT/StringExtras.h"
15db17bf38SDimitry Andric #include "llvm/ADT/SmallVector.h"
162cab237bSDimitry Andric #include "llvm/Support/raw_ostream.h"
17f22ef01cSRoman Divacky using namespace llvm;
18f22ef01cSRoman Divacky
19f22ef01cSRoman Divacky /// StrInStrNoCase - Portable version of strcasestr. Locates the first
20f22ef01cSRoman Divacky /// occurrence of string 's1' in string 's2', ignoring case. Returns
21f22ef01cSRoman Divacky /// the offset of s2 in s1 or npos if s2 cannot be found.
StrInStrNoCase(StringRef s1,StringRef s2)22f22ef01cSRoman Divacky StringRef::size_type llvm::StrInStrNoCase(StringRef s1, StringRef s2) {
23f22ef01cSRoman Divacky size_t N = s2.size(), M = s1.size();
24f22ef01cSRoman Divacky if (N > M)
25f22ef01cSRoman Divacky return StringRef::npos;
26f22ef01cSRoman Divacky for (size_t i = 0, e = M - N + 1; i != e; ++i)
27f22ef01cSRoman Divacky if (s1.substr(i, N).equals_lower(s2))
28f22ef01cSRoman Divacky return i;
29f22ef01cSRoman Divacky return StringRef::npos;
30f22ef01cSRoman Divacky }
31f22ef01cSRoman Divacky
32f22ef01cSRoman Divacky /// getToken - This function extracts one token from source, ignoring any
33f22ef01cSRoman Divacky /// leading characters that appear in the Delimiters string, and ending the
34f22ef01cSRoman Divacky /// token at any of the characters that appear in the Delimiters string. If
35f22ef01cSRoman Divacky /// there are no tokens in the source string, an empty string is returned.
36f22ef01cSRoman Divacky /// The function returns a pair containing the extracted token and the
37f22ef01cSRoman Divacky /// remaining tail string.
getToken(StringRef Source,StringRef Delimiters)38f22ef01cSRoman Divacky std::pair<StringRef, StringRef> llvm::getToken(StringRef Source,
39f22ef01cSRoman Divacky StringRef Delimiters) {
40f22ef01cSRoman Divacky // Figure out where the token starts.
41f22ef01cSRoman Divacky StringRef::size_type Start = Source.find_first_not_of(Delimiters);
42f22ef01cSRoman Divacky
43f22ef01cSRoman Divacky // Find the next occurrence of the delimiter.
44f22ef01cSRoman Divacky StringRef::size_type End = Source.find_first_of(Delimiters, Start);
45f22ef01cSRoman Divacky
46f22ef01cSRoman Divacky return std::make_pair(Source.slice(Start, End), Source.substr(End));
47f22ef01cSRoman Divacky }
48f22ef01cSRoman Divacky
49f22ef01cSRoman Divacky /// SplitString - Split up the specified string according to the specified
50f22ef01cSRoman Divacky /// delimiters, appending the result fragments to the output list.
SplitString(StringRef Source,SmallVectorImpl<StringRef> & OutFragments,StringRef Delimiters)51f22ef01cSRoman Divacky void llvm::SplitString(StringRef Source,
52f22ef01cSRoman Divacky SmallVectorImpl<StringRef> &OutFragments,
53f22ef01cSRoman Divacky StringRef Delimiters) {
546122f3e6SDimitry Andric std::pair<StringRef, StringRef> S = getToken(Source, Delimiters);
556122f3e6SDimitry Andric while (!S.first.empty()) {
566122f3e6SDimitry Andric OutFragments.push_back(S.first);
576122f3e6SDimitry Andric S = getToken(S.second, Delimiters);
58f22ef01cSRoman Divacky }
59f22ef01cSRoman Divacky }
602cab237bSDimitry Andric
printEscapedString(StringRef Name,raw_ostream & Out)61*4ba319b5SDimitry Andric void llvm::printEscapedString(StringRef Name, raw_ostream &Out) {
62*4ba319b5SDimitry Andric for (unsigned i = 0, e = Name.size(); i != e; ++i) {
63*4ba319b5SDimitry Andric unsigned char C = Name[i];
64*4ba319b5SDimitry Andric if (isPrint(C) && C != '\\' && C != '"')
65*4ba319b5SDimitry Andric Out << C;
66*4ba319b5SDimitry Andric else
67*4ba319b5SDimitry Andric Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
68*4ba319b5SDimitry Andric }
69*4ba319b5SDimitry Andric }
70*4ba319b5SDimitry Andric
printHTMLEscaped(StringRef String,raw_ostream & Out)71*4ba319b5SDimitry Andric void llvm::printHTMLEscaped(StringRef String, raw_ostream &Out) {
72*4ba319b5SDimitry Andric for (char C : String) {
73*4ba319b5SDimitry Andric if (C == '&')
74*4ba319b5SDimitry Andric Out << "&";
75*4ba319b5SDimitry Andric else if (C == '<')
76*4ba319b5SDimitry Andric Out << "<";
77*4ba319b5SDimitry Andric else if (C == '>')
78*4ba319b5SDimitry Andric Out << ">";
79*4ba319b5SDimitry Andric else if (C == '\"')
80*4ba319b5SDimitry Andric Out << """;
81*4ba319b5SDimitry Andric else if (C == '\'')
82*4ba319b5SDimitry Andric Out << "'";
83*4ba319b5SDimitry Andric else
84*4ba319b5SDimitry Andric Out << C;
85*4ba319b5SDimitry Andric }
86*4ba319b5SDimitry Andric }
87*4ba319b5SDimitry Andric
printLowerCase(StringRef String,raw_ostream & Out)882cab237bSDimitry Andric void llvm::printLowerCase(StringRef String, raw_ostream &Out) {
892cab237bSDimitry Andric for (const char C : String)
902cab237bSDimitry Andric Out << toLower(C);
912cab237bSDimitry Andric }
92