StringExtras.h revision 30f100e14056c2fd88a3448c8bf89b656e7d8584
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 <cctype>
20#include <cstdio>
21#include <string>
22#include <vector>
23
24namespace llvm {
25
26/// hexdigit - Return the (uppercase) hexadecimal character for the
27/// given number \arg X (which should be less than 16).
28static inline char hexdigit(unsigned X) {
29  return X < 10 ? '0' + X : 'A' + X - 10;
30}
31
32static inline std::string utohexstr(uint64_t X) {
33  char Buffer[40];
34  char *BufPtr = Buffer+39;
35
36  *BufPtr = 0;                  // Null terminate buffer...
37  if (X == 0) *--BufPtr = '0';  // Handle special case...
38
39  while (X) {
40    unsigned char Mod = static_cast<unsigned char>(X) & 15;
41    *--BufPtr = hexdigit(Mod);
42    X >>= 4;
43  }
44  return std::string(BufPtr);
45}
46
47static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
48  char Buffer[20];
49  char *BufPtr = Buffer+19;
50
51  *BufPtr = 0;                  // Null terminate buffer...
52  if (X == 0) *--BufPtr = '0';  // Handle special case...
53
54  while (X) {
55    *--BufPtr = '0' + char(X % 10);
56    X /= 10;
57  }
58
59  if (isNeg) *--BufPtr = '-';   // Add negative sign...
60
61  return std::string(BufPtr);
62}
63
64static inline std::string utostr(uint64_t X, bool isNeg = false) {
65  if (X == uint32_t(X))
66    return utostr_32(uint32_t(X), isNeg);
67
68  char Buffer[40];
69  char *BufPtr = Buffer+39;
70
71  *BufPtr = 0;                  // Null terminate buffer...
72  if (X == 0) *--BufPtr = '0';  // Handle special case...
73
74  while (X) {
75    *--BufPtr = '0' + char(X % 10);
76    X /= 10;
77  }
78
79  if (isNeg) *--BufPtr = '-';   // Add negative sign...
80  return std::string(BufPtr);
81}
82
83
84static inline std::string itostr(int64_t X) {
85  if (X < 0)
86    return utostr(static_cast<uint64_t>(-X), true);
87  else
88    return utostr(static_cast<uint64_t>(X));
89}
90
91static inline std::string itohexstr(int64_t X) {
92  return utohexstr(static_cast<uint64_t>(X));
93}
94
95static inline std::string ftostr(double V) {
96  char Buffer[200];
97  sprintf(Buffer, "%20.6e", V);
98  char *B = Buffer;
99  while (*B == ' ') ++B;
100  return B;
101}
102
103static inline std::string ftostr(const APFloat& V) {
104  if (&V.getSemantics() == &APFloat::IEEEdouble)
105    return ftostr(V.convertToDouble());
106  else if (&V.getSemantics() == &APFloat::IEEEsingle)
107    return ftostr((double)V.convertToFloat());
108  return "<unknown format in ftostr>"; // error
109}
110
111static inline std::string LowercaseString(const std::string &S) {
112  std::string result(S);
113  for (unsigned i = 0; i < S.length(); ++i)
114    if (isupper(result[i]))
115      result[i] = char(tolower(result[i]));
116  return result;
117}
118
119static inline std::string UppercaseString(const std::string &S) {
120  std::string result(S);
121  for (unsigned i = 0; i < S.length(); ++i)
122    if (islower(result[i]))
123      result[i] = char(toupper(result[i]));
124  return result;
125}
126
127/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
128/// case.
129static inline bool StringsEqualNoCase(const std::string &LHS,
130                                      const std::string &RHS) {
131  if (LHS.size() != RHS.size()) return false;
132  for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i)
133    if (tolower(LHS[i]) != tolower(RHS[i])) return false;
134  return true;
135}
136
137/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
138/// case.
139static inline bool StringsEqualNoCase(const std::string &LHS,
140                                      const char *RHS) {
141  for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i) {
142    if (RHS[i] == 0) return false;  // RHS too short.
143    if (tolower(LHS[i]) != tolower(RHS[i])) return false;
144  }
145  return RHS[LHS.size()] == 0;  // Not too long?
146}
147
148/// CStrInCStrNoCase - Portable version of strcasestr.  Locates the first
149///  occurance of c-string 's2' in string 's1', ignoring case.  Returns
150///  NULL if 's2' cannot be found.
151static inline const char* CStrInCStrNoCase(const char *s1, const char *s2) {
152
153  // Are either strings NULL or empty?
154  if (!s1 || !s2 || s1[0] == '\0' || s2[0] == '\0')
155    return 0;
156
157  if (s1 == s2)
158    return s1;
159
160  const char *I1=s1, *I2=s2;
161
162  while (*I1 != '\0' && *I2 != '\0' )
163    if (tolower(*I1) != tolower(*I2)) { // No match.  Start over.
164      ++s1; I1 = s1; I2 = s2;
165    }
166    else { // Character match.  Advance to the next character.
167      ++I1; ++I2;
168    }
169
170  // If we exhausted all of the characters in 's2', then 's2' appears in 's1'.
171  return *I2 == '\0' ? s1 : 0;
172}
173
174/// getToken - This function extracts one token from source, ignoring any
175/// leading characters that appear in the Delimiters string, and ending the
176/// token at any of the characters that appear in the Delimiters string.  If
177/// there are no tokens in the source string, an empty string is returned.
178/// The Source source string is updated in place to remove the returned string
179/// and any delimiter prefix from it.
180std::string getToken(std::string &Source,
181                     const char *Delimiters = " \t\n\v\f\r");
182
183/// SplitString - Split up the specified string according to the specified
184/// delimiters, appending the result fragments to the output list.
185void SplitString(const std::string &Source,
186                 std::vector<std::string> &OutFragments,
187                 const char *Delimiters = " \t\n\v\f\r");
188
189/// UnescapeString - Modify the argument string, turning two character sequences
190/// like '\\' 'n' into '\n'.  This handles: \e \a \b \f \n \r \t \v \' \\ and
191/// \num (where num is a 1-3 byte octal value).
192void UnescapeString(std::string &Str);
193
194/// EscapeString - Modify the argument string, turning '\\' and anything that
195/// doesn't satisfy std::isprint into an escape sequence.
196void EscapeString(std::string &Str);
197
198} // End llvm namespace
199
200#endif
201