blob: 4c427012b13e0cb2d1245176cad97e3244b5a66c [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
13const size_t StringRef::npos;
Chris Lattnercea14382009-09-19 19:47:14 +000014
Chris Lattner63c6b7d2009-09-19 23:58:48 +000015/// GetAsUnsignedInteger - Workhorse method that converts a integer character
16/// sequence of radix up to 36 to an unsigned long long value.
Chris Lattnercea14382009-09-19 19:47:14 +000017static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix,
18 unsigned long long &Result) {
19 // Autosense radix if not specified.
20 if (Radix == 0) {
21 if (Str[0] != '0') {
22 Radix = 10;
23 } else {
24 if (Str.size() < 2) {
25 Radix = 8;
26 } else {
27 if (Str[1] == 'x') {
28 Str = Str.substr(2);
29 Radix = 16;
30 } else if (Str[1] == 'b') {
31 Str = Str.substr(2);
32 Radix = 2;
33 } else {
34 Radix = 8;
35 }
36 }
37 }
38 }
39
40 // Empty strings (after the radix autosense) are invalid.
41 if (Str.empty()) return true;
42
43 // Parse all the bytes of the string given this radix. Watch for overflow.
44 Result = 0;
45 while (!Str.empty()) {
46 unsigned CharVal;
47 if (Str[0] >= '0' && Str[0] <= '9')
48 CharVal = Str[0]-'0';
49 else if (Str[0] >= 'a' && Str[0] <= 'z')
50 CharVal = Str[0]-'a'+10;
51 else if (Str[0] >= 'A' && Str[0] <= 'Z')
52 CharVal = Str[0]-'A'+10;
53 else
54 return true;
55
56 // If the parsed value is larger than the integer radix, the string is
57 // invalid.
58 if (CharVal >= Radix)
59 return true;
60
61 // Add in this character.
62 unsigned long long PrevResult = Result;
63 Result = Result*Radix+CharVal;
64
65 // Check for overflow.
66 if (Result < PrevResult)
67 return true;
68
69 Str = Str.substr(1);
70 }
71
72 return false;
73}
74
75bool StringRef::getAsInteger(unsigned Radix, unsigned long long &Result) const {
76 return GetAsUnsignedInteger(*this, Radix, Result);
77}
78
Chris Lattner63c6b7d2009-09-19 23:58:48 +000079
80bool StringRef::getAsInteger(unsigned Radix, long long &Result) const {
81 unsigned long long ULLVal;
82
83 // Handle positive strings first.
84 if (empty() || front() != '-') {
85 if (GetAsUnsignedInteger(*this, Radix, ULLVal) ||
86 // Check for value so large it overflows a signed value.
87 (long long)ULLVal < 0)
88 return true;
89 Result = ULLVal;
90 return false;
91 }
92
93 // Get the positive part of the value.
94 if (GetAsUnsignedInteger(substr(1), Radix, ULLVal) ||
95 // Reject values so large they'd overflow as negative signed, but allow
96 // "-0". This negates the unsigned so that the negative isn't undefined
97 // on signed overflow.
98 (long long)-ULLVal > 0)
99 return true;
100
101 Result = -ULLVal;
102 return false;
103}
104
105bool StringRef::getAsInteger(unsigned Radix, int &Result) const {
106 long long Val;
107 if (getAsInteger(Radix, Val) ||
108 (int)Val != Val)
109 return true;
110 Result = Val;
111 return false;
112}
113
114bool StringRef::getAsInteger(unsigned Radix, unsigned &Result) const {
115 unsigned long long Val;
116 if (getAsInteger(Radix, Val) ||
117 (unsigned)Val != Val)
118 return true;
119 Result = Val;
120 return false;
121}