1 // Copyright 2016 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 #ifndef NINJA_STATUS_H_ 16 #define NINJA_STATUS_H_ 17 18 #include <map> 19 #include <string> 20 21 #include "build.h" 22 #include "line_printer.h" 23 24 /// Abstract interface to object that tracks the status of a build: 25 /// completion fraction, printing updates. 26 struct Status { 27 virtual void PlanHasTotalEdges(int total) = 0; 28 virtual void BuildEdgeStarted(const Edge* edge, int64_t start_time_millis) = 0; 29 virtual void BuildEdgeFinished(Edge* edge, int64_t end_time_millis, 30 bool success, const std::string& output) = 0; 31 virtual void BuildLoadDyndeps() = 0; 32 virtual void BuildStarted() = 0; 33 virtual void BuildFinished() = 0; 34 35 virtual void Info(const char* msg, ...) = 0; 36 virtual void Warning(const char* msg, ...) = 0; 37 virtual void Error(const char* msg, ...) = 0; 38 ~StatusStatus39 virtual ~Status() { } 40 }; 41 42 /// Implementation of the Status interface that prints the status as 43 /// human-readable strings to stdout 44 struct StatusPrinter : Status { 45 explicit StatusPrinter(const BuildConfig& config); 46 virtual void PlanHasTotalEdges(int total); 47 virtual void BuildEdgeStarted(const Edge* edge, int64_t start_time_millis); 48 virtual void BuildEdgeFinished(Edge* edge, int64_t end_time_millis, 49 bool success, const std::string& output); 50 virtual void BuildLoadDyndeps(); 51 virtual void BuildStarted(); 52 virtual void BuildFinished(); 53 54 virtual void Info(const char* msg, ...); 55 virtual void Warning(const char* msg, ...); 56 virtual void Error(const char* msg, ...); 57 ~StatusPrinterStatusPrinter58 virtual ~StatusPrinter() { } 59 60 /// Format the progress status string by replacing the placeholders. 61 /// See the user manual for more information about the available 62 /// placeholders. 63 /// @param progress_status_format The format of the progress status. 64 /// @param status The status of the edge. 65 std::string FormatProgressStatus(const char* progress_status_format, 66 int64_t time_millis) const; 67 68 private: 69 void PrintStatus(const Edge* edge, int64_t time_millis); 70 71 const BuildConfig& config_; 72 73 int started_edges_, finished_edges_, total_edges_, running_edges_; 74 int64_t time_millis_; 75 76 /// Prints progress output. 77 LinePrinter printer_; 78 79 /// The custom progress status format to use. 80 const char* progress_status_format_; 81 82 template<size_t S> SnprintfRateStatusPrinter83 void SnprintfRate(double rate, char(&buf)[S], const char* format) const { 84 if (rate == -1) 85 snprintf(buf, S, "?"); 86 else 87 snprintf(buf, S, format, rate); 88 } 89 90 struct SlidingRateInfo { SlidingRateInfoStatusPrinter::SlidingRateInfo91 SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {} 92 rateStatusPrinter::SlidingRateInfo93 double rate() { return rate_; } 94 UpdateRateStatusPrinter::SlidingRateInfo95 void UpdateRate(int update_hint, int64_t time_millis_) { 96 if (update_hint == last_update_) 97 return; 98 last_update_ = update_hint; 99 100 if (times_.size() == N) 101 times_.pop(); 102 times_.push(time_millis_); 103 if (times_.back() != times_.front()) 104 rate_ = times_.size() / ((times_.back() - times_.front()) / 1e3); 105 } 106 107 private: 108 double rate_; 109 const size_t N; 110 std::queue<double> times_; 111 int last_update_; 112 }; 113 114 mutable SlidingRateInfo current_rate_; 115 }; 116 117 #endif // NINJA_STATUS_H_ 118