Add From arguments to StringRef search functions, and tweak doxyments.
[oota-llvm.git] / lib / Support / StringRef.cpp
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 }