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