1 //===-- StringRef.cpp - Lightweight String References ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/StringRef.h" 11 using namespace llvm; 12 13 // MSVC emits references to this into the translation units which reference it. 14 #ifndef _MSC_VER 15 const size_t StringRef::npos; 16 #endif 17 18 //===----------------------------------------------------------------------===// 19 // String Searching 20 //===----------------------------------------------------------------------===// 21 22 23 /// find - Search for the first string \arg Str in the string. 24 /// 25 /// \return - The index of the first occurence of \arg Str, or npos if not 26 /// found. 27 size_t StringRef::find(StringRef Str, size_t From) const { 28 size_t N = Str.size(); 29 if (N > Length) 30 return npos; 31 for (size_t e = Length - N + 1, i = std::min(From, e); i != e; ++i) 32 if (substr(i, N).equals(Str)) 33 return i; 34 return npos; 35 } 36 37 /// rfind - Search for the last string \arg Str in the string. 38 /// 39 /// \return - The index of the last occurence of \arg Str, or npos if not 40 /// found. 41 size_t StringRef::rfind(StringRef Str) const { 42 size_t N = Str.size(); 43 if (N > Length) 44 return npos; 45 for (size_t i = Length - N + 1, e = 0; i != e;) { 46 --i; 47 if (substr(i, N).equals(Str)) 48 return i; 49 } 50 return npos; 51 } 52 53 /// find_first_of - Find the first character in the string that is in \arg 54 /// Chars, or npos if not found. 55 /// 56 /// Note: O(size() * Chars.size()) 57 StringRef::size_type StringRef::find_first_of(StringRef Chars, 58 size_t From) const { 59 for (size_type i = std::min(From, Length), e = Length; i != e; ++i) 60 if (Chars.find(Data[i]) != npos) 61 return i; 62 return npos; 63 } 64 65 /// find_first_not_of - Find the first character in the string that is not 66 /// \arg C or npos if not found. 67 StringRef::size_type StringRef::find_first_not_of(char C, size_t From) const { 68 for (size_type i = std::min(From, Length), e = Length; i != e; ++i) 69 if (Data[i] != C) 70 return i; 71 return npos; 72 } 73 74 /// find_first_not_of - Find the first character in the string that is not 75 /// in the string \arg Chars, or npos if not found. 76 /// 77 /// Note: O(size() * Chars.size()) 78 StringRef::size_type StringRef::find_first_not_of(StringRef Chars, 79 size_t From) const { 80 for (size_type i = std::min(From, Length), e = Length; i != e; ++i) 81 if (Chars.find(Data[i]) == npos) 82 return i; 83 return npos; 84 } 85 86 87 //===----------------------------------------------------------------------===// 88 // Helpful Algorithms 89 //===----------------------------------------------------------------------===// 90 91 /// count - Return the number of non-overlapped occurrences of \arg Str in 92 /// the string. 93 size_t StringRef::count(StringRef Str) const { 94 size_t Count = 0; 95 size_t N = Str.size(); 96 if (N > Length) 97 return 0; 98 for (size_t i = 0, e = Length - N + 1; i != e; ++i) 99 if (substr(i, N).equals(Str)) 100 ++Count; 101 return Count; 102 } 103 104 /// GetAsUnsignedInteger - Workhorse method that converts a integer character 105 /// sequence of radix up to 36 to an unsigned long long value. 106 static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix, 107 unsigned long long &Result) { 108 // Autosense radix if not specified. 109 if (Radix == 0) { 110 if (Str.startswith("0x")) { 111 Str = Str.substr(2); 112 Radix = 16; 113 } else if (Str.startswith("0b")) { 114 Str = Str.substr(2); 115 Radix = 2; 116 } else if (Str.startswith("0")) 117 Radix = 8; 118 else 119 Radix = 10; 120 } 121 122 // Empty strings (after the radix autosense) are invalid. 123 if (Str.empty()) return true; 124 125 // Parse all the bytes of the string given this radix. Watch for overflow. 126 Result = 0; 127 while (!Str.empty()) { 128 unsigned CharVal; 129 if (Str[0] >= '0' && Str[0] <= '9') 130 CharVal = Str[0]-'0'; 131 else if (Str[0] >= 'a' && Str[0] <= 'z') 132 CharVal = Str[0]-'a'+10; 133 else if (Str[0] >= 'A' && Str[0] <= 'Z') 134 CharVal = Str[0]-'A'+10; 135 else 136 return true; 137 138 // If the parsed value is larger than the integer radix, the string is 139 // invalid. 140 if (CharVal >= Radix) 141 return true; 142 143 // Add in this character. 144 unsigned long long PrevResult = Result; 145 Result = Result*Radix+CharVal; 146 147 // Check for overflow. 148 if (Result < PrevResult) 149 return true; 150 151 Str = Str.substr(1); 152 } 153 154 return false; 155 } 156 157 bool StringRef::getAsInteger(unsigned Radix, unsigned long long &Result) const { 158 return GetAsUnsignedInteger(*this, Radix, Result); 159 } 160 161 162 bool StringRef::getAsInteger(unsigned Radix, long long &Result) const { 163 unsigned long long ULLVal; 164 165 // Handle positive strings first. 166 if (empty() || front() != '-') { 167 if (GetAsUnsignedInteger(*this, Radix, ULLVal) || 168 // Check for value so large it overflows a signed value. 169 (long long)ULLVal < 0) 170 return true; 171 Result = ULLVal; 172 return false; 173 } 174 175 // Get the positive part of the value. 176 if (GetAsUnsignedInteger(substr(1), Radix, ULLVal) || 177 // Reject values so large they'd overflow as negative signed, but allow 178 // "-0". This negates the unsigned so that the negative isn't undefined 179 // on signed overflow. 180 (long long)-ULLVal > 0) 181 return true; 182 183 Result = -ULLVal; 184 return false; 185 } 186 187 bool StringRef::getAsInteger(unsigned Radix, int &Result) const { 188 long long Val; 189 if (getAsInteger(Radix, Val) || 190 (int)Val != Val) 191 return true; 192 Result = Val; 193 return false; 194 } 195 196 bool StringRef::getAsInteger(unsigned Radix, unsigned &Result) const { 197 unsigned long long Val; 198 if (getAsInteger(Radix, Val) || 199 (unsigned)Val != Val) 200 return true; 201 Result = Val; 202 return false; 203 } 204