diff options
author | Chris Lattner <sabre@nondot.org> | 2009-09-19 19:47:14 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-09-19 19:47:14 +0000 |
commit | cea1438cf59c7cd3a632d61d78e68589315510d3 (patch) | |
tree | 59ff6f2ac9629a3a80cafa04852f75b6b5f734ad /lib | |
parent | c2fc1fec6c8c5360828aa778e8fcc446bb9c6ae9 (diff) | |
download | external_llvm-cea1438cf59c7cd3a632d61d78e68589315510d3.zip external_llvm-cea1438cf59c7cd3a632d61d78e68589315510d3.tar.gz external_llvm-cea1438cf59c7cd3a632d61d78e68589315510d3.tar.bz2 |
provide a "strtoull" operation that works on StringRef's.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82322 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Support/StringRef.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp index 4751f06..2e7d3c0 100644 --- a/lib/Support/StringRef.cpp +++ b/lib/Support/StringRef.cpp @@ -11,3 +11,66 @@ using namespace llvm; const size_t StringRef::npos; + +static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix, + unsigned long long &Result) { + // Autosense radix if not specified. + if (Radix == 0) { + if (Str[0] != '0') { + Radix = 10; + } else { + if (Str.size() < 2) { + Radix = 8; + } else { + if (Str[1] == 'x') { + Str = Str.substr(2); + Radix = 16; + } else if (Str[1] == 'b') { + Str = Str.substr(2); + Radix = 2; + } else { + Radix = 8; + } + } + } + } + + // Empty strings (after the radix autosense) are invalid. + if (Str.empty()) return true; + + // Parse all the bytes of the string given this radix. Watch for overflow. + Result = 0; + while (!Str.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; + else + return true; + + // If the parsed value is larger than the integer radix, the string is + // invalid. + if (CharVal >= Radix) + return true; + + // Add in this character. + unsigned long long PrevResult = Result; + Result = Result*Radix+CharVal; + + // Check for overflow. + if (Result < PrevResult) + return true; + + Str = Str.substr(1); + } + + return false; +} + +bool StringRef::getAsInteger(unsigned Radix, unsigned long long &Result) const { + return GetAsUnsignedInteger(*this, Radix, Result); +} + |