Ninja
explanations.h
Go to the documentation of this file.
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  void Record(const void* item, const char* fmt, ...) {
31  va_list args;
32  va_start(args, fmt);
33  RecordArgs(item, fmt, args);
34  va_end(args);
35  }
36 
37  /// Same as Record(), but uses a va_list to pass formatting arguments.
38  void RecordArgs(const void* item, const char* fmt, va_list args) {
39  char buffer[1024];
40  vsnprintf(buffer, sizeof(buffer), fmt, args);
41  map_[item].emplace_back(buffer);
42  }
43 
44  /// Lookup the explanations recorded for |item|, and append them
45  /// to |*out|, if any.
46  void LookupAndAppend(const void* item, std::vector<std::string>* out) {
47  auto it = map_.find(item);
48  if (it == map_.end())
49  return;
50 
51  for (const auto& explanation : it->second)
52  out->push_back(explanation);
53  }
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.
63  : explanations_(explanations) {}
64 
65  void Record(const void* item, const char* fmt, ...) {
66  if (explanations_) {
67  va_list args;
68  va_start(args, fmt);
69  explanations_->RecordArgs(item, fmt, args);
70  va_end(args);
71  }
72  }
73 
74  void RecordArgs(const void* item, const char* fmt, va_list args) {
75  if (explanations_)
76  explanations_->RecordArgs(item, fmt, args);
77  }
78 
79  void LookupAndAppend(const void* item, std::vector<std::string>* out) {
80  if (explanations_)
81  explanations_->LookupAndAppend(item, out);
82  }
83 
84  Explanations* ptr() const { return explanations_; }
85 
86  private:
88 };
A class used to record a list of explanation strings associated with a given 'item' pointer.
Definition: explanations.h:27
void LookupAndAppend(const void *item, std::vector< std::string > *out)
Lookup the explanations recorded for |item|, and append them to |*out|, if any.
Definition: explanations.h:46
void Record(const void *item, const char *fmt,...)
Record an explanation for |item| if this instance is enabled.
Definition: explanations.h:30
void RecordArgs(const void *item, const char *fmt, va_list args)
Same as Record(), but uses a va_list to pass formatting arguments.
Definition: explanations.h:38
std::unordered_map< const void *, std::vector< std::string > > map_
Definition: explanations.h:56
Convenience wrapper for an Explanations pointer, which can be null if no explanations need to be reco...
Definition: explanations.h:61
void RecordArgs(const void *item, const char *fmt, va_list args)
Definition: explanations.h:74
Explanations * explanations_
Definition: explanations.h:87
Explanations * ptr() const
Definition: explanations.h:84
OptionalExplanations(Explanations *explanations)
Definition: explanations.h:62
void Record(const void *item, const char *fmt,...)
Definition: explanations.h:65
void LookupAndAppend(const void *item, std::vector< std::string > *out)
Definition: explanations.h:79