Merge "Simplify adb LinePrinter newline handling."

This commit is contained in:
Elliott Hughes 2015-12-10 02:44:13 +00:00 committed by Gerrit Code Review
commit 9fa5cefea4
3 changed files with 33 additions and 89 deletions

View file

@ -76,6 +76,8 @@ class SyncConnection {
ReadOrderlyShutdown(fd);
}
adb_close(fd);
line_printer_.KeepInfoLine();
}
bool IsValid() { return fd >= 0; }
@ -243,8 +245,7 @@ class SyncConnection {
}
void Print(const std::string& s) {
// TODO: we actually don't want ELIDE; we want "ELIDE if smart, FULL if dumb".
line_printer_.Print(s, LinePrinter::ELIDE);
line_printer_.Print(s, LinePrinter::INFO);
}
void Printf(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) {
@ -265,7 +266,7 @@ class SyncConnection {
android::base::StringAppendV(&s, fmt, ap);
va_end(ap);
line_printer_.Print(s, LinePrinter::FULL);
line_printer_.Print(s, LinePrinter::ERROR);
}
void Warning(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) {
@ -276,7 +277,7 @@ class SyncConnection {
android::base::StringAppendV(&s, fmt, ap);
va_end(ap);
line_printer_.Print(s, LinePrinter::FULL);
line_printer_.Print(s, LinePrinter::WARNING);
}
uint64_t total_bytes;
@ -664,7 +665,7 @@ static bool copy_local_dir_remote(SyncConnection& sc, std::string lpath,
}
}
sc.Printf("%s: %d file%s pushed. %d file%s skipped.%s\n", rpath.c_str(),
sc.Printf("%s: %d file%s pushed. %d file%s skipped.%s", rpath.c_str(),
pushed, (pushed == 1) ? "" : "s", skipped,
(skipped == 1) ? "" : "s", sc.TransferRate().c_str());
return true;
@ -739,7 +740,6 @@ bool do_sync_push(const std::vector<const char*>& srcs, const char* dst) {
success &= sync_send(sc, src_path, dst_path, st.st_mtime, st.st_mode);
}
sc.Print("\n");
return success;
}
@ -858,7 +858,7 @@ static bool copy_remote_dir_local(SyncConnection& sc, std::string rpath,
}
}
sc.Printf("%s: %d file%s pulled. %d file%s skipped.%s\n", rpath.c_str(),
sc.Printf("%s: %d file%s pulled. %d file%s skipped.%s", rpath.c_str(),
pulled, (pulled == 1) ? "" : "s", skipped,
(skipped == 1) ? "" : "s", sc.TransferRate().c_str());
return true;
@ -967,7 +967,6 @@ bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst,
}
}
sc.Print("\n");
return success;
}

View file

@ -43,7 +43,7 @@ string ElideMiddle(const string& str, size_t width) {
return result;
}
LinePrinter::LinePrinter() : have_blank_line_(true), console_locked_(false) {
LinePrinter::LinePrinter() : have_blank_line_(true) {
#ifndef _WIN32
const char* term = getenv("TERM");
smart_terminal_ = unix_isatty(1) && term && string(term) != "dumb";
@ -59,20 +59,24 @@ LinePrinter::LinePrinter() : have_blank_line_(true), console_locked_(false) {
#endif
}
static void Out(const std::string& s) {
// Avoid printf and C strings, since the actual output might contain null
// bytes like UTF-16 does (yuck).
fwrite(s.data(), 1, s.size(), stdout);
}
void LinePrinter::Print(string to_print, LineType type) {
if (console_locked_) {
line_buffer_ = to_print;
line_type_ = type;
if (!smart_terminal_) {
Out(to_print);
return;
}
if (smart_terminal_) {
printf("\r"); // Print over previous line, if any.
// On Windows, calling a C library function writing to stdout also handles
// pausing the executable when the "Pause" key or Ctrl-S is pressed.
}
// Print over previous line, if any.
// On Windows, calling a C library function writing to stdout also handles
// pausing the executable when the "Pause" key or Ctrl-S is pressed.
printf("\r");
if (smart_terminal_ && type == ELIDE) {
if (type == INFO) {
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(console_, &csbi);
@ -105,57 +109,19 @@ void LinePrinter::Print(string to_print, LineType type) {
if ((ioctl(0, TIOCGWINSZ, &size) == 0) && size.ws_col) {
to_print = ElideMiddle(to_print, size.ws_col);
}
printf("%s", to_print.c_str());
Out(to_print);
printf("\x1B[K"); // Clear to end of line.
fflush(stdout);
#endif
have_blank_line_ = false;
} else {
printf("%s\n", to_print.c_str());
Out(to_print);
Out("\n");
have_blank_line_ = true;
}
}
void LinePrinter::PrintOrBuffer(const char* data, size_t size) {
if (console_locked_) {
output_buffer_.append(data, size);
} else {
// Avoid printf and C strings, since the actual output might contain null
// bytes like UTF-16 does (yuck).
fwrite(data, 1, size, stdout);
}
}
void LinePrinter::PrintOnNewLine(const string& to_print) {
if (console_locked_ && !line_buffer_.empty()) {
output_buffer_.append(line_buffer_);
output_buffer_.append(1, '\n');
line_buffer_.clear();
}
if (!have_blank_line_) {
PrintOrBuffer("\n", 1);
}
if (!to_print.empty()) {
PrintOrBuffer(&to_print[0], to_print.size());
}
have_blank_line_ = to_print.empty() || *to_print.rbegin() == '\n';
}
void LinePrinter::SetConsoleLocked(bool locked) {
if (locked == console_locked_)
return;
if (locked)
PrintOnNewLine("");
console_locked_ = locked;
if (!locked) {
PrintOnNewLine(output_buffer_);
if (!line_buffer_.empty()) {
Print(line_buffer_, line_type_);
}
output_buffer_.clear();
line_buffer_.clear();
}
void LinePrinter::KeepInfoLine() {
if (!have_blank_line_) Out("\n");
}

View file

@ -26,20 +26,14 @@ struct LinePrinter {
bool is_smart_terminal() const { return smart_terminal_; }
void set_smart_terminal(bool smart) { smart_terminal_ = smart; }
enum LineType {
FULL,
ELIDE
};
/// Overprints the current line. If type is ELIDE, elides to_print to fit on
/// one line.
enum LineType { INFO, WARNING, ERROR };
/// Outputs the given line. INFO output will be overwritten.
/// WARNING and ERROR appear on a line to themselves.
void Print(std::string to_print, LineType type);
/// Prints a string on a new line, not overprinting previous output.
void PrintOnNewLine(const std::string& to_print);
/// Lock or unlock the console. Any output sent to the LinePrinter while the
/// console is locked will not be printed until it is unlocked.
void SetConsoleLocked(bool locked);
/// If there's an INFO line, keep it. If not, do nothing.
void KeepInfoLine();
private:
/// Whether we can do fancy terminal control codes.
@ -48,24 +42,9 @@ struct LinePrinter {
/// Whether the caret is at the beginning of a blank line.
bool have_blank_line_;
/// Whether console is locked.
bool console_locked_;
/// Buffered current line while console is locked.
std::string line_buffer_;
/// Buffered line type while console is locked.
LineType line_type_;
/// Buffered console output while console is locked.
std::string output_buffer_;
#ifdef _WIN32
void* console_;
#endif
/// Print the given data to the console, or buffer it if it is locked.
void PrintOrBuffer(const char *data, size_t size);
};
#endif // NINJA_LINE_PRINTER_H_