Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9fa5cefe authored by Elliott Hughes's avatar Elliott Hughes Committed by Gerrit Code Review
Browse files

Merge "Simplify adb LinePrinter newline handling."

parents 98a82573 77f539ab
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -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;
}

+20 −54
Original line number Diff line number Diff line
@@ -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.
  // 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());
  }
}

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);
    Out(to_print);
    Out("\n");
    have_blank_line_ = true;
  }
}

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");
}
+6 −27
Original line number Diff line number Diff line
@@ -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.
  void Print(std::string to_print, LineType type);
  enum LineType { INFO, WARNING, ERROR };

  /// Prints a string on a new line, not overprinting previous output.
  void PrintOnNewLine(const std::string& to_print);
  /// 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);

  /// 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_