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 << "&amp;";
75*4ba319b5SDimitry Andric     else if (C == '<')
76*4ba319b5SDimitry Andric       Out << "&lt;";
77*4ba319b5SDimitry Andric     else if (C == '>')
78*4ba319b5SDimitry Andric       Out << "&gt;";
79*4ba319b5SDimitry Andric     else if (C == '\"')
80*4ba319b5SDimitry Andric       Out << "&quot;";
81*4ba319b5SDimitry Andric     else if (C == '\'')
82*4ba319b5SDimitry Andric       Out << "&apos;";
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