summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/StringRef.cpp
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-09-22 15:05:19 +0000
committerZachary Turner <zturner@google.com>2016-09-22 15:05:19 +0000
commit65fd2fc7b407ca9dafc1b0a87df281b38e2eefb0 (patch)
tree79114f29c97d9e383c6ccefb5a090c5b7797eebf /llvm/lib/Support/StringRef.cpp
parent7f0e3153270d21d7931a18c2c0d4a2791103b52d (diff)
downloadbcm5719-llvm-65fd2fc7b407ca9dafc1b0a87df281b38e2eefb0.tar.gz
bcm5719-llvm-65fd2fc7b407ca9dafc1b0a87df281b38e2eefb0.zip
[Support] Add StringRef::consumeInteger.
StringRef::getInteger() exists and treats the entire string as an integer of the specified radix, failing if any invalid characters are encountered or the number overflows. Sometimes you might have something like "123456foo" and you want to get the number 123456 and leave the string "foo" remaining. This is similar to what would be possible by using the standard runtime library functions strtoul et al and specifying an end pointer. This patch adds consumeInteger(), which does exactly that. It consumes as much as possible until an invalid character is found, and modifies the StringRef in place so that upon return only the portion of the StringRef after the number remains. Differential Revision: https://reviews.llvm.org/D24778 llvm-svn: 282164
Diffstat (limited to 'llvm/lib/Support/StringRef.cpp')
-rw-r--r--llvm/lib/Support/StringRef.cpp80
1 files changed, 55 insertions, 25 deletions
diff --git a/llvm/lib/Support/StringRef.cpp b/llvm/lib/Support/StringRef.cpp
index 8a9da5edca8..7503fac240a 100644
--- a/llvm/lib/Support/StringRef.cpp
+++ b/llvm/lib/Support/StringRef.cpp
@@ -366,17 +366,16 @@ static unsigned GetAutoSenseRadix(StringRef &Str) {
return 8;
}
- if (Str.startswith("0"))
+ if (Str[0] == '0' && Str.size() > 1 && ascii_isdigit(Str[1])) {
+ Str = Str.substr(1);
return 8;
-
+ }
+
return 10;
}
-
-/// GetAsUnsignedInteger - Workhorse method that converts a integer character
-/// sequence of radix up to 36 to an unsigned long long value.
-bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
- unsigned long long &Result) {
+bool llvm::consumeUnsignedInteger(StringRef &Str, unsigned Radix,
+ unsigned long long &Result) {
// Autosense radix if not specified.
if (Radix == 0)
Radix = GetAutoSenseRadix(Str);
@@ -385,44 +384,51 @@ bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
if (Str.empty()) return true;
// Parse all the bytes of the string given this radix. Watch for overflow.
+ StringRef Str2 = Str;
Result = 0;
- while (!Str.empty()) {
+ while (!Str2.empty()) {
unsigned CharVal;
- if (Str[0] >= '0' && Str[0] <= '9')
- CharVal = Str[0]-'0';
- else if (Str[0] >= 'a' && Str[0] <= 'z')
- CharVal = Str[0]-'a'+10;
- else if (Str[0] >= 'A' && Str[0] <= 'Z')
- CharVal = Str[0]-'A'+10;
+ if (Str2[0] >= '0' && Str2[0] <= '9')
+ CharVal = Str2[0] - '0';
+ else if (Str2[0] >= 'a' && Str2[0] <= 'z')
+ CharVal = Str2[0] - 'a' + 10;
+ else if (Str2[0] >= 'A' && Str2[0] <= 'Z')
+ CharVal = Str2[0] - 'A' + 10;
else
- return true;
+ break;
- // If the parsed value is larger than the integer radix, the string is
- // invalid.
+ // If the parsed value is larger than the integer radix, we cannot
+ // consume any more characters.
if (CharVal >= Radix)
- return true;
+ break;
// Add in this character.
unsigned long long PrevResult = Result;
- Result = Result*Radix+CharVal;
+ Result = Result * Radix + CharVal;
// Check for overflow by shifting back and seeing if bits were lost.
- if (Result/Radix < PrevResult)
+ if (Result / Radix < PrevResult)
return true;
- Str = Str.substr(1);
+ Str2 = Str2.substr(1);
}
+ // We consider the operation a failure if no characters were consumed
+ // successfully.
+ if (Str.size() == Str2.size())
+ return true;
+
+ Str = Str2;
return false;
}
-bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
- long long &Result) {
+bool llvm::consumeSignedInteger(StringRef &Str, unsigned Radix,
+ long long &Result) {
unsigned long long ULLVal;
// Handle positive strings first.
if (Str.empty() || Str.front() != '-') {
- if (getAsUnsignedInteger(Str, Radix, ULLVal) ||
+ if (consumeUnsignedInteger(Str, Radix, ULLVal) ||
// Check for value so large it overflows a signed value.
(long long)ULLVal < 0)
return true;
@@ -431,17 +437,41 @@ bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
}
// Get the positive part of the value.
- if (getAsUnsignedInteger(Str.substr(1), Radix, ULLVal) ||
+ StringRef Str2 = Str.drop_front(1);
+ if (consumeUnsignedInteger(Str2, Radix, ULLVal) ||
// Reject values so large they'd overflow as negative signed, but allow
// "-0". This negates the unsigned so that the negative isn't undefined
// on signed overflow.
(long long)-ULLVal > 0)
return true;
+ Str = Str2;
Result = -ULLVal;
return false;
}
+/// GetAsUnsignedInteger - Workhorse method that converts a integer character
+/// sequence of radix up to 36 to an unsigned long long value.
+bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
+ unsigned long long &Result) {
+ if (consumeUnsignedInteger(Str, Radix, Result))
+ return true;
+
+ // For getAsUnsignedInteger, we require the whole string to be consumed or
+ // else we consider it a failure.
+ return !Str.empty();
+}
+
+bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
+ long long &Result) {
+ if (consumeSignedInteger(Str, Radix, Result))
+ return true;
+
+ // For getAsSignedInteger, we require the whole string to be consumed or else
+ // we consider it a failure.
+ return !Str.empty();
+}
+
bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
StringRef Str = *this;
OpenPOWER on IntegriCloud