// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef NINJA_STATUS_H_ #define NINJA_STATUS_H_ #include #include #include "build.h" #include "line_printer.h" /// Abstract interface to object that tracks the status of a build: /// completion fraction, printing updates. struct Status { virtual void PlanHasTotalEdges(int total) = 0; virtual void BuildEdgeStarted(const Edge* edge, int64_t start_time_millis) = 0; virtual void BuildEdgeFinished(Edge* edge, int64_t end_time_millis, bool success, const std::string& output) = 0; virtual void BuildLoadDyndeps() = 0; virtual void BuildStarted() = 0; virtual void BuildFinished() = 0; virtual void Info(const char* msg, ...) = 0; virtual void Warning(const char* msg, ...) = 0; virtual void Error(const char* msg, ...) = 0; virtual ~Status() { } }; /// Implementation of the Status interface that prints the status as /// human-readable strings to stdout struct StatusPrinter : Status { explicit StatusPrinter(const BuildConfig& config); virtual void PlanHasTotalEdges(int total); virtual void BuildEdgeStarted(const Edge* edge, int64_t start_time_millis); virtual void BuildEdgeFinished(Edge* edge, int64_t end_time_millis, bool success, const std::string& output); virtual void BuildLoadDyndeps(); virtual void BuildStarted(); virtual void BuildFinished(); virtual void Info(const char* msg, ...); virtual void Warning(const char* msg, ...); virtual void Error(const char* msg, ...); virtual ~StatusPrinter() { } /// Format the progress status string by replacing the placeholders. /// See the user manual for more information about the available /// placeholders. /// @param progress_status_format The format of the progress status. /// @param status The status of the edge. std::string FormatProgressStatus(const char* progress_status_format, int64_t time_millis) const; private: void PrintStatus(const Edge* edge, int64_t time_millis); const BuildConfig& config_; int started_edges_, finished_edges_, total_edges_, running_edges_; int64_t time_millis_; /// Prints progress output. LinePrinter printer_; /// The custom progress status format to use. const char* progress_status_format_; template void SnprintfRate(double rate, char(&buf)[S], const char* format) const { if (rate == -1) snprintf(buf, S, "?"); else snprintf(buf, S, format, rate); } struct SlidingRateInfo { SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {} double rate() { return rate_; } void UpdateRate(int update_hint, int64_t time_millis_) { if (update_hint == last_update_) return; last_update_ = update_hint; if (times_.size() == N) times_.pop(); times_.push(time_millis_); if (times_.back() != times_.front()) rate_ = times_.size() / ((times_.back() - times_.front()) / 1e3); } private: double rate_; const size_t N; std::queue times_; int last_update_; }; mutable SlidingRateInfo current_rate_; }; #endif // NINJA_STATUS_H_