blob: 2d023e4895d068b915cdfaaa70e3da929b64b2cc [file] [log] [blame]
Daniel Dunbare6551282009-09-16 22:38:48 +00001//===-- 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"
11using namespace llvm;
12
Daniel Dunbar77696be2009-09-22 03:34:40 +000013// MSVC emits references to this into the translation units which reference it.
14#ifndef _MSC_VER
Daniel Dunbare6551282009-09-16 22:38:48 +000015const size_t StringRef::npos;
Daniel Dunbar77696be2009-09-22 03:34:40 +000016#endif
Chris Lattnercea14382009-09-19 19:47:14 +000017
Benjamin Kramer05872ea2009-11-12 20:36:59 +000018static char ascii_tolower(char x) {
19 if (x >= 'A' && x <= 'Z')
20 return x - 'A' + 'a';
21 return x;
22}
23
24/// compare_lower - Compare strings, ignoring case.
25int StringRef::compare_lower(StringRef RHS) const {
Daniel Dunbar58ce7ac2009-11-19 18:53:18 +000026 for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) {
Benjamin Kramer05872ea2009-11-12 20:36:59 +000027 char LHC = ascii_tolower(Data[I]);
28 char RHC = ascii_tolower(RHS.Data[I]);
29 if (LHC != RHC)
30 return LHC < RHC ? -1 : 1;
31 }
32
33 if (Length == RHS.Length)
34 return 0;
35 return Length < RHS.Length ? -1 : 1;
36}
37
Chris Lattner05a32c82009-09-20 01:22:16 +000038//===----------------------------------------------------------------------===//
39// String Searching
40//===----------------------------------------------------------------------===//
41
42
43/// find - Search for the first string \arg Str in the string.
44///
45/// \return - The index of the first occurence of \arg Str, or npos if not
46/// found.
Daniel Dunbar64066bd2009-11-11 00:28:53 +000047size_t StringRef::find(StringRef Str, size_t From) const {
Chris Lattner05a32c82009-09-20 01:22:16 +000048 size_t N = Str.size();
49 if (N > Length)
50 return npos;
Daniel Dunbar58ce7ac2009-11-19 18:53:18 +000051 for (size_t e = Length - N + 1, i = min(From, e); i != e; ++i)
Chris Lattner05a32c82009-09-20 01:22:16 +000052 if (substr(i, N).equals(Str))
53 return i;
54 return npos;
55}
56
57/// rfind - Search for the last string \arg Str in the string.
58///
59/// \return - The index of the last occurence of \arg Str, or npos if not
60/// found.
Daniel Dunbar2928c832009-11-06 10:58:06 +000061size_t StringRef::rfind(StringRef Str) const {
Chris Lattner05a32c82009-09-20 01:22:16 +000062 size_t N = Str.size();
63 if (N > Length)
64 return npos;
65 for (size_t i = Length - N + 1, e = 0; i != e;) {
66 --i;
67 if (substr(i, N).equals(Str))
68 return i;
69 }
70 return npos;
71}
72
Daniel Dunbar64066bd2009-11-11 00:28:53 +000073/// find_first_of - Find the first character in the string that is in \arg
74/// Chars, or npos if not found.
75///
76/// Note: O(size() * Chars.size())
77StringRef::size_type StringRef::find_first_of(StringRef Chars,
78 size_t From) const {
Daniel Dunbar58ce7ac2009-11-19 18:53:18 +000079 for (size_type i = min(From, Length), e = Length; i != e; ++i)
Chris Lattner05a32c82009-09-20 01:22:16 +000080 if (Chars.find(Data[i]) != npos)
81 return i;
82 return npos;
83}
84
85/// find_first_not_of - Find the first character in the string that is not
Daniel Dunbar64066bd2009-11-11 00:28:53 +000086/// \arg C or npos if not found.
87StringRef::size_type StringRef::find_first_not_of(char C, size_t From) const {
Daniel Dunbar58ce7ac2009-11-19 18:53:18 +000088 for (size_type i = min(From, Length), e = Length; i != e; ++i)
Daniel Dunbar64066bd2009-11-11 00:28:53 +000089 if (Data[i] != C)
90 return i;
91 return npos;
92}
93
94/// find_first_not_of - Find the first character in the string that is not
95/// in the string \arg Chars, or npos if not found.
96///
97/// Note: O(size() * Chars.size())
98StringRef::size_type StringRef::find_first_not_of(StringRef Chars,
99 size_t From) const {
Daniel Dunbar58ce7ac2009-11-19 18:53:18 +0000100 for (size_type i = min(From, Length), e = Length; i != e; ++i)
Chris Lattner05a32c82009-09-20 01:22:16 +0000101 if (Chars.find(Data[i]) == npos)
102 return i;
103 return npos;
104}
105
106
107//===----------------------------------------------------------------------===//
108// Helpful Algorithms
109//===----------------------------------------------------------------------===//
110
111/// count - Return the number of non-overlapped occurrences of \arg Str in
112/// the string.
Daniel Dunbar2928c832009-11-06 10:58:06 +0000113size_t StringRef::count(StringRef Str) const {
Chris Lattner05a32c82009-09-20 01:22:16 +0000114 size_t Count = 0;
115 size_t N = Str.size();
116 if (N > Length)
117 return 0;
118 for (size_t i = 0, e = Length - N + 1; i != e; ++i)
119 if (substr(i, N).equals(Str))
120 ++Count;
121 return Count;
122}
123
Chris Lattner63c6b7d2009-09-19 23:58:48 +0000124/// GetAsUnsignedInteger - Workhorse method that converts a integer character
125/// sequence of radix up to 36 to an unsigned long long value.
Chris Lattnercea14382009-09-19 19:47:14 +0000126static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix,
127 unsigned long long &Result) {
128 // Autosense radix if not specified.
129 if (Radix == 0) {
Chris Lattner6441e542009-09-20 22:56:43 +0000130 if (Str.startswith("0x")) {
131 Str = Str.substr(2);
132 Radix = 16;
133 } else if (Str.startswith("0b")) {
134 Str = Str.substr(2);
135 Radix = 2;
136 } else if (Str.startswith("0"))
137 Radix = 8;
138 else
Chris Lattnercea14382009-09-19 19:47:14 +0000139 Radix = 10;
Chris Lattnercea14382009-09-19 19:47:14 +0000140 }
141
142 // Empty strings (after the radix autosense) are invalid.
143 if (Str.empty()) return true;
144
145 // Parse all the bytes of the string given this radix. Watch for overflow.
146 Result = 0;
147 while (!Str.empty()) {
148 unsigned CharVal;
149 if (Str[0] >= '0' && Str[0] <= '9')
150 CharVal = Str[0]-'0';
151 else if (Str[0] >= 'a' && Str[0] <= 'z')
152 CharVal = Str[0]-'a'+10;
153 else if (Str[0] >= 'A' && Str[0] <= 'Z')
154 CharVal = Str[0]-'A'+10;
155 else
156 return true;
157
158 // If the parsed value is larger than the integer radix, the string is
159 // invalid.
160 if (CharVal >= Radix)
161 return true;
162
163 // Add in this character.
164 unsigned long long PrevResult = Result;
165 Result = Result*Radix+CharVal;
166
167 // Check for overflow.
168 if (Result < PrevResult)
169 return true;
170
171 Str = Str.substr(1);
172 }
173
174 return false;
175}
176
177bool StringRef::getAsInteger(unsigned Radix, unsigned long long &Result) const {
178 return GetAsUnsignedInteger(*this, Radix, Result);
179}
180
Chris Lattner63c6b7d2009-09-19 23:58:48 +0000181
182bool StringRef::getAsInteger(unsigned Radix, long long &Result) const {
183 unsigned long long ULLVal;
184
185 // Handle positive strings first.
186 if (empty() || front() != '-') {
187 if (GetAsUnsignedInteger(*this, Radix, ULLVal) ||
188 // Check for value so large it overflows a signed value.
189 (long long)ULLVal < 0)
190 return true;
191 Result = ULLVal;
192 return false;
193 }
194
195 // Get the positive part of the value.
196 if (GetAsUnsignedInteger(substr(1), Radix, ULLVal) ||
197 // Reject values so large they'd overflow as negative signed, but allow
198 // "-0". This negates the unsigned so that the negative isn't undefined
199 // on signed overflow.
200 (long long)-ULLVal > 0)
201 return true;
202
203 Result = -ULLVal;
204 return false;
205}
206
207bool StringRef::getAsInteger(unsigned Radix, int &Result) const {
208 long long Val;
209 if (getAsInteger(Radix, Val) ||
210 (int)Val != Val)
211 return true;
212 Result = Val;
213 return false;
214}
215
216bool StringRef::getAsInteger(unsigned Radix, unsigned &Result) const {
217 unsigned long long Val;
218 if (getAsInteger(Radix, Val) ||
219 (unsigned)Val != Val)
220 return true;
221 Result = Val;
222 return false;
223}