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