1193323Sed//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements the format() function, which can be used with other 11193323Sed// LLVM subsystems to provide printf-style formatting. This gives all the power 12193323Sed// and risk of printf. This can be used like this (with raw_ostreams as an 13193323Sed// example): 14193323Sed// 15193323Sed// OS << "mynumber: " << format("%4.5f", 1234.412) << '\n'; 16193323Sed// 17193323Sed// Or if you prefer: 18193323Sed// 19193323Sed// OS << format("mynumber: %4.5f\n", 1234.412); 20193323Sed// 21193323Sed//===----------------------------------------------------------------------===// 22193323Sed 23193323Sed#ifndef LLVM_SUPPORT_FORMAT_H 24193323Sed#define LLVM_SUPPORT_FORMAT_H 25193323Sed 26198953Srdivacky#include <cassert> 27193323Sed#include <cstdio> 28201360Srdivacky#ifdef _MSC_VER 29201360Srdivacky// FIXME: This define is wrong: 30201360Srdivacky// - _snprintf does not guarantee that trailing null is always added - if 31201360Srdivacky// there is no space for null, it does not report any error. 32201360Srdivacky// - According to C++ standard, snprintf should be visible in the 'std' 33201360Srdivacky// namespace - this define makes this impossible. 34193323Sed#define snprintf _snprintf 35193323Sed#endif 36193323Sed 37193323Sednamespace llvm { 38193323Sed 39193323Sed/// format_object_base - This is a helper class used for handling formatted 40193323Sed/// output. It is the abstract base class of a templated derived class. 41193323Sedclass format_object_base { 42193323Sedprotected: 43193323Sed const char *Fmt; 44193323Sed virtual void home(); // Out of line virtual method. 45198090Srdivacky 46198090Srdivacky /// snprint - Call snprintf() for this object, on the given buffer and size. 47198090Srdivacky virtual int snprint(char *Buffer, unsigned BufferSize) const = 0; 48198090Srdivacky 49193323Sedpublic: 50193323Sed format_object_base(const char *fmt) : Fmt(fmt) {} 51193323Sed virtual ~format_object_base() {} 52193323Sed 53193323Sed /// print - Format the object into the specified buffer. On success, this 54193323Sed /// returns the length of the formatted string. If the buffer is too small, 55193323Sed /// this returns a length to retry with, which will be larger than BufferSize. 56198090Srdivacky unsigned print(char *Buffer, unsigned BufferSize) const { 57198090Srdivacky assert(BufferSize && "Invalid buffer size!"); 58198090Srdivacky 59198090Srdivacky // Print the string, leaving room for the terminating null. 60198090Srdivacky int N = snprint(Buffer, BufferSize); 61198090Srdivacky 62198090Srdivacky // VC++ and old GlibC return negative on overflow, just double the size. 63198090Srdivacky if (N < 0) 64198090Srdivacky return BufferSize*2; 65198090Srdivacky 66198090Srdivacky // Other impls yield number of bytes needed, not including the final '\0'. 67198090Srdivacky if (unsigned(N) >= BufferSize) 68198090Srdivacky return N+1; 69198090Srdivacky 70198090Srdivacky // Otherwise N is the length of output (not including the final '\0'). 71198090Srdivacky return N; 72198090Srdivacky } 73193323Sed}; 74193323Sed 75193323Sed/// format_object1 - This is a templated helper class used by the format 76193323Sed/// function that captures the object to be formated and the format string. When 77193323Sed/// actually printed, this synthesizes the string into a temporary buffer 78193323Sed/// provided and returns whether or not it is big enough. 79193323Sedtemplate <typename T> 80193323Sedclass format_object1 : public format_object_base { 81193323Sed T Val; 82193323Sedpublic: 83193323Sed format_object1(const char *fmt, const T &val) 84193323Sed : format_object_base(fmt), Val(val) { 85193323Sed } 86193323Sed 87198090Srdivacky virtual int snprint(char *Buffer, unsigned BufferSize) const { 88198090Srdivacky return snprintf(Buffer, BufferSize, Fmt, Val); 89193323Sed } 90193323Sed}; 91193323Sed 92193323Sed/// format_object2 - This is a templated helper class used by the format 93193323Sed/// function that captures the object to be formated and the format string. When 94193323Sed/// actually printed, this synthesizes the string into a temporary buffer 95193323Sed/// provided and returns whether or not it is big enough. 96193323Sedtemplate <typename T1, typename T2> 97193323Sedclass format_object2 : public format_object_base { 98193323Sed T1 Val1; 99193323Sed T2 Val2; 100193323Sedpublic: 101193323Sed format_object2(const char *fmt, const T1 &val1, const T2 &val2) 102193323Sed : format_object_base(fmt), Val1(val1), Val2(val2) { 103193323Sed } 104193323Sed 105198090Srdivacky virtual int snprint(char *Buffer, unsigned BufferSize) const { 106198090Srdivacky return snprintf(Buffer, BufferSize, Fmt, Val1, Val2); 107193323Sed } 108193323Sed}; 109193323Sed 110193323Sed/// format_object3 - This is a templated helper class used by the format 111193323Sed/// function that captures the object to be formated and the format string. When 112193323Sed/// actually printed, this synthesizes the string into a temporary buffer 113193323Sed/// provided and returns whether or not it is big enough. 114193323Sedtemplate <typename T1, typename T2, typename T3> 115193323Sedclass format_object3 : public format_object_base { 116193323Sed T1 Val1; 117193323Sed T2 Val2; 118193323Sed T3 Val3; 119193323Sedpublic: 120193323Sed format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3) 121193323Sed : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) { 122193323Sed } 123193323Sed 124198090Srdivacky virtual int snprint(char *Buffer, unsigned BufferSize) const { 125198090Srdivacky return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3); 126193323Sed } 127193323Sed}; 128193323Sed 129226633Sdim/// format_object4 - This is a templated helper class used by the format 130226633Sdim/// function that captures the object to be formated and the format string. When 131226633Sdim/// actually printed, this synthesizes the string into a temporary buffer 132226633Sdim/// provided and returns whether or not it is big enough. 133226633Sdimtemplate <typename T1, typename T2, typename T3, typename T4> 134226633Sdimclass format_object4 : public format_object_base { 135226633Sdim T1 Val1; 136226633Sdim T2 Val2; 137226633Sdim T3 Val3; 138226633Sdim T4 Val4; 139226633Sdimpublic: 140226633Sdim format_object4(const char *fmt, const T1 &val1, const T2 &val2, 141226633Sdim const T3 &val3, const T4 &val4) 142226633Sdim : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) { 143226633Sdim } 144226633Sdim 145226633Sdim virtual int snprint(char *Buffer, unsigned BufferSize) const { 146226633Sdim return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4); 147226633Sdim } 148226633Sdim}; 149226633Sdim 150226633Sdim/// format_object5 - This is a templated helper class used by the format 151226633Sdim/// function that captures the object to be formated and the format string. When 152226633Sdim/// actually printed, this synthesizes the string into a temporary buffer 153226633Sdim/// provided and returns whether or not it is big enough. 154226633Sdimtemplate <typename T1, typename T2, typename T3, typename T4, typename T5> 155226633Sdimclass format_object5 : public format_object_base { 156226633Sdim T1 Val1; 157226633Sdim T2 Val2; 158226633Sdim T3 Val3; 159226633Sdim T4 Val4; 160226633Sdim T5 Val5; 161226633Sdimpublic: 162226633Sdim format_object5(const char *fmt, const T1 &val1, const T2 &val2, 163226633Sdim const T3 &val3, const T4 &val4, const T5 &val5) 164226633Sdim : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4), 165226633Sdim Val5(val5) { 166226633Sdim } 167226633Sdim 168226633Sdim virtual int snprint(char *Buffer, unsigned BufferSize) const { 169226633Sdim return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5); 170226633Sdim } 171226633Sdim}; 172226633Sdim 173243830Sdim/// This is a helper function that is used to produce formatted output. 174243830Sdim/// 175243830Sdim/// This is typically used like: 176243830Sdim/// \code 177243830Sdim/// OS << format("%0.4f", myfloat) << '\n'; 178243830Sdim/// \endcode 179193323Sedtemplate <typename T> 180193323Sedinline format_object1<T> format(const char *Fmt, const T &Val) { 181193323Sed return format_object1<T>(Fmt, Val); 182193323Sed} 183193323Sed 184243830Sdim/// This is a helper function that is used to produce formatted output. 185243830Sdim/// 186243830Sdim/// This is typically used like: 187243830Sdim/// \code 188243830Sdim/// OS << format("%0.4f", myfloat) << '\n'; 189243830Sdim/// \endcode 190193323Sedtemplate <typename T1, typename T2> 191193323Sedinline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1, 192193323Sed const T2 &Val2) { 193193323Sed return format_object2<T1, T2>(Fmt, Val1, Val2); 194193323Sed} 195193323Sed 196243830Sdim/// This is a helper function that is used to produce formatted output. 197243830Sdim/// 198243830Sdim/// This is typically used like: 199243830Sdim/// \code 200243830Sdim/// OS << format("%0.4f", myfloat) << '\n'; 201243830Sdim/// \endcode 202193323Sedtemplate <typename T1, typename T2, typename T3> 203193323Sed inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1, 204193323Sed const T2 &Val2, const T3 &Val3) { 205193323Sed return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3); 206193323Sed} 207193323Sed 208243830Sdim/// This is a helper function that is used to produce formatted output. 209243830Sdim/// 210243830Sdim/// This is typically used like: 211243830Sdim/// \code 212243830Sdim/// OS << format("%0.4f", myfloat) << '\n'; 213243830Sdim/// \endcode 214226633Sdimtemplate <typename T1, typename T2, typename T3, typename T4> 215226633Sdiminline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1, 216226633Sdim const T2 &Val2, const T3 &Val3, 217226633Sdim const T4 &Val4) { 218226633Sdim return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4); 219226633Sdim} 220226633Sdim 221243830Sdim/// This is a helper function that is used to produce formatted output. 222243830Sdim/// 223243830Sdim/// This is typically used like: 224243830Sdim/// \code 225243830Sdim/// OS << format("%0.4f", myfloat) << '\n'; 226243830Sdim/// \endcode 227226633Sdimtemplate <typename T1, typename T2, typename T3, typename T4, typename T5> 228226633Sdiminline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1, 229226633Sdim const T2 &Val2, const T3 &Val3, 230226633Sdim const T4 &Val4, const T5 &Val5) { 231226633Sdim return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5); 232226633Sdim} 233226633Sdim 234193323Sed} // end namespace llvm 235193323Sed 236193323Sed#endif 237