899823d5c6c84e3a2310969d29f3fc62f4c75782
[oota-llvm.git] / include / llvm / ADT / StringExtras.h
1 //===-- llvm/ADT/StringExtras.h - Useful string functions -------*- C++ -*-===//
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 // This file contains some functions that are useful when dealing with strings.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ADT_STRINGEXTRAS_H
15 #define LLVM_ADT_STRINGEXTRAS_H
16
17 #include "llvm/Support/DataTypes.h"
18 #include "llvm/ADT/APFloat.h"
19 #include "llvm/ADT/StringRef.h"
20 #include <cctype>
21 #include <cstdio>
22 #include <string>
23 #include <vector>
24
25 namespace llvm {
26
27 /// hexdigit - Return the (uppercase) hexadecimal character for the
28 /// given number \arg X (which should be less than 16).
29 static inline char hexdigit(unsigned X) {
30   return X < 10 ? '0' + X : 'A' + X - 10;
31 }
32
33 /// utohex_buffer - Emit the specified number into the buffer specified by
34 /// BufferEnd, returning a pointer to the start of the string.  This can be used
35 /// like this: (note that the buffer must be large enough to handle any number):
36 ///    char Buffer[40];
37 ///    printf("0x%s", utohex_buffer(X, Buffer+40));
38 ///
39 /// This should only be used with unsigned types.
40 ///
41 template<typename IntTy>
42 static inline char *utohex_buffer(IntTy X, char *BufferEnd) {
43   char *BufPtr = BufferEnd;
44   *--BufPtr = 0;      // Null terminate buffer.
45   if (X == 0) {
46     *--BufPtr = '0';  // Handle special case.
47     return BufPtr;
48   }
49
50   while (X) {
51     unsigned char Mod = static_cast<unsigned char>(X) & 15;
52     *--BufPtr = hexdigit(Mod);
53     X >>= 4;
54   }
55   return BufPtr;
56 }
57
58 static inline std::string utohexstr(uint64_t X) {
59   char Buffer[40];
60   return utohex_buffer(X, Buffer+40);
61 }
62
63 static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
64   char Buffer[20];
65   char *BufPtr = Buffer+19;
66
67   *BufPtr = 0;                  // Null terminate buffer...
68   if (X == 0) *--BufPtr = '0';  // Handle special case...
69
70   while (X) {
71     *--BufPtr = '0' + char(X % 10);
72     X /= 10;
73   }
74
75   if (isNeg) *--BufPtr = '-';   // Add negative sign...
76
77   return std::string(BufPtr);
78 }
79
80 static inline std::string utostr(uint64_t X, bool isNeg = false) {
81   if (X == uint32_t(X))
82     return utostr_32(uint32_t(X), isNeg);
83
84   char Buffer[40];
85   char *BufPtr = Buffer+39;
86
87   *BufPtr = 0;                  // Null terminate buffer...
88   if (X == 0) *--BufPtr = '0';  // Handle special case...
89
90   while (X) {
91     *--BufPtr = '0' + char(X % 10);
92     X /= 10;
93   }
94
95   if (isNeg) *--BufPtr = '-';   // Add negative sign...
96   return std::string(BufPtr);
97 }
98
99
100 static inline std::string itostr(int64_t X) {
101   if (X < 0)
102     return utostr(static_cast<uint64_t>(-X), true);
103   else
104     return utostr(static_cast<uint64_t>(X));
105 }
106
107 static inline std::string ftostr(double V) {
108   char Buffer[200];
109   sprintf(Buffer, "%20.6e", V);
110   char *B = Buffer;
111   while (*B == ' ') ++B;
112   return B;
113 }
114
115 static inline std::string ftostr(const APFloat& V) {
116   if (&V.getSemantics() == &APFloat::IEEEdouble)
117     return ftostr(V.convertToDouble());
118   else if (&V.getSemantics() == &APFloat::IEEEsingle)
119     return ftostr((double)V.convertToFloat());
120   return "<unknown format in ftostr>"; // error
121 }
122
123 static inline std::string LowercaseString(const std::string &S) {
124   std::string result(S);
125   for (unsigned i = 0; i < S.length(); ++i)
126     if (isupper(result[i]))
127       result[i] = char(tolower(result[i]));
128   return result;
129 }
130
131 static inline std::string UppercaseString(const std::string &S) {
132   std::string result(S);
133   for (unsigned i = 0; i < S.length(); ++i)
134     if (islower(result[i]))
135       result[i] = char(toupper(result[i]));
136   return result;
137 }
138
139 /// StringsEqualNoCase - Return true if the two strings are equal, ignoring
140 /// case.
141 static inline bool StringsEqualNoCase(const std::string &LHS,
142                                       const std::string &RHS) {
143   if (LHS.size() != RHS.size()) return false;
144   for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i)
145     if (tolower(LHS[i]) != tolower(RHS[i])) return false;
146   return true;
147 }
148
149 /// StringsEqualNoCase - Return true if the two strings are equal, ignoring
150 /// case.
151 static inline bool StringsEqualNoCase(const std::string &LHS,
152                                       const char *RHS) {
153   for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i) {
154     if (RHS[i] == 0) return false;  // RHS too short.
155     if (tolower(LHS[i]) != tolower(RHS[i])) return false;
156   }
157   return RHS[LHS.size()] == 0;  // Not too long?
158 }
159   
160 /// StringsEqualNoCase - Return true if the two null-terminated C strings are
161 ///  equal, ignoring
162
163 static inline bool StringsEqualNoCase(const char *LHS, const char *RHS,
164                                       unsigned len) {
165
166   for (unsigned i = 0; i < len; ++i) {
167     if (tolower(LHS[i]) != tolower(RHS[i]))
168       return false;
169     
170     // If RHS[i] == 0 then LHS[i] == 0 or otherwise we would have returned
171     // at the previous branch as tolower('\0') == '\0'.
172     if (RHS[i] == 0)
173       return true;
174   }
175   
176   return true;
177 }
178
179 /// CStrInCStrNoCase - Portable version of strcasestr.  Locates the first
180 ///  occurance of c-string 's2' in string 's1', ignoring case.  Returns
181 ///  NULL if 's2' cannot be found.
182 static inline const char* CStrInCStrNoCase(const char *s1, const char *s2) {
183
184   // Are either strings NULL or empty?
185   if (!s1 || !s2 || s1[0] == '\0' || s2[0] == '\0')
186     return 0;
187
188   if (s1 == s2)
189     return s1;
190
191   const char *I1=s1, *I2=s2;
192
193   while (*I1 != '\0' && *I2 != '\0' )
194     if (tolower(*I1) != tolower(*I2)) { // No match.  Start over.
195       ++s1; I1 = s1; I2 = s2;
196     }
197     else { // Character match.  Advance to the next character.
198       ++I1; ++I2;
199     }
200
201   // If we exhausted all of the characters in 's2', then 's2' appears in 's1'.
202   return *I2 == '\0' ? s1 : 0;
203 }
204
205 /// getToken - This function extracts one token from source, ignoring any
206 /// leading characters that appear in the Delimiters string, and ending the
207 /// token at any of the characters that appear in the Delimiters string.  If
208 /// there are no tokens in the source string, an empty string is returned.
209 /// The Source source string is updated in place to remove the returned string
210 /// and any delimiter prefix from it.
211 std::string getToken(std::string &Source,
212                      const char *Delimiters = " \t\n\v\f\r");
213
214 /// SplitString - Split up the specified string according to the specified
215 /// delimiters, appending the result fragments to the output list.
216 void SplitString(const std::string &Source,
217                  std::vector<std::string> &OutFragments,
218                  const char *Delimiters = " \t\n\v\f\r");
219
220 /// HashString - Hash funtion for strings.
221 ///
222 /// This is the Bernstein hash function.
223 //
224 // FIXME: Investigate whether a modified bernstein hash function performs
225 // better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
226 //   X*33+c -> X*33^c
227 static inline unsigned HashString(StringRef Str, unsigned Result = 0) {
228   for (unsigned i = 0, e = Str.size(); i != e; ++i)
229     Result = Result * 33 + Str[i];
230   return Result;
231 }
232
233 } // End llvm namespace
234
235 #endif