GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/debug_utils-inl.h Lines: 33 35 94.3 %
Date: 2020-02-19 22:14:06 Branches: 109 396 27.5 %

Line Branch Exec Source
1
#ifndef SRC_DEBUG_UTILS_INL_H_
2
#define SRC_DEBUG_UTILS_INL_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "debug_utils.h"
7
8
#include <type_traits>
9
10
namespace node {
11
12
struct ToStringHelper {
13
  template <typename T>
14
805
  static std::string Convert(
15
      const T& value,
16
      std::string(T::* to_string)() const = &T::ToString) {
17
805
    return (value.*to_string)();
18
  }
19
  template <typename T,
20
            typename test_for_number = typename std::
21
                enable_if<std::is_arithmetic<T>::value, bool>::type,
22
            typename dummy = bool>
23
5813
  static std::string Convert(const T& value) { return std::to_string(value); }
24
2242
  static std::string Convert(const char* value) {
25
2242
    return value != nullptr ? value : "(null)";
26
  }
27
4586
  static std::string Convert(const std::string& value) { return value; }
28
6
  static std::string Convert(bool value) { return value ? "true" : "false"; }
29
};
30
31
template <typename T>
32
13452
std::string ToString(const T& value) {
33
13452
  return ToStringHelper::Convert(value);
34
}
35
36
6814
inline std::string SPrintFImpl(const char* format) {
37
6814
  const char* p = strchr(format, '%');
38
6814
  if (LIKELY(p == nullptr)) return format;
39
1
  CHECK_EQ(p[1], '%');  // Only '%%' allowed when there are no arguments.
40
41
1
  return std::string(format, p + 1) + SPrintFImpl(p + 2);
42
}
43
44
template <typename Arg, typename... Args>
45
13455
std::string COLD_NOINLINE SPrintFImpl(  // NOLINT(runtime/string)
46
    const char* format, Arg&& arg, Args&&... args) {
47
13455
  const char* p = strchr(format, '%');
48























13455
  CHECK_NOT_NULL(p);  // If you hit this, you passed in too many arguments.
49
26910
  std::string ret(format, p);
50
  // Ignore long / size_t modifiers
51























13455
  while (strchr("lz", *++p) != nullptr) {}
52















































13455
  switch (*p) {
53
    case '%': {
54
      return ret + '%' + SPrintFImpl(p + 1,
55
                                     std::forward<Arg>(arg),
56
1
                                     std::forward<Args>(args)...);
57
    }
58
    default: {
59
      return ret + '%' + SPrintFImpl(p,
60
                                     std::forward<Arg>(arg),
61
                                     std::forward<Args>(args)...);
62
    }
63
    case 'd':
64
    case 'i':
65
    case 'u':
66
13452
    case 's': ret += ToString(arg); break;
67
    case 'p': {
68
      CHECK(std::is_pointer<typename std::remove_reference<Arg>::type>::value);
69
      char out[20];
70
2
      int n = snprintf(out,
71
                       sizeof(out),
72
                       "%p",
73
2
                       *reinterpret_cast<const void* const*>(&arg));
74


2
      CHECK_GE(n, 0);
75
2
      ret += out;
76
2
      break;
77
    }
78
  }
79
13454
  return ret + SPrintFImpl(p + 1, std::forward<Args>(args)...);
80
}
81
82
template <typename... Args>
83
6813
std::string COLD_NOINLINE SPrintF(  // NOLINT(runtime/string)
84
    const char* format, Args&&... args) {
85
6813
  return SPrintFImpl(format, std::forward<Args>(args)...);
86
}
87
88
template <typename... Args>
89
1779
void COLD_NOINLINE FPrintF(FILE* file, const char* format, Args&&... args) {
90
1779
  FWrite(file, SPrintF(format, std::forward<Args>(args)...));
91
1779
}
92
93
}  // namespace node
94
95
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
96
97
#endif  // SRC_DEBUG_UTILS_INL_H_