| 1 | //===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===// | 
| 2 | // | 
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
| 4 | // See https://llvm.org/LICENSE.txt for license information. | 
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| 6 | // | 
| 7 | //===----------------------------------------------------------------------===// | 
| 8 | // | 
| 9 | // This file implements the format() function, which can be used with other | 
| 10 | // LLVM subsystems to provide printf-style formatting.  This gives all the power | 
| 11 | // and risk of printf.  This can be used like this (with raw_ostreams as an | 
| 12 | // example): | 
| 13 | // | 
| 14 | //    OS << "mynumber: " << format("%4.5f", 1234.412) << '\n'; | 
| 15 | // | 
| 16 | // Or if you prefer: | 
| 17 | // | 
| 18 | //  OS << format("mynumber: %4.5f\n", 1234.412); | 
| 19 | // | 
| 20 | //===----------------------------------------------------------------------===// | 
| 21 |  | 
| 22 | #ifndef LLVM_SUPPORT_FORMAT_H | 
| 23 | #define LLVM_SUPPORT_FORMAT_H | 
| 24 |  | 
| 25 | #include "llvm/ADT/ArrayRef.h" | 
| 26 | #include "llvm/ADT/STLExtras.h" | 
| 27 | #include "llvm/ADT/StringRef.h" | 
| 28 | #include "llvm/Support/DataTypes.h" | 
| 29 | #include <cassert> | 
| 30 | #include <cstdio> | 
| 31 | #include <optional> | 
| 32 | #include <tuple> | 
| 33 | #include <utility> | 
| 34 |  | 
| 35 | namespace llvm { | 
| 36 |  | 
| 37 | /// This is a helper class used for handling formatted output.  It is the | 
| 38 | /// abstract base class of a templated derived class. | 
| 39 | class format_object_base { | 
| 40 | protected: | 
| 41 |   const char *Fmt; | 
| 42 |   ~format_object_base() = default; // Disallow polymorphic deletion. | 
| 43 |   format_object_base(const format_object_base &) = default; | 
| 44 |   virtual void home(); // Out of line virtual method. | 
| 45 |  | 
| 46 |   /// Call snprintf() for this object, on the given buffer and size. | 
| 47 |   virtual int snprint(char *Buffer, unsigned BufferSize) const = 0; | 
| 48 |  | 
| 49 | public: | 
| 50 |   format_object_base(const char *fmt) : Fmt(fmt) {} | 
| 51 |  | 
| 52 |   /// Format the object into the specified buffer.  On success, this returns | 
| 53 |   /// the length of the formatted string.  If the buffer is too small, this | 
| 54 |   /// returns a length to retry with, which will be larger than BufferSize. | 
| 55 |   unsigned print(char *Buffer, unsigned BufferSize) const { | 
| 56 |     assert(BufferSize && "Invalid buffer size!" ); | 
| 57 |  | 
| 58 |     // Print the string, leaving room for the terminating null. | 
| 59 |     int N = snprint(Buffer, BufferSize); | 
| 60 |  | 
| 61 |     // VC++ and old GlibC return negative on overflow, just double the size. | 
| 62 |     if (N < 0) | 
| 63 |       return BufferSize * 2; | 
| 64 |  | 
| 65 |     // Other implementations yield number of bytes needed, not including the | 
| 66 |     // final '\0'. | 
| 67 |     if (unsigned(N) >= BufferSize) | 
| 68 |       return N + 1; | 
| 69 |  | 
| 70 |     // Otherwise N is the length of output (not including the final '\0'). | 
| 71 |     return N; | 
| 72 |   } | 
| 73 | }; | 
| 74 |  | 
| 75 | /// These are templated helper classes used by the format function that | 
| 76 | /// capture the object to be formatted and the format string. When actually | 
| 77 | /// printed, this synthesizes the string into a temporary buffer provided and | 
| 78 | /// returns whether or not it is big enough. | 
| 79 |  | 
| 80 | // Helper to validate that format() parameters are scalars or pointers. | 
| 81 | template <typename... Args> struct validate_format_parameters; | 
| 82 | template <typename Arg, typename... Args> | 
| 83 | struct validate_format_parameters<Arg, Args...> { | 
| 84 |   static_assert(std::is_scalar_v<Arg>, | 
| 85 |                 "format can't be used with non fundamental / non pointer type" ); | 
| 86 |   validate_format_parameters() { validate_format_parameters<Args...>(); } | 
| 87 | }; | 
| 88 | template <> struct validate_format_parameters<> {}; | 
| 89 |  | 
| 90 | template <typename... Ts> | 
| 91 | class format_object final : public format_object_base { | 
| 92 |   std::tuple<Ts...> Vals; | 
| 93 |  | 
| 94 |   template <std::size_t... Is> | 
| 95 |   int snprint_tuple(char *Buffer, unsigned BufferSize, | 
| 96 |                     std::index_sequence<Is...>) const { | 
| 97 | #ifdef _MSC_VER | 
| 98 |     return _snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...); | 
| 99 | #else | 
| 100 |     return snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...); | 
| 101 | #endif | 
| 102 |   } | 
| 103 |  | 
| 104 | public: | 
| 105 |   format_object(const char *fmt, const Ts &... vals) | 
| 106 |       : format_object_base(fmt), Vals(vals...) { | 
| 107 |     validate_format_parameters<Ts...>(); | 
| 108 |   } | 
| 109 |  | 
| 110 |   int snprint(char *Buffer, unsigned BufferSize) const override { | 
| 111 |     return snprint_tuple(Buffer, BufferSize, std::index_sequence_for<Ts...>()); | 
| 112 |   } | 
| 113 | }; | 
| 114 |  | 
| 115 | /// These are helper functions used to produce formatted output.  They use | 
| 116 | /// template type deduction to construct the appropriate instance of the | 
| 117 | /// format_object class to simplify their construction. | 
| 118 | /// | 
| 119 | /// This is typically used like: | 
| 120 | /// \code | 
| 121 | ///   OS << format("%0.4f", myfloat) << '\n'; | 
| 122 | /// \endcode | 
| 123 |  | 
| 124 | template <typename... Ts> | 
| 125 | inline format_object<Ts...> format(const char *Fmt, const Ts &... Vals) { | 
| 126 |   return format_object<Ts...>(Fmt, Vals...); | 
| 127 | } | 
| 128 |  | 
| 129 | /// This is a helper class for left_justify, right_justify, and center_justify. | 
| 130 | class FormattedString { | 
| 131 | public: | 
| 132 |   enum Justification { JustifyNone, JustifyLeft, JustifyRight, JustifyCenter }; | 
| 133 |   FormattedString(StringRef S, unsigned W, Justification J) | 
| 134 |       : Str(S), Width(W), Justify(J) {} | 
| 135 |  | 
| 136 | private: | 
| 137 |   StringRef Str; | 
| 138 |   unsigned Width; | 
| 139 |   Justification Justify; | 
| 140 |   friend class raw_ostream; | 
| 141 | }; | 
| 142 |  | 
| 143 | /// left_justify - append spaces after string so total output is | 
| 144 | /// \p Width characters.  If \p Str is larger that \p Width, full string | 
| 145 | /// is written with no padding. | 
| 146 | inline FormattedString left_justify(StringRef Str, unsigned Width) { | 
| 147 |   return FormattedString(Str, Width, FormattedString::JustifyLeft); | 
| 148 | } | 
| 149 |  | 
| 150 | /// right_justify - add spaces before string so total output is | 
| 151 | /// \p Width characters.  If \p Str is larger that \p Width, full string | 
| 152 | /// is written with no padding. | 
| 153 | inline FormattedString right_justify(StringRef Str, unsigned Width) { | 
| 154 |   return FormattedString(Str, Width, FormattedString::JustifyRight); | 
| 155 | } | 
| 156 |  | 
| 157 | /// center_justify - add spaces before and after string so total output is | 
| 158 | /// \p Width characters.  If \p Str is larger that \p Width, full string | 
| 159 | /// is written with no padding. | 
| 160 | inline FormattedString center_justify(StringRef Str, unsigned Width) { | 
| 161 |   return FormattedString(Str, Width, FormattedString::JustifyCenter); | 
| 162 | } | 
| 163 |  | 
| 164 | /// This is a helper class used for format_hex() and format_decimal(). | 
| 165 | class FormattedNumber { | 
| 166 |   uint64_t HexValue; | 
| 167 |   int64_t DecValue; | 
| 168 |   unsigned Width; | 
| 169 |   bool Hex; | 
| 170 |   bool Upper; | 
| 171 |   bool HexPrefix; | 
| 172 |   friend class raw_ostream; | 
| 173 |  | 
| 174 | public: | 
| 175 |   FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U, | 
| 176 |                   bool Prefix) | 
| 177 |       : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U), | 
| 178 |         HexPrefix(Prefix) {} | 
| 179 | }; | 
| 180 |  | 
| 181 | /// format_hex - Output \p N as a fixed width hexadecimal. If number will not | 
| 182 | /// fit in width, full number is still printed.  Examples: | 
| 183 | ///   OS << format_hex(255, 4)              => 0xff | 
| 184 | ///   OS << format_hex(255, 4, true)        => 0xFF | 
| 185 | ///   OS << format_hex(255, 6)              => 0x00ff | 
| 186 | ///   OS << format_hex(255, 2)              => 0xff | 
| 187 | inline FormattedNumber format_hex(uint64_t N, unsigned Width, | 
| 188 |                                   bool Upper = false) { | 
| 189 |   assert(Width <= 18 && "hex width must be <= 18" ); | 
| 190 |   return FormattedNumber(N, 0, Width, true, Upper, true); | 
| 191 | } | 
| 192 |  | 
| 193 | /// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not | 
| 194 | /// prepend '0x' to the outputted string.  If number will not fit in width, | 
| 195 | /// full number is still printed.  Examples: | 
| 196 | ///   OS << format_hex_no_prefix(255, 2)              => ff | 
| 197 | ///   OS << format_hex_no_prefix(255, 2, true)        => FF | 
| 198 | ///   OS << format_hex_no_prefix(255, 4)              => 00ff | 
| 199 | ///   OS << format_hex_no_prefix(255, 1)              => ff | 
| 200 | inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, | 
| 201 |                                             bool Upper = false) { | 
| 202 |   assert(Width <= 16 && "hex width must be <= 16" ); | 
| 203 |   return FormattedNumber(N, 0, Width, true, Upper, false); | 
| 204 | } | 
| 205 |  | 
| 206 | /// format_decimal - Output \p N as a right justified, fixed-width decimal. If | 
| 207 | /// number will not fit in width, full number is still printed.  Examples: | 
| 208 | ///   OS << format_decimal(0, 5)     => "    0" | 
| 209 | ///   OS << format_decimal(255, 5)   => "  255" | 
| 210 | ///   OS << format_decimal(-1, 3)    => " -1" | 
| 211 | ///   OS << format_decimal(12345, 3) => "12345" | 
| 212 | inline FormattedNumber format_decimal(int64_t N, unsigned Width) { | 
| 213 |   return FormattedNumber(0, N, Width, false, false, false); | 
| 214 | } | 
| 215 |  | 
| 216 | class FormattedBytes { | 
| 217 |   ArrayRef<uint8_t> Bytes; | 
| 218 |  | 
| 219 |   // If not std::nullopt, display offsets for each line relative to starting | 
| 220 |   // value. | 
| 221 |   std::optional<uint64_t> FirstByteOffset; | 
| 222 |   uint32_t IndentLevel;  // Number of characters to indent each line. | 
| 223 |   uint32_t NumPerLine;   // Number of bytes to show per line. | 
| 224 |   uint8_t ByteGroupSize; // How many hex bytes are grouped without spaces | 
| 225 |   bool Upper;            // Show offset and hex bytes as upper case. | 
| 226 |   bool ASCII;            // Show the ASCII bytes for the hex bytes to the right. | 
| 227 |   friend class raw_ostream; | 
| 228 |  | 
| 229 | public: | 
| 230 |   FormattedBytes(ArrayRef<uint8_t> B, uint32_t IL, std::optional<uint64_t> O, | 
| 231 |                  uint32_t NPL, uint8_t BGS, bool U, bool A) | 
| 232 |       : Bytes(B), FirstByteOffset(O), IndentLevel(IL), NumPerLine(NPL), | 
| 233 |         ByteGroupSize(BGS), Upper(U), ASCII(A) { | 
| 234 |  | 
| 235 |     if (ByteGroupSize > NumPerLine) | 
| 236 |       ByteGroupSize = NumPerLine; | 
| 237 |   } | 
| 238 | }; | 
| 239 |  | 
| 240 | inline FormattedBytes | 
| 241 | format_bytes(ArrayRef<uint8_t> Bytes, | 
| 242 |              std::optional<uint64_t> FirstByteOffset = std::nullopt, | 
| 243 |              uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4, | 
| 244 |              uint32_t IndentLevel = 0, bool Upper = false) { | 
| 245 |   return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine, | 
| 246 |                         ByteGroupSize, Upper, false); | 
| 247 | } | 
| 248 |  | 
| 249 | inline FormattedBytes | 
| 250 | format_bytes_with_ascii(ArrayRef<uint8_t> Bytes, | 
| 251 |                         std::optional<uint64_t> FirstByteOffset = std::nullopt, | 
| 252 |                         uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4, | 
| 253 |                         uint32_t IndentLevel = 0, bool Upper = false) { | 
| 254 |   return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine, | 
| 255 |                         ByteGroupSize, Upper, true); | 
| 256 | } | 
| 257 |  | 
| 258 | } // end namespace llvm | 
| 259 |  | 
| 260 | #endif | 
| 261 |  |