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