Coverage Report

Created: 2025-12-31 08:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ninja/src/explanations.h
Line
Count
Source
1
// Copyright 2024 Google Inc. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#pragma once
16
17
#include <stdarg.h>
18
#include <stdio.h>
19
20
#include <string>
21
#include <unordered_map>
22
#include <vector>
23
24
/// A class used to record a list of explanation strings associated
25
/// with a given 'item' pointer. This is used to implement the
26
/// `-d explain` feature.
27
struct Explanations {
28
 public:
29
  /// Record an explanation for |item| if this instance is enabled.
30
0
  void Record(const void* item, const char* fmt, ...) {
31
0
    va_list args;
32
0
    va_start(args, fmt);
33
0
    RecordArgs(item, fmt, args);
34
0
    va_end(args);
35
0
  }
36
37
  /// Same as Record(), but uses a va_list to pass formatting arguments.
38
0
  void RecordArgs(const void* item, const char* fmt, va_list args) {
39
0
    char buffer[1024];
40
0
    vsnprintf(buffer, sizeof(buffer), fmt, args);
41
0
    map_[item].emplace_back(buffer);
42
0
  }
43
44
  /// Lookup the explanations recorded for |item|, and append them
45
  /// to |*out|, if any.
46
0
  void LookupAndAppend(const void* item, std::vector<std::string>* out) {
47
0
    auto it = map_.find(item);
48
0
    if (it == map_.end())
49
0
      return;
50
0
51
0
    for (const auto& explanation : it->second)
52
0
      out->push_back(explanation);
53
0
  }
54
55
 private:
56
  std::unordered_map<const void*, std::vector<std::string>> map_;
57
};
58
59
/// Convenience wrapper for an Explanations pointer, which can be null
60
/// if no explanations need to be recorded.
61
struct OptionalExplanations {
62
  OptionalExplanations(Explanations* explanations)
63
0
      : explanations_(explanations) {}
64
65
0
  void Record(const void* item, const char* fmt, ...) {
66
0
    if (explanations_) {
67
0
      va_list args;
68
0
      va_start(args, fmt);
69
0
      explanations_->RecordArgs(item, fmt, args);
70
0
      va_end(args);
71
0
    }
72
0
  }
73
74
0
  void RecordArgs(const void* item, const char* fmt, va_list args) {
75
0
    if (explanations_)
76
0
      explanations_->RecordArgs(item, fmt, args);
77
0
  }
78
79
0
  void LookupAndAppend(const void* item, std::vector<std::string>* out) {
80
0
    if (explanations_)
81
0
      explanations_->LookupAndAppend(item, out);
82
0
  }
83
84
0
  Explanations* ptr() const { return explanations_; }
85
86
 private:
87
  Explanations* explanations_;
88
};