From b2560526d5f6d2f9cc3698244dbb1f4861dc8efc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 23 Aug 2008 19:48:00 +0000 Subject: [PATCH] Split format() out to its own file, add support for formatting up to three values in one call. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55251 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/Format.h | 155 +++++++++++++++++++++++++++++ include/llvm/Support/raw_ostream.h | 60 +---------- 2 files changed, 156 insertions(+), 59 deletions(-) create mode 100644 include/llvm/Support/Format.h diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h new file mode 100644 index 00000000000..b08d6983588 --- /dev/null +++ b/include/llvm/Support/Format.h @@ -0,0 +1,155 @@ +//===--- Format.h - Efficient printf-style formatting for streams etc -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the format() function, which can be used with other +// LLVM subsystems to provide printf-style formatting. This gives all the power +// and risk of printf. This can be used like this (with raw_ostreams as an +// example): +// +// OS << "mynumber: " << format("%4.5f", 1234.412) << '\n'; +// +// Or if you prefer: +// +// OS << format("mynumber: %4.5f\n", 1234.412); +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_FORMAT_H +#define LLVM_SUPPORT_FORMAT_H + +#include +#ifdef WIN32 +#define snprintf _snprintf +#endif + +namespace llvm { + +/// format_object_base - This is a helper class used for handling formatted +/// output. It is the abstract base class of a templated derived class. +class format_object_base { +protected: + const char *Fmt; + virtual void home(); // Out of line virtual method. +public: + format_object_base(const char *fmt) : Fmt(fmt) {} + virtual ~format_object_base() {} + + /// 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; +}; + +/// format_object1 - 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_object1 : public format_object_base { + T Val; +public: + format_object1(const char *fmt, const T &val) + : 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; + } +}; + +/// format_object2 - 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_object2 : public format_object_base { + T1 Val1; + T2 Val2; +public: + format_object2(const char *fmt, const T1 &val1, const T2 &val2) + : 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; + } +}; + +/// format_object3 - 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_object3 : public format_object_base { + T1 Val1; + T2 Val2; + T3 Val3; +public: + format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3) + : 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; + } +}; + +/// format - This is a helper function that is used to produce formatted output. +/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +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'; +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'; +template + inline format_object3 format(const char *Fmt, const T1 &Val1, + const T2 &Val2, const T3 &Val3) { + return format_object3(Fmt, Val1, Val2, Val3); +} + +} // end namespace llvm + +#endif diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index db312f87358..e78cfe86417 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -17,7 +17,6 @@ #include "llvm/ADT/StringExtras.h" #include #include -#include #include #include @@ -112,7 +111,7 @@ public: raw_ostream &write(const char *Ptr, unsigned Size); - // Formatted output, see the format() function below. + // Formatted output, see the format() function in Support/Format.h. raw_ostream &operator<<(const format_object_base &Fmt); //===--------------------------------------------------------------------===// @@ -138,63 +137,6 @@ private: virtual void handle(); }; -//===----------------------------------------------------------------------===// -// Formatted Output -//===----------------------------------------------------------------------===// - -/// format_object_base - This is a helper class used for handling formatted -/// output. It is the abstract base class of a templated derived class. -class format_object_base { -protected: - const char *Fmt; - virtual void home(); // Out of line virtual method. -public: - format_object_base(const char *fmt) : Fmt(fmt) {} - virtual ~format_object_base() {} - - /// 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; -}; - -/// format_object - 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_object : public format_object_base { - T Val; -public: - format_object(const char *fmt, const T &val) - : 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 { -#ifdef WIN32 - int N = _snprintf(Buffer, BufferSize-1, Fmt, Val); -#else - int N = snprintf(Buffer, BufferSize-1, Fmt, Val); -#endif - 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; - } -}; - -/// format - This is a helper function that is used to produce formatted output. -/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; -template -inline format_object format(const char *Fmt, const T &Val) { - return format_object(Fmt, Val); -} - //===----------------------------------------------------------------------===// // File Output Streams //===----------------------------------------------------------------------===// -- 2.34.1