X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FFormat.h;h=aaa54e1090a6d6622c525867c009703b13cd51c2;hb=717a142823f84bd3aa958755ead1d991860ca8f4;hp=2ab097faf56d97b8624707acc517fb0f9556d972;hpb=7af924839140d185e4da9fa5f86a01163b0691c0;p=oota-llvm.git diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index 2ab097faf56..aaa54e1090a 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -23,8 +23,14 @@ #ifndef LLVM_SUPPORT_FORMAT_H #define LLVM_SUPPORT_FORMAT_H +#include #include -#ifdef WIN32 +#ifdef _MSC_VER +// FIXME: This define is wrong: +// - _snprintf does not guarantee that trailing null is always added - if +// there is no space for null, it does not report any error. +// - According to C++ standard, snprintf should be visible in the 'std' +// namespace - this define makes this impossible. #define snprintf _snprintf #endif @@ -36,6 +42,10 @@ class format_object_base { protected: const char *Fmt; virtual void home(); // Out of line virtual method. + + /// snprint - Call snprintf() for this object, on the given buffer and size. + virtual int snprint(char *Buffer, unsigned BufferSize) const = 0; + public: format_object_base(const char *fmt) : Fmt(fmt) {} virtual ~format_object_base() {} @@ -43,7 +53,23 @@ public: /// print - Format the object into the specified buffer. On success, this /// returns the length of the formatted string. If the buffer is too small, /// this returns a length to retry with, which will be larger than BufferSize. - virtual unsigned print(char *Buffer, unsigned BufferSize) const = 0; + unsigned print(char *Buffer, unsigned BufferSize) const { + assert(BufferSize && "Invalid buffer size!"); + + // Print the string, leaving room for the terminating null. + int N = snprint(Buffer, BufferSize); + + // VC++ and old GlibC return negative on overflow, just double the size. + if (N < 0) + return BufferSize*2; + + // Other impls yield number of bytes needed, not including the final '\0'. + if (unsigned(N) >= BufferSize) + return N+1; + + // Otherwise N is the length of output (not including the final '\0'). + return N; + } }; /// format_object1 - This is a templated helper class used by the format @@ -58,17 +84,8 @@ public: : format_object_base(fmt), Val(val) { } - /// print - Format the object into the specified buffer. On success, this - /// returns the length of the formatted string. If the buffer is too small, - /// this returns a length to retry with, which will be larger than BufferSize. - virtual unsigned print(char *Buffer, unsigned BufferSize) const { - int N = snprintf(Buffer, BufferSize-1, Fmt, Val); - if (N < 0) // VC++ and old GlibC return negative on overflow. - return BufferSize*2; - if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed. - return N+1; - // If N is positive and <= BufferSize-1, then the string fit, yay. - return N; + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val); } }; @@ -85,17 +102,8 @@ public: : format_object_base(fmt), Val1(val1), Val2(val2) { } - /// print - Format the object into the specified buffer. On success, this - /// returns the length of the formatted string. If the buffer is too small, - /// this returns a length to retry with, which will be larger than BufferSize. - virtual unsigned print(char *Buffer, unsigned BufferSize) const { - int N = snprintf(Buffer, BufferSize-1, Fmt, Val1, Val2); - if (N < 0) // VC++ and old GlibC return negative on overflow. - return BufferSize*2; - if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed. - return N+1; - // If N is positive and <= BufferSize-1, then the string fit, yay. - return N; + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2); } }; @@ -113,43 +121,116 @@ public: : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) { } - /// print - Format the object into the specified buffer. On success, this - /// returns the length of the formatted string. If the buffer is too small, - /// this returns a length to retry with, which will be larger than BufferSize. - virtual unsigned print(char *Buffer, unsigned BufferSize) const { - int N = snprintf(Buffer, BufferSize-1, Fmt, Val1, Val2, Val3); - if (N < 0) // VC++ and old GlibC return negative on overflow. - return BufferSize*2; - if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed. - return N+1; - // If N is positive and <= BufferSize-1, then the string fit, yay. - return N; + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3); } }; -/// format - This is a helper function that is used to produce formatted output. -/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +/// format_object4 - This is a templated helper class used by the format +/// function that captures the object to be formated and the format string. When +/// actually printed, this synthesizes the string into a temporary buffer +/// provided and returns whether or not it is big enough. +template +class format_object4 : public format_object_base { + T1 Val1; + T2 Val2; + T3 Val3; + T4 Val4; +public: + format_object4(const char *fmt, const T1 &val1, const T2 &val2, + const T3 &val3, const T4 &val4) + : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) { + } + + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4); + } +}; + +/// format_object5 - This is a templated helper class used by the format +/// function that captures the object to be formated and the format string. When +/// actually printed, this synthesizes the string into a temporary buffer +/// provided and returns whether or not it is big enough. +template +class format_object5 : public format_object_base { + T1 Val1; + T2 Val2; + T3 Val3; + T4 Val4; + T5 Val5; +public: + format_object5(const char *fmt, const T1 &val1, const T2 &val2, + const T3 &val3, const T4 &val4, const T5 &val5) + : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4), + Val5(val5) { + } + + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5); + } +}; + +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode template inline format_object1 format(const char *Fmt, const T &Val) { return format_object1(Fmt, Val); } -/// format - This is a helper function that is used to produce formatted output. -/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode template inline format_object2 format(const char *Fmt, const T1 &Val1, const T2 &Val2) { return format_object2(Fmt, Val1, Val2); } -/// format - This is a helper function that is used to produce formatted output. -/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode template inline format_object3 format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3) { return format_object3(Fmt, Val1, Val2, Val3); } +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode +template +inline format_object4 format(const char *Fmt, const T1 &Val1, + const T2 &Val2, const T3 &Val3, + const T4 &Val4) { + return format_object4(Fmt, Val1, Val2, Val3, Val4); +} + +/// This is a helper function that is used to produce formatted output. +/// +/// This is typically used like: +/// \code +/// OS << format("%0.4f", myfloat) << '\n'; +/// \endcode +template +inline format_object5 format(const char *Fmt,const T1 &Val1, + const T2 &Val2, const T3 &Val3, + const T4 &Val4, const T5 &Val5) { + return format_object5(Fmt, Val1, Val2, Val3, Val4, Val5); +} + } // end namespace llvm #endif