Format.h revision 360784
126209Swpaul//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===//
274462Salfred//
3258578Shrs// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4258578Shrs// See https://llvm.org/LICENSE.txt for license information.
5258578Shrs// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6258578Shrs//
7258578Shrs//===----------------------------------------------------------------------===//
8258578Shrs//
9258578Shrs// This file implements the format() function, which can be used with other
10258578Shrs// LLVM subsystems to provide printf-style formatting.  This gives all the power
11258578Shrs// and risk of printf.  This can be used like this (with raw_ostreams as an
12258578Shrs// example):
13258578Shrs//
14258578Shrs//    OS << "mynumber: " << format("%4.5f", 1234.412) << '\n';
15258578Shrs//
16258578Shrs// Or if you prefer:
17258578Shrs//
18258578Shrs//  OS << format("mynumber: %4.5f\n", 1234.412);
19258578Shrs//
20258578Shrs//===----------------------------------------------------------------------===//
21258578Shrs
22258578Shrs#ifndef LLVM_SUPPORT_FORMAT_H
23258578Shrs#define LLVM_SUPPORT_FORMAT_H
24258578Shrs
25258578Shrs#include "llvm/ADT/ArrayRef.h"
26258578Shrs#include "llvm/ADT/STLExtras.h"
27258578Shrs#include "llvm/ADT/StringRef.h"
28258578Shrs#include "llvm/Support/DataTypes.h"
2926209Swpaul#include <cassert>
3074462Salfred#include <cstdio>
3174462Salfred#include <tuple>
3226209Swpaul#include <utility>
3326209Swpaul
3426209Swpaulnamespace llvm {
3574462Salfred
3626209Swpaul/// This is a helper class used for handling formatted output.  It is the
3726209Swpaul/// abstract base class of a templated derived class.
3826209Swpaulclass format_object_base {
3926209Swpaulprotected:
4026209Swpaul  const char *Fmt;
4126209Swpaul  ~format_object_base() = default; // Disallow polymorphic deletion.
4226209Swpaul  format_object_base(const format_object_base &) = default;
4326209Swpaul  virtual void home(); // Out of line virtual method.
4426209Swpaul
4526209Swpaul  /// Call snprintf() for this object, on the given buffer and size.
4626209Swpaul  virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
4726209Swpaul
4826209Swpaulpublic:
4926209Swpaul  format_object_base(const char *fmt) : Fmt(fmt) {}
5026209Swpaul
5126209Swpaul  /// Format the object into the specified buffer.  On success, this returns
5226209Swpaul  /// the length of the formatted string.  If the buffer is too small, this
5326209Swpaul  /// returns a length to retry with, which will be larger than BufferSize.
5426209Swpaul  unsigned print(char *Buffer, unsigned BufferSize) const {
5526209Swpaul    assert(BufferSize && "Invalid buffer size!");
5626209Swpaul
5726209Swpaul    // Print the string, leaving room for the terminating null.
5826209Swpaul    int N = snprint(Buffer, BufferSize);
5926209Swpaul
6026209Swpaul    // VC++ and old GlibC return negative on overflow, just double the size.
6126209Swpaul    if (N < 0)
6226209Swpaul      return BufferSize * 2;
6326209Swpaul
6426209Swpaul    // Other implementations yield number of bytes needed, not including the
6526209Swpaul    // final '\0'.
6626209Swpaul    if (unsigned(N) >= BufferSize)
6726209Swpaul      return N + 1;
6826209Swpaul
6926209Swpaul    // Otherwise N is the length of output (not including the final '\0').
7026209Swpaul    return N;
7126209Swpaul  }
7226209Swpaul};
7326209Swpaul
7426209Swpaul/// These are templated helper classes used by the format function that
7526209Swpaul/// capture the object to be formatted and the format string. When actually
7626209Swpaul/// printed, this synthesizes the string into a temporary buffer provided and
7726209Swpaul/// returns whether or not it is big enough.
7826209Swpaul
7926209Swpaul// Helper to validate that format() parameters are scalars or pointers.
8026209Swpaultemplate <typename... Args> struct validate_format_parameters;
8126209Swpaultemplate <typename Arg, typename... Args>
8226209Swpaulstruct validate_format_parameters<Arg, Args...> {
8326209Swpaul  static_assert(std::is_scalar<Arg>::value,
8426209Swpaul                "format can't be used with non fundamental / non pointer type");
8526209Swpaul  validate_format_parameters() { validate_format_parameters<Args...>(); }
8626209Swpaul};
8726209Swpaultemplate <> struct validate_format_parameters<> {};
8826209Swpaul
8926209Swpaultemplate <typename... Ts>
9026209Swpaulclass format_object final : public format_object_base {
9126209Swpaul  std::tuple<Ts...> Vals;
9226209Swpaul
9326209Swpaul  template <std::size_t... Is>
9426209Swpaul  int snprint_tuple(char *Buffer, unsigned BufferSize,
9526209Swpaul                    std::index_sequence<Is...>) const {
9626209Swpaul#ifdef _MSC_VER
9726209Swpaul    return _snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
9826209Swpaul#else
9926209Swpaul    return snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
10026209Swpaul#endif
10126209Swpaul  }
10226209Swpaul
10326209Swpaulpublic:
10426209Swpaul  format_object(const char *fmt, const Ts &... vals)
10526209Swpaul      : format_object_base(fmt), Vals(vals...) {
10626209Swpaul    validate_format_parameters<Ts...>();
10726209Swpaul  }
10874462Salfred
10974462Salfred  int snprint(char *Buffer, unsigned BufferSize) const override {
11074462Salfred    return snprint_tuple(Buffer, BufferSize, std::index_sequence_for<Ts...>());
11174462Salfred  }
11226209Swpaul};
11393032Simp
11426209Swpaul/// These are helper functions used to produce formatted output.  They use
11526209Swpaul/// template type deduction to construct the appropriate instance of the
11674462Salfred/// format_object class to simplify their construction.
11774462Salfred///
11874462Salfred/// This is typically used like:
11974462Salfred/// \code
12074462Salfred///   OS << format("%0.4f", myfloat) << '\n';
12174462Salfred/// \endcode
12274462Salfred
12374462Salfredtemplate <typename... Ts>
12474462Salfredinline format_object<Ts...> format(const char *Fmt, const Ts &... Vals) {
12526209Swpaul  return format_object<Ts...>(Fmt, Vals...);
126}
127
128/// This is a helper class for left_justify, right_justify, and center_justify.
129class FormattedString {
130public:
131  enum Justification { JustifyNone, JustifyLeft, JustifyRight, JustifyCenter };
132  FormattedString(StringRef S, unsigned W, Justification J)
133      : Str(S), Width(W), Justify(J) {}
134
135private:
136  StringRef Str;
137  unsigned Width;
138  Justification Justify;
139  friend class raw_ostream;
140};
141
142/// left_justify - append spaces after string so total output is
143/// \p Width characters.  If \p Str is larger that \p Width, full string
144/// is written with no padding.
145inline FormattedString left_justify(StringRef Str, unsigned Width) {
146  return FormattedString(Str, Width, FormattedString::JustifyLeft);
147}
148
149/// right_justify - add spaces before string so total output is
150/// \p Width characters.  If \p Str is larger that \p Width, full string
151/// is written with no padding.
152inline FormattedString right_justify(StringRef Str, unsigned Width) {
153  return FormattedString(Str, Width, FormattedString::JustifyRight);
154}
155
156/// center_justify - add spaces before and after string so total output is
157/// \p Width characters.  If \p Str is larger that \p Width, full string
158/// is written with no padding.
159inline FormattedString center_justify(StringRef Str, unsigned Width) {
160  return FormattedString(Str, Width, FormattedString::JustifyCenter);
161}
162
163/// This is a helper class used for format_hex() and format_decimal().
164class FormattedNumber {
165  uint64_t HexValue;
166  int64_t DecValue;
167  unsigned Width;
168  bool Hex;
169  bool Upper;
170  bool HexPrefix;
171  friend class raw_ostream;
172
173public:
174  FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U,
175                  bool Prefix)
176      : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U),
177        HexPrefix(Prefix) {}
178};
179
180/// format_hex - Output \p N as a fixed width hexadecimal. If number will not
181/// fit in width, full number is still printed.  Examples:
182///   OS << format_hex(255, 4)              => 0xff
183///   OS << format_hex(255, 4, true)        => 0xFF
184///   OS << format_hex(255, 6)              => 0x00ff
185///   OS << format_hex(255, 2)              => 0xff
186inline FormattedNumber format_hex(uint64_t N, unsigned Width,
187                                  bool Upper = false) {
188  assert(Width <= 18 && "hex width must be <= 18");
189  return FormattedNumber(N, 0, Width, true, Upper, true);
190}
191
192/// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not
193/// prepend '0x' to the outputted string.  If number will not fit in width,
194/// full number is still printed.  Examples:
195///   OS << format_hex_no_prefix(255, 2)              => ff
196///   OS << format_hex_no_prefix(255, 2, true)        => FF
197///   OS << format_hex_no_prefix(255, 4)              => 00ff
198///   OS << format_hex_no_prefix(255, 1)              => ff
199inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width,
200                                            bool Upper = false) {
201  assert(Width <= 16 && "hex width must be <= 16");
202  return FormattedNumber(N, 0, Width, true, Upper, false);
203}
204
205/// format_decimal - Output \p N as a right justified, fixed-width decimal. If
206/// number will not fit in width, full number is still printed.  Examples:
207///   OS << format_decimal(0, 5)     => "    0"
208///   OS << format_decimal(255, 5)   => "  255"
209///   OS << format_decimal(-1, 3)    => " -1"
210///   OS << format_decimal(12345, 3) => "12345"
211inline FormattedNumber format_decimal(int64_t N, unsigned Width) {
212  return FormattedNumber(0, N, Width, false, false, false);
213}
214
215class FormattedBytes {
216  ArrayRef<uint8_t> Bytes;
217
218  // If not None, display offsets for each line relative to starting value.
219  Optional<uint64_t> FirstByteOffset;
220  uint32_t IndentLevel;  // Number of characters to indent each line.
221  uint32_t NumPerLine;   // Number of bytes to show per line.
222  uint8_t ByteGroupSize; // How many hex bytes are grouped without spaces
223  bool Upper;            // Show offset and hex bytes as upper case.
224  bool ASCII;            // Show the ASCII bytes for the hex bytes to the right.
225  friend class raw_ostream;
226
227public:
228  FormattedBytes(ArrayRef<uint8_t> B, uint32_t IL, Optional<uint64_t> O,
229                 uint32_t NPL, uint8_t BGS, bool U, bool A)
230      : Bytes(B), FirstByteOffset(O), IndentLevel(IL), NumPerLine(NPL),
231        ByteGroupSize(BGS), Upper(U), ASCII(A) {
232
233    if (ByteGroupSize > NumPerLine)
234      ByteGroupSize = NumPerLine;
235  }
236};
237
238inline FormattedBytes
239format_bytes(ArrayRef<uint8_t> Bytes, Optional<uint64_t> FirstByteOffset = None,
240             uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4,
241             uint32_t IndentLevel = 0, bool Upper = false) {
242  return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine,
243                        ByteGroupSize, Upper, false);
244}
245
246inline FormattedBytes
247format_bytes_with_ascii(ArrayRef<uint8_t> Bytes,
248                        Optional<uint64_t> FirstByteOffset = None,
249                        uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4,
250                        uint32_t IndentLevel = 0, bool Upper = false) {
251  return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine,
252                        ByteGroupSize, Upper, true);
253}
254
255} // end namespace llvm
256
257#endif
258