1 // Copyright 2011 Google Inc. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include "disk_interface.h"
28 Cleaner::Cleaner(State* state, const BuildConfig& config)
32 cleaned_files_count_(0),
33 disk_interface_(new RealDiskInterface),
37 Cleaner::Cleaner(State* state,
38 const BuildConfig& config,
39 DiskInterface* disk_interface)
43 cleaned_files_count_(0),
44 disk_interface_(disk_interface),
48 int Cleaner::RemoveFile(const string& path) {
49 return disk_interface_->RemoveFile(path);
52 bool Cleaner::FileExists(const string& path) {
53 return disk_interface_->Stat(path) > 0;
56 void Cleaner::Report(const string& path) {
57 ++cleaned_files_count_;
59 printf("Remove %s\n", path.c_str());
62 void Cleaner::Remove(const string& path) {
63 if (!IsAlreadyRemoved(path)) {
64 removed_.insert(path);
65 if (config_.dry_run) {
69 int ret = RemoveFile(path);
78 bool Cleaner::IsAlreadyRemoved(const string& path) {
79 set<string>::iterator i = removed_.find(path);
80 return (i != removed_.end());
83 void Cleaner::PrintHeader() {
84 if (config_.verbosity == BuildConfig::QUIET)
86 printf("Cleaning...");
93 void Cleaner::PrintFooter() {
94 if (config_.verbosity == BuildConfig::QUIET)
96 printf("%d files.\n", cleaned_files_count_);
99 int Cleaner::CleanAll(bool generator) {
102 for (vector<Edge*>::iterator e = state_->edges_.begin();
103 e != state_->edges_.end(); ++e) {
104 // Do not try to remove phony targets
105 if ((*e)->rule_ == &State::kPhonyRule)
107 // Do not remove generator's files unless generator specified.
108 if (!generator && (*e)->rule().generator_)
110 for (vector<Node*>::iterator out_node = (*e)->outputs_.begin();
111 out_node != (*e)->outputs_.end(); ++out_node) {
112 Remove((*out_node)->path());
114 if (!(*e)->rule().depfile_.empty())
115 Remove((*e)->EvaluateDepFile());
121 void Cleaner::DoCleanTarget(Node* target) {
122 if (target->in_edge()) {
123 Remove(target->path());
124 for (vector<Node*>::iterator n = target->in_edge()->inputs_.begin();
125 n != target->in_edge()->inputs_.end();
132 int Cleaner::CleanTarget(Node* target) {
137 DoCleanTarget(target);
142 int Cleaner::CleanTarget(const char* target) {
146 Node* node = state_->LookupNode(target);
150 Error("unknown target '%s'", target);
156 int Cleaner::CleanTargets(int target_count, char* targets[]) {
159 for (int i = 0; i < target_count; ++i) {
160 const char* target_name = targets[i];
161 Node* target = state_->LookupNode(target_name);
164 printf("Target %s\n", target_name);
165 DoCleanTarget(target);
167 Error("unknown target '%s'", target_name);
175 void Cleaner::DoCleanRule(const Rule* rule) {
178 for (vector<Edge*>::iterator e = state_->edges_.begin();
179 e != state_->edges_.end();
181 if ((*e)->rule().name_ == rule->name_)
182 for (vector<Node*>::iterator out_node = (*e)->outputs_.begin();
183 out_node != (*e)->outputs_.end();
185 Remove((*out_node)->path());
188 int Cleaner::CleanRule(const Rule* rule) {
198 int Cleaner::CleanRule(const char* rule) {
202 const Rule* r = state_->LookupRule(rule);
206 Error("unknown rule '%s'", rule);
212 int Cleaner::CleanRules(int rule_count, char* rules[]) {
217 for (int i = 0; i < rule_count; ++i) {
218 const char* rule_name = rules[i];
219 const Rule* rule = state_->LookupRule(rule_name);
222 printf("Rule %s\n", rule_name);
225 Error("unknown rule '%s'", rule_name);
233 void Cleaner::Reset() {
235 cleaned_files_count_ = 0;