1 //===- Format.h - Efficient printf-style formatting for streams -*- 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 implements the format() function, which can be used with other 11 // LLVM subsystems to provide printf-style formatting. This gives all the power 12 // and risk of printf. This can be used like this (with raw_ostreams as an 13 // example): 14 // 15 // OS << "mynumber: " << format("%4.5f", 1234.412) << '\n'; 16 // 17 // Or if you prefer: 18 // 19 // OS << format("mynumber: %4.5f\n", 1234.412); 20 // 21 //===----------------------------------------------------------------------===// 22 23 #ifndef LLVM_SUPPORT_FORMAT_H 24 #define LLVM_SUPPORT_FORMAT_H 25 26 #include <cassert> 27 #include <cstdio> 28 #ifdef _MSC_VER 29 // FIXME: This define is wrong: 30 // - _snprintf does not guarantee that trailing null is always added - if 31 // there is no space for null, it does not report any error. 32 // - According to C++ standard, snprintf should be visible in the 'std' 33 // namespace - this define makes this impossible. 34 #define snprintf _snprintf 35 #endif 36 37 namespace llvm { 38 39 /// format_object_base - This is a helper class used for handling formatted 40 /// output. It is the abstract base class of a templated derived class. 41 class format_object_base { 42 protected: 43 const char *Fmt; 44 virtual void home(); // Out of line virtual method. 45 46 /// snprint - Call snprintf() for this object, on the given buffer and size. 47 virtual int snprint(char *Buffer, unsigned BufferSize) const = 0; 48 49 public: 50 format_object_base(const char *fmt) : Fmt(fmt) {} 51 virtual ~format_object_base() {} 52 53 /// print - Format the object into the specified buffer. On success, this 54 /// returns the length of the formatted string. If the buffer is too small, 55 /// this returns a length to retry with, which will be larger than BufferSize. 56 unsigned print(char *Buffer, unsigned BufferSize) const { 57 assert(BufferSize && "Invalid buffer size!"); 58 59 // Print the string, leaving room for the terminating null. 60 int N = snprint(Buffer, BufferSize); 61 62 // VC++ and old GlibC return negative on overflow, just double the size. 63 if (N < 0) 64 return BufferSize*2; 65 66 // Other impls yield number of bytes needed, not including the final '\0'. 67 if (unsigned(N) >= BufferSize) 68 return N+1; 69 70 // Otherwise N is the length of output (not including the final '\0'). 71 return N; 72 } 73 }; 74 75 /// format_object1 - This is a templated helper class used by the format 76 /// function that captures the object to be formated and the format string. When 77 /// actually printed, this synthesizes the string into a temporary buffer 78 /// provided and returns whether or not it is big enough. 79 template <typename T> 80 class format_object1 : public format_object_base { 81 T Val; 82 public: 83 format_object1(const char *fmt, const T &val) 84 : format_object_base(fmt), Val(val) { 85 } 86 87 virtual int snprint(char *Buffer, unsigned BufferSize) const { 88 return snprintf(Buffer, BufferSize, Fmt, Val); 89 } 90 }; 91 92 /// format_object2 - This is a templated helper class used by the format 93 /// function that captures the object to be formated and the format string. When 94 /// actually printed, this synthesizes the string into a temporary buffer 95 /// provided and returns whether or not it is big enough. 96 template <typename T1, typename T2> 97 class format_object2 : public format_object_base { 98 T1 Val1; 99 T2 Val2; 100 public: 101 format_object2(const char *fmt, const T1 &val1, const T2 &val2) 102 : format_object_base(fmt), Val1(val1), Val2(val2) { 103 } 104 105 virtual int snprint(char *Buffer, unsigned BufferSize) const { 106 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2); 107 } 108 }; 109 110 /// format_object3 - This is a templated helper class used by the format 111 /// function that captures the object to be formated and the format string. When 112 /// actually printed, this synthesizes the string into a temporary buffer 113 /// provided and returns whether or not it is big enough. 114 template <typename T1, typename T2, typename T3> 115 class format_object3 : public format_object_base { 116 T1 Val1; 117 T2 Val2; 118 T3 Val3; 119 public: 120 format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3) 121 : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) { 122 } 123 124 virtual int snprint(char *Buffer, unsigned BufferSize) const { 125 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3); 126 } 127 }; 128 129 /// format_object4 - This is a templated helper class used by the format 130 /// function that captures the object to be formated and the format string. When 131 /// actually printed, this synthesizes the string into a temporary buffer 132 /// provided and returns whether or not it is big enough. 133 template <typename T1, typename T2, typename T3, typename T4> 134 class format_object4 : public format_object_base { 135 T1 Val1; 136 T2 Val2; 137 T3 Val3; 138 T4 Val4; 139 public: 140 format_object4(const char *fmt, const T1 &val1, const T2 &val2, 141 const T3 &val3, const T4 &val4) 142 : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) { 143 } 144 145 virtual int snprint(char *Buffer, unsigned BufferSize) const { 146 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4); 147 } 148 }; 149 150 /// format_object5 - This is a templated helper class used by the format 151 /// function that captures the object to be formated and the format string. When 152 /// actually printed, this synthesizes the string into a temporary buffer 153 /// provided and returns whether or not it is big enough. 154 template <typename T1, typename T2, typename T3, typename T4, typename T5> 155 class format_object5 : public format_object_base { 156 T1 Val1; 157 T2 Val2; 158 T3 Val3; 159 T4 Val4; 160 T5 Val5; 161 public: 162 format_object5(const char *fmt, const T1 &val1, const T2 &val2, 163 const T3 &val3, const T4 &val4, const T5 &val5) 164 : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4), 165 Val5(val5) { 166 } 167 168 virtual int snprint(char *Buffer, unsigned BufferSize) const { 169 return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5); 170 } 171 }; 172 173 /// This is a helper function that is used to produce formatted output. 174 /// 175 /// This is typically used like: 176 /// \code 177 /// OS << format("%0.4f", myfloat) << '\n'; 178 /// \endcode 179 template <typename T> 180 inline format_object1<T> format(const char *Fmt, const T &Val) { 181 return format_object1<T>(Fmt, Val); 182 } 183 184 /// This is a helper function that is used to produce formatted output. 185 /// 186 /// This is typically used like: 187 /// \code 188 /// OS << format("%0.4f", myfloat) << '\n'; 189 /// \endcode 190 template <typename T1, typename T2> 191 inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1, 192 const T2 &Val2) { 193 return format_object2<T1, T2>(Fmt, Val1, Val2); 194 } 195 196 /// This is a helper function that is used to produce formatted output. 197 /// 198 /// This is typically used like: 199 /// \code 200 /// OS << format("%0.4f", myfloat) << '\n'; 201 /// \endcode 202 template <typename T1, typename T2, typename T3> 203 inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1, 204 const T2 &Val2, const T3 &Val3) { 205 return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3); 206 } 207 208 /// This is a helper function that is used to produce formatted output. 209 /// 210 /// This is typically used like: 211 /// \code 212 /// OS << format("%0.4f", myfloat) << '\n'; 213 /// \endcode 214 template <typename T1, typename T2, typename T3, typename T4> 215 inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1, 216 const T2 &Val2, const T3 &Val3, 217 const T4 &Val4) { 218 return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4); 219 } 220 221 /// This is a helper function that is used to produce formatted output. 222 /// 223 /// This is typically used like: 224 /// \code 225 /// OS << format("%0.4f", myfloat) << '\n'; 226 /// \endcode 227 template <typename T1, typename T2, typename T3, typename T4, typename T5> 228 inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1, 229 const T2 &Val2, const T3 &Val3, 230 const T4 &Val4, const T5 &Val5) { 231 return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5); 232 } 233 234 } // end namespace llvm 235 236 #endif 237