]> git.saurik.com Git - apt.git/blobdiff - apt-private/acqprogress.cc
respect user pinning in M-A:same version (un)screwing
[apt.git] / apt-private / acqprogress.cc
index e834d7d6ac8e9bcb411565b8154f8d032a5217bf..c182fa02dfd4ebd9379d8595656976e61c4773e1 100644 (file)
@@ -1,10 +1,9 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: acqprogress.cc,v 1.24 2003/04/27 01:56:48 doogie Exp $
 /* ######################################################################
 
-   Acquire Progress - Command line progress meter 
-   
+   Acquire Progress - Command line progress meter
+
    ##################################################################### */
                                                                        /*}}}*/
 // Include files                                                       /*{{{*/
 #include <apti18n.h>
                                                                        /*}}}*/
 
-using namespace std;
-
 // AcqTextStatus::AcqTextStatus - Constructor                          /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int const Quiet) :
-    pkgAcquireStatus(), ScreenWidth(ScreenWidth), LastLineLength(0), ID(0), Quiet(Quiet)
+AcqTextStatus::AcqTextStatus(std::ostream &out, unsigned int &ScreenWidth,unsigned int const Quiet) :
+    pkgAcquireStatus(), out(out), ScreenWidth(ScreenWidth), LastLineLength(0), ID(0), Quiet(Quiet)
 {
    // testcases use it to disable pulses without disabling other user messages
    if (Quiet == 0 && _config->FindB("quiet::NoUpdate", false) == true)
       this->Quiet = 1;
+   if (Quiet < 2 && _config->FindB("quiet::NoProgress", false) == true)
+      this->Quiet = 2;
 }
                                                                        /*}}}*/
 // AcqTextStatus::Start - Downloading has started                      /*{{{*/
@@ -52,6 +51,16 @@ void AcqTextStatus::Start()
    ID = 1;
 }
                                                                        /*}}}*/
+void AcqTextStatus::AssignItemID(pkgAcquire::ItemDesc &Itm)            /*{{{*/
+{
+   /* In theory calling it from Fetch() would be enough, but to be
+      safe we call it from IMSHit and Fail as well.
+      Also, an Item can pass through multiple stages, so ensure
+      that it keeps the same number */
+   if (Itm.Owner->ID == 0)
+      Itm.Owner->ID = ID++;
+}
+                                                                       /*}}}*/
 // AcqTextStatus::IMSHit - Called when an item got a HIT response      /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -60,10 +69,12 @@ void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc &Itm)
    if (Quiet > 1)
       return;
 
+   AssignItemID(Itm);
    clearLastLine();
 
-   cout << _("Hit ") << Itm.Description;
-   cout << endl;
+   // TRANSLATOR: Very short word to be displayed before unchanged files in 'apt-get update'
+   ioprintf(out, _("Hit:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
+   out << std::endl;
    Update = true;
 }
                                                                        /*}}}*/
@@ -75,26 +86,28 @@ void AcqTextStatus::Fetch(pkgAcquire::ItemDesc &Itm)
    Update = true;
    if (Itm.Owner->Complete == true)
       return;
-
-   Itm.Owner->ID = ID++;
+   AssignItemID(Itm);
 
    if (Quiet > 1)
       return;
 
    clearLastLine();
 
-   cout << _("Get:") << Itm.Owner->ID << ' ' << Itm.Description;
+   // TRANSLATOR: Very short word to be displayed for files processed in 'apt-get update'
+   // Potentially replaced later by "Hit:", "Ign:" or "Err:" if something (bad) happens
+   ioprintf(out, _("Get:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
    if (Itm.Owner->FileSize != 0)
-      cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
-   cout << endl;
+      out << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
+   out << std::endl;
 }
                                                                        /*}}}*/
 // AcqTextStatus::Done - Completed a download                          /*{{{*/
 // ---------------------------------------------------------------------
 /* We don't display anything... */
-void AcqTextStatus::Done(pkgAcquire::ItemDesc &/*Itm*/)
+void AcqTextStatus::Done(pkgAcquire::ItemDesc &Itm)
 {
    Update = true;
+   AssignItemID(Itm);
 }
                                                                        /*}}}*/
 // AcqTextStatus::Fail - Called when an item fails to download         /*{{{*/
@@ -105,25 +118,43 @@ void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
    if (Quiet > 1)
       return;
 
-   // Ignore certain kinds of transient failures (bad code)
-   if (Itm.Owner->Status == pkgAcquire::Item::StatIdle)
-      return;
-
+   AssignItemID(Itm);
    clearLastLine();
 
-   if (Itm.Owner->Status == pkgAcquire::Item::StatDone)
+   bool ShowErrorText = true;
+   if (Itm.Owner->Status == pkgAcquire::Item::StatDone || Itm.Owner->Status == pkgAcquire::Item::StatIdle)
    {
-      cout << _("Ign ") << Itm.Description << endl;
-      if (Itm.Owner->ErrorText.empty() == false &&
-           _config->FindB("Acquire::Progress::Ignore::ShowErrorText", false) == true)
-        cout << "  " << Itm.Owner->ErrorText << endl;
+      // TRANSLATOR: Very short word to be displayed for files in 'apt-get update'
+      // which failed to download, but the error is ignored (compare "Err:")
+      ioprintf(out, _("Ign:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
+      if (Itm.Owner->ErrorText.empty() ||
+           _config->FindB("Acquire::Progress::Ignore::ShowErrorText", false) == false)
+        ShowErrorText = false;
    }
    else
    {
-      cout << _("Err ") << Itm.Description << endl;
-      cout << "  " << Itm.Owner->ErrorText << endl;
+      // TRANSLATOR: Very short word to be displayed for files in 'apt-get update'
+      // which failed to download and the error is critical (compare "Ign:")
+      ioprintf(out, _("Err:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
    }
 
+   if (ShowErrorText)
+   {
+      std::string::size_type line_start = 0;
+      std::string::size_type line_end;
+      while ((line_end = Itm.Owner->ErrorText.find_first_of("\n\r", line_start)) != std::string::npos) {
+        out << std::endl << "  " << Itm.Owner->ErrorText.substr(line_start, line_end - line_start);
+        line_start = Itm.Owner->ErrorText.find_first_not_of("\n\r", line_end + 1);
+        if (line_start == std::string::npos)
+           break;
+      }
+      if (line_start == 0)
+        out << std::endl << "  " << Itm.Owner->ErrorText;
+      else if (line_start != std::string::npos)
+        out << std::endl << "  " << Itm.Owner->ErrorText.substr(line_start);
+   }
+   out << std::endl;
+
    Update = true;
 }
                                                                        /*}}}*/
@@ -143,7 +174,7 @@ void AcqTextStatus::Stop()
       return;
 
    if (FetchedBytes != 0 && _error->PendingError() == false)
-      ioprintf(cout,_("Fetched %sB in %s (%sB/s)\n"),
+      ioprintf(out,_("Fetched %sB in %s (%sB/s)\n"),
               SizeToStr(FetchedBytes).c_str(),
               TimeToStr(ElapsedTime).c_str(),
               SizeToStr(CurrentCPS).c_str());
@@ -152,7 +183,7 @@ void AcqTextStatus::Stop()
 // AcqTextStatus::Pulse - Regular event pulse                          /*{{{*/
 // ---------------------------------------------------------------------
 /* This draws the current progress. Each line has an overall percent
-   meter and a per active item status meter along with an overall 
+   meter and a per active item status meter along with an overall
    bandwidth and ETA indicator. */
 bool AcqTextStatus::Pulse(pkgAcquire *Owner)
 {
@@ -161,8 +192,6 @@ bool AcqTextStatus::Pulse(pkgAcquire *Owner)
    if (Quiet > 0)
       return true;
 
-   enum {Long = 0,Medium,Short} Mode = Medium;
-
    std::string Line;
    {
       std::stringstream S;
@@ -188,6 +217,7 @@ bool AcqTextStatus::Pulse(pkgAcquire *Owner)
         if (I->CurrentItem->Owner->ActiveSubprocess.empty() == false)
            S << " " << I->CurrentItem->Owner->ActiveSubprocess;
 
+        enum {Long = 0,Medium,Short} Mode = Medium;
         // Add the current progress
         if (Mode == Long)
            S << " " << I->CurrentSize;
@@ -250,14 +280,14 @@ bool AcqTextStatus::Pulse(pkgAcquire *Owner)
 
    // Draw the current status
    if (_config->FindB("Apt::Color", false) == true)
-      cout << _config->Find("APT::Color::Yellow");
+      out << _config->Find("APT::Color::Yellow");
    if (LastLineLength > Line.length())
       clearLastLine();
    else
-      cout << '\r';
-   cout << Line << flush;
+      out << '\r';
+   out << Line << std::flush;
    if (_config->FindB("Apt::Color", false) == true)
-      cout << _config->Find("APT::Color::Neutral") << flush;
+      out << _config->Find("APT::Color::Neutral") << std::flush;
 
    LastLineLength = Line.length();
    Update = false;
@@ -268,7 +298,7 @@ bool AcqTextStatus::Pulse(pkgAcquire *Owner)
 // AcqTextStatus::MediaChange - Media need to be swapped               /*{{{*/
 // ---------------------------------------------------------------------
 /* Prompt for a media swap */
-bool AcqTextStatus::MediaChange(string Media,string Drive)
+bool AcqTextStatus::MediaChange(std::string Media, std::string Drive)
 {
    // If we do not output on a terminal and one of the options to avoid user
    // interaction is given, we assume that no user is present who could react
@@ -281,9 +311,9 @@ bool AcqTextStatus::MediaChange(string Media,string Drive)
       return false;
 
    clearLastLine();
-   ioprintf(cout,_("Media change: please insert the disc labeled\n"
+   ioprintf(out,_("Media change: please insert the disc labeled\n"
                   " '%s'\n"
-                  "in the drive '%s' and press enter\n"),
+                  "in the drive '%s' and press [Enter]\n"),
            Media.c_str(),Drive.c_str());
 
    char C = 0;
@@ -301,16 +331,16 @@ bool AcqTextStatus::MediaChange(string Media,string Drive)
 }
                                                                        /*}}}*/
 void AcqTextStatus::clearLastLine() {                                  /*{{{*/
-   if (Quiet > 0)
+   if (Quiet > 0 || LastLineLength == 0)
       return;
 
    // do not try to clear more than the (now smaller) screen
    if (LastLineLength > ScreenWidth)
       LastLineLength = ScreenWidth;
 
-   std::cout << '\r';
+   out << '\r';
    for (size_t i = 0; i < LastLineLength; ++i)
-      std::cout << ' ';
-   std::cout << '\r' << std::flush;
+      out << ' ';
+   out << '\r' << std::flush;
 }
                                                                        /*}}}*/