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.
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.
void LookupAndAppend(const void *item, std::vector< std::string > *out)
Lookup the explanations recorded for |item|, and append them to |*out|, if any.
void Record(const void *item, const char *fmt,...)
Record an explanation for |item| if this instance is enabled.
void RecordArgs(const void *item, const char *fmt, va_list args)
Same as Record(), but uses a va_list to pass formatting arguments.
std::unordered_map< const void *, std::vector< std::string > > map_
void RecordArgs(const void *item, const char *fmt, va_list args)
Explanations * explanations_
Explanations * ptr() const
OptionalExplanations(Explanations *explanations)
void Record(const void *item, const char *fmt,...)
void LookupAndAppend(const void *item, std::vector< std::string > *out)