LCOV - code coverage report
Current view: top level - include/llvm/Support - Format.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 26 27 96.3 %
Date: 2017-09-14 15:23:50 Functions: 66 92 71.7 %
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     3474779 :   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     3475356 :     int N = snprint(Buffer, BufferSize);
      59             : 
      60             :     // VC++ and old GlibC return negative on overflow, just double the size.
      61     3472915 :     if (N < 0)
      62           0 :       return BufferSize * 2;
      63             : 
      64             :     // Other implementations yield number of bytes needed, not including the
      65             :     // final '\0'.
      66     3472915 :     if (unsigned(N) >= BufferSize)
      67         577 :       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             :   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        1085 :   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     7088780 :     return snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
     100             : #endif
     101             :   }
     102             : 
     103             : public:
     104             :   format_object(const char *fmt, const Ts &... vals)
     105    10480753 :       : format_object_base(fmt), Vals(vals...) {
     106             :     validate_format_parameters<Ts...>();
     107             :   }
     108             : 
     109     3475356 :   int snprint(char *Buffer, unsigned BufferSize) const override {
     110     7006047 :     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             : /// template type deduction to construct the appropriate instance of the
     116             : /// format_object class to simplify their construction.
     117             : ///
     118             : /// This is typically used like:
     119             : /// \code
     120             : ///   OS << format("%0.4f", myfloat) << '\n';
     121             : /// \endcode
     122             : 
     123             : template <typename... Ts>
     124             : inline format_object<Ts...> format(const char *Fmt, const Ts &... Vals) {
     125     3502989 :   return format_object<Ts...>(Fmt, Vals...);
     126             : }
     127             : 
     128             : /// This is a helper class for left_justify, right_justify, and center_justify.
     129             : class FormattedString {
     130             : public:
     131             :   enum Justification { JustifyNone, JustifyLeft, JustifyRight, JustifyCenter };
     132             :   FormattedString(StringRef S, unsigned W, Justification J)
     133        1888 :       : Str(S), Width(W), Justify(J) {}
     134             : 
     135             : private:
     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.
     145             : inline FormattedString left_justify(StringRef Str, unsigned Width) {
     146         494 :   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.
     152             : inline FormattedString right_justify(StringRef Str, unsigned Width) {
     153        1389 :   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.
     159             : inline FormattedString center_justify(StringRef Str, unsigned Width) {
     160           5 :   return FormattedString(Str, Width, FormattedString::JustifyCenter);
     161             : }
     162             : 
     163             : /// This is a helper class used for format_hex() and format_decimal().
     164             : class 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             : 
     173             : public:
     174             :   FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U,
     175             :                   bool Prefix)
     176      617107 :       : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U),
     177      617107 :         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
     186             : inline FormattedNumber format_hex(uint64_t N, unsigned Width,
     187             :                                   bool Upper = false) {
     188             :   assert(Width <= 18 && "hex width must be <= 18");
     189        5574 :   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
     199             : inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width,
     200             :                                             bool Upper = false) {
     201             :   assert(Width <= 16 && "hex width must be <= 16");
     202     1227244 :   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"
     211             : inline FormattedNumber format_decimal(int64_t N, unsigned Width) {
     212         698 :   return FormattedNumber(0, N, Width, false, false, false);
     213             : }
     214             : 
     215        6372 : class 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             : 
     227             : public:
     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        6372 :         ByteGroupSize(BGS), Upper(U), ASCII(A) {
     232             : 
     233        1641 :     if (ByteGroupSize > NumPerLine)
     234          68 :       ByteGroupSize = NumPerLine;
     235             :   }
     236             : };
     237             : 
     238             : inline FormattedBytes
     239             : format_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        3275 :                         ByteGroupSize, Upper, false);
     244             : }
     245             : 
     246             : inline FormattedBytes
     247             : format_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        4677 :                         ByteGroupSize, Upper, true);
     253             : }
     254             : 
     255             : } // end namespace llvm
     256             : 
     257             : #endif

Generated by: LCOV version 1.13