Merge "Simplify adb LinePrinter newline handling."
This commit is contained in:
commit
9fa5cefea4
3 changed files with 33 additions and 89 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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_
|
||||
|
|
Loading…
Reference in a new issue