LCOV - code coverage report
Current view: top level - include/llvm/Support - Format.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 143 214 66.8 %
Date: 2018-10-20 13:21:21 Functions: 81 243 33.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13