From 2ddef5b052c42876333928bc9591ad6ff8953fab Mon Sep 17 00:00:00 2001 From: Evan Martin Date: Wed, 25 Apr 2012 20:30:35 -0700 Subject: reduce custom ninja status patch in minor ways Elsewhere in the code I avoid sstream and manual buffer management, so switch this code to behave similarly. Sorry for being OCD. --- src/build.cc | 131 ++++++++++++++++++++---------------------------------- src/build.h | 17 +------ src/build_test.cc | 33 +------------- 3 files changed, 53 insertions(+), 128 deletions(-) diff --git a/src/build.cc b/src/build.cc index bacae6c..a9e1e56 100644 --- a/src/build.cc +++ b/src/build.cc @@ -16,7 +16,6 @@ #include #include -#include #ifdef _WIN32 #include @@ -59,7 +58,7 @@ BuildStatus::BuildStatus(const BuildConfig& config) smart_terminal_ = false; progress_status_format_ = getenv("NINJA_STATUS"); - if (progress_status_format_ == NULL) + if (!progress_status_format_) progress_status_format_ = "[%s/%t] "; } @@ -141,89 +140,58 @@ void BuildStatus::BuildFinished() { printf("\n"); } -int BuildStatus::FormatProgressStatus(const char* progress_status_format, - char* buffer, - const int buffer_size, - string* err) const { - int i = 0; - for (const char* s = progress_status_format; - *s != '\0' && i < buffer_size; - ++s) { +string BuildStatus::FormatProgressStatus(const char* progress_status_format) const { + string out; + char buf[32]; + for (const char* s = progress_status_format; *s != '\0'; ++s) { if (*s == '%') { ++s; - switch(*s) { - case '%': - buffer[i] = '%'; - ++i; - break; - - // Started edges. - case 's': - i += snprintf(&buffer[i], buffer_size - i, "%d", started_edges_); - break; - - // Total edges. - case 't': - i += snprintf(&buffer[i], buffer_size - i, "%d", total_edges_); - break; - - // Running edges. - case 'r': - i += snprintf(&buffer[i], buffer_size - i, "%d", - started_edges_ - finished_edges_); - break; - - // Unstarted edges. - case 'u': - i += snprintf(&buffer[i], buffer_size - i, "%d", - total_edges_ - started_edges_); - break; - - // Finished edges. - case 'f': - i += snprintf(&buffer[i], buffer_size - i, "%d", finished_edges_); - break; - - default: - if (err != NULL) { - ostringstream oss; - oss << "unknown placeholders '%" << *s << "' in NINJA_STATUS"; - *err = oss.str(); - } - return -1; + switch (*s) { + case '%': + out.push_back('%'); + break; + + // Started edges. + case 's': + snprintf(buf, sizeof(buf), "%d", started_edges_); + out += buf; + break; + + // Total edges. + case 't': + snprintf(buf, sizeof(buf), "%d", total_edges_); + out += buf; + break; + + // Running edges. + case 'r': + snprintf(buf, sizeof(buf), "%d", started_edges_ - finished_edges_); + out += buf; + break; + + // Unstarted edges. + case 'u': + snprintf(buf, sizeof(buf), "%d", total_edges_ - started_edges_); + out += buf; + break; + + // Finished edges. + case 'f': + snprintf(buf, sizeof(buf), "%d", finished_edges_); + out += buf; + break; + + default: { + Fatal("unknown placeholder '%%%c' in $NINJA_STATUS", *s); + return ""; + } } } else { - buffer[i] = *s; - ++i; - } - } - if (i >= buffer_size) { - if (err != NULL) { - ostringstream oss; - oss << "custom NINJA_STATUS exceed buffer size " << buffer_size; - *err = oss.str(); + out.push_back(*s); } - return -1; - } else { - buffer[i] = '\0'; - if (err != NULL) - *err = ""; - return i; } -} -int BuildStatus::PrintProgressStatus() const { - const int kBUFF_SIZE = 1024; - char buff[kBUFF_SIZE] = { '\0' }; - string err; - int progress_chars = FormatProgressStatus(progress_status_format_, - buff, - kBUFF_SIZE, - &err); - if (progress_chars < 0) - return printf("!! %s !! ", err.c_str()); - else - return printf("%s", buff); + return out; } void BuildStatus::PrintStatus(Edge* edge) { @@ -250,15 +218,15 @@ void BuildStatus::PrintStatus(Edge* edge) { #endif } - int progress_chars = PrintProgressStatus(); + to_print = FormatProgressStatus(progress_status_format_) + to_print; if (smart_terminal_ && !force_full_command) { + const int kMargin = 3; // Space for "...". #ifndef _WIN32 // Limit output to width of the terminal if provided so we don't cause // line-wrapping. winsize size; if ((ioctl(0, TIOCGWINSZ, &size) == 0) && size.ws_col) { - const int kMargin = progress_chars + 3; // Space for [xx/yy] and "...". if (to_print.size() + kMargin > size.ws_col) { int elide_size = (size.ws_col - kMargin) / 2; to_print = to_print.substr(0, elide_size) @@ -267,8 +235,7 @@ void BuildStatus::PrintStatus(Edge* edge) { } } #else - const int kMargin = progress_chars + 3; // Space for [xx/yy] and "...". - // Don't use the full width or console with move to next line. + // Don't use the full width or console will move to next line. size_t width = static_cast(csbi.dwSize.X) - 1; if (to_print.size() + kMargin > width) { int elide_size = (width - kMargin) / 2; diff --git a/src/build.h b/src/build.h index 8078910..c0328f3 100644 --- a/src/build.h +++ b/src/build.h @@ -24,6 +24,7 @@ using namespace std; #include "exit_status.h" +#include "util.h" // int64_t struct BuildLog; struct Edge; @@ -162,25 +163,11 @@ struct BuildStatus { /// See the user manual for more information about the available /// placeholders. /// @param progress_status_format_ The format of the progress status. - /// @param buffer The buffer where is stored the formatted progress status. - /// @param buffer_size The size of the given @a buffer. - /// @param err The error message if -1 is returned. - /// @return The number of characters inserted in @a buffer and -1 on error. - int FormatProgressStatus(const char* progress_status_format, - char* buffer, - const int buffer_size, - string* err) const; + string FormatProgressStatus(const char* progress_status_format) const; private: void PrintStatus(Edge* edge); - /// Print the progress status. - /// - /// Get the status from the NINJA_STATUS environment variable if defined. - /// - /// @return The number of printed characters. - int PrintProgressStatus() const; - const BuildConfig& config_; /// Time the build started. diff --git a/src/build_test.cc b/src/build_test.cc index f3f5472..c45f2b3 100644 --- a/src/build_test.cc +++ b/src/build_test.cc @@ -1024,36 +1024,7 @@ TEST_F(BuildTest, PhonyWithNoInputs) { ASSERT_EQ(1u, commands_ran_.size()); } -TEST_F(BuildTest, StatusFormatBufferTooSmall) { - const int kBUFF_SIZE = 5; - char buff[kBUFF_SIZE] = { '\0' }; - string err; - - EXPECT_EQ(-1, status_.FormatProgressStatus("0123456789", - buff, kBUFF_SIZE, - &err)); - EXPECT_EQ("custom NINJA_STATUS exceed buffer size 5", err); -} - -TEST_F(BuildTest, StatusFormatWrongPlaceholder) { - const int kBUFF_SIZE = 1024; - char buff[kBUFF_SIZE] = { '\0' }; - string err; - - EXPECT_EQ(-1, status_.FormatProgressStatus("[%r/%X]", - buff, kBUFF_SIZE, - &err)); - EXPECT_EQ("unknown placeholders '%X' in NINJA_STATUS", err); -} - TEST_F(BuildTest, StatusFormatReplacePlaceholder) { - const int kBUFF_SIZE = 1024; - char buff[kBUFF_SIZE] = { '\0' }; - string err; - - EXPECT_EQ(18, status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]", - buff, kBUFF_SIZE, - &err)); - EXPECT_EQ("", err); - EXPECT_STREQ("[%/s0/t0/r0/u0/f0]", buff); + EXPECT_EQ("[%/s0/t0/r0/u0/f0]", + status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]")); } -- cgit v0.12