]> git.saurik.com Git - apt.git/blame - apt-pkg/contrib/progress.cc
* merge from apt--mvo (fix resource leak, run apt.cron.daily only if
[apt.git] / apt-pkg / contrib / progress.cc
CommitLineData
404ec98e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
82c6b98d 3// $Id: progress.cc,v 1.12 2003/01/11 07:17:04 jgg Exp $
404ec98e
AL
4/* ######################################################################
5
6 OpProgress - Operation Progress
7
8 ##################################################################### */
9 /*}}}*/
10// Include Files /*{{{*/
404ec98e 11#include <apt-pkg/progress.h>
6f4f200a 12#include <apt-pkg/error.h>
0a8e3465 13#include <apt-pkg/configuration.h>
b2e465d6
AL
14
15#include <apti18n.h>
4d055c05
AL
16
17#include <iostream>
404ec98e 18#include <stdio.h>
4f333a8b 19#include <cstring>
404ec98e
AL
20 /*}}}*/
21
4d055c05
AL
22using namespace std;
23
404ec98e
AL
24// OpProgress::OpProgress - Constructor /*{{{*/
25// ---------------------------------------------------------------------
26/* */
27OpProgress::OpProgress() : Current(0), Total(0), Size(0), SubTotal(1),
28 LastPercent(0), Percent(0)
29{
30 memset(&LastTime,0,sizeof(LastTime));
31}
32 /*}}}*/
33// OpProgress::Progress - Sub progress with no state change /*{{{*/
34// ---------------------------------------------------------------------
a246f2dc
AL
35/* Current is the Base Overall progress in units of Total. Cur is the sub
36 progress in units of SubTotal. Size is a scaling factor that says what
37 percent of Total SubTotal is. */
404ec98e
AL
38void OpProgress::Progress(unsigned long Cur)
39{
77b9dbc2
AL
40 if (Total == 0 || Size == 0 || SubTotal == 0)
41 Percent = 0;
42 else
43 Percent = (Current + Cur/((float)SubTotal)*Size)*100.0/Total;
404ec98e
AL
44 Update();
45}
46 /*}}}*/
47// OpProgress::OverallProgress - Set the overall progress /*{{{*/
48// ---------------------------------------------------------------------
49/* */
50void OpProgress::OverallProgress(unsigned long Current, unsigned long Total,
171c75f1 51 unsigned long Size,const string &Op)
404ec98e
AL
52{
53 this->Current = Current;
54 this->Total = Total;
55 this->Size = Size;
56 this->Op = Op;
57 SubOp = string();
77b9dbc2
AL
58 if (Total == 0)
59 Percent = 0;
60 else
61 Percent = Current*100.0/Total;
404ec98e
AL
62 Update();
63}
64 /*}}}*/
65// OpProgress::SubProgress - Set the sub progress state /*{{{*/
66// ---------------------------------------------------------------------
67/* */
171c75f1 68void OpProgress::SubProgress(unsigned long SubTotal,const string &Op)
404ec98e
AL
69{
70 this->SubTotal = SubTotal;
71 SubOp = Op;
77b9dbc2
AL
72 if (Total == 0)
73 Percent = 0;
74 else
75 Percent = Current*100.0/Total;
404ec98e
AL
76 Update();
77}
78 /*}}}*/
8ce4327b
AL
79// OpProgress::SubProgress - Set the sub progress state /*{{{*/
80// ---------------------------------------------------------------------
81/* */
82void OpProgress::SubProgress(unsigned long SubTotal)
83{
84 this->SubTotal = SubTotal;
77b9dbc2
AL
85 if (Total == 0)
86 Percent = 0;
87 else
88 Percent = Current*100.0/Total;
8ce4327b
AL
89 Update();
90}
91 /*}}}*/
404ec98e
AL
92// OpProgress::CheckChange - See if the display should be updated /*{{{*/
93// ---------------------------------------------------------------------
94/* Progress calls are made so frequently that if every one resulted in
95 an update the display would be swamped and the system much slower.
96 This provides an upper bound on the update rate. */
97bool OpProgress::CheckChange(float Interval)
98{
99 // New major progress indication
100 if (Op != LastOp)
101 {
102 MajorChange = true;
103 LastOp = Op;
104 return true;
105 }
106 MajorChange = false;
107
1a7c9eba
AL
108 if (SubOp != LastSubOp)
109 {
110 LastSubOp = SubOp;
111 return true;
112 }
113
404ec98e
AL
114 if ((int)LastPercent == (int)Percent)
115 return false;
61ec2779
MV
116
117 LastPercent = Percent;
404ec98e 118
b2e465d6
AL
119 if (Interval == 0)
120 return false;
121
404ec98e
AL
122 // Check time delta
123 struct timeval Now;
124 gettimeofday(&Now,0);
125 double Diff = Now.tv_sec - LastTime.tv_sec + (Now.tv_usec - LastTime.tv_usec)/1000000.0;
126 if (Diff < Interval)
127 return false;
128 LastTime = Now;
129 return true;
130}
131 /*}}}*/
0a8e3465
AL
132// OpTextProgress::OpTextProgress - Constructor /*{{{*/
133// ---------------------------------------------------------------------
134/* */
135OpTextProgress::OpTextProgress(Configuration &Config) :
136 NoUpdate(false), NoDisplay(false), LastLen(0)
137{
138 if (Config.FindI("quiet",0) >= 1)
139 NoUpdate = true;
140 if (Config.FindI("quiet",0) >= 2)
141 NoDisplay = true;
142};
143 /*}}}*/
404ec98e
AL
144// OpTextProgress::Done - Clean up the display /*{{{*/
145// ---------------------------------------------------------------------
146/* */
147void OpTextProgress::Done()
148{
149 if (NoUpdate == false && OldOp.empty() == false)
150 {
151 char S[300];
6f4f200a 152 if (_error->PendingError() == true)
82c6b98d 153 snprintf(S,sizeof(S),_("%c%s... Error!"),'\r',OldOp.c_str());
b35d2f5f 154 else
82c6b98d 155 snprintf(S,sizeof(S),_("%c%s... Done"),'\r',OldOp.c_str());
404ec98e
AL
156 Write(S);
157 cout << endl;
158 OldOp = string();
0a8e3465
AL
159 }
160
161 if (NoUpdate == true && NoDisplay == false && OldOp.empty() == false)
162 {
163 OldOp = string();
164 cout << endl;
165 }
404ec98e
AL
166}
167 /*}}}*/
168// OpTextProgress::Update - Simple text spinner /*{{{*/
169// ---------------------------------------------------------------------
170/* */
171void OpTextProgress::Update()
172{
b2e465d6 173 if (CheckChange((NoUpdate == true?0:0.7)) == false)
404ec98e
AL
174 return;
175
176 // No percent spinner
177 if (NoUpdate == true)
178 {
179 if (MajorChange == false)
180 return;
0a8e3465
AL
181 if (NoDisplay == false)
182 {
183 if (OldOp.empty() == false)
184 cout << endl;
185 OldOp = "a";
186 cout << Op << "..." << flush;
187 }
188
404ec98e
AL
189 return;
190 }
191
192 // Erase the old text and 'log' the event
193 char S[300];
194 if (MajorChange == true && OldOp.empty() == false)
195 {
196 snprintf(S,sizeof(S),"\r%s",OldOp.c_str());
197 Write(S);
198 cout << endl;
199 }
200
201 // Print the spinner
202 snprintf(S,sizeof(S),"\r%s... %u%%",Op.c_str(),(unsigned int)Percent);
203 Write(S);
204
205 OldOp = Op;
206}
207 /*}}}*/
208// OpTextProgress::Write - Write the progress string /*{{{*/
209// ---------------------------------------------------------------------
210/* This space fills the end to overwrite the previous text */
211void OpTextProgress::Write(const char *S)
212{
213 cout << S;
214 for (unsigned int I = strlen(S); I < LastLen; I++)
215 cout << ' ';
216 cout << '\r' << flush;
217 LastLen = strlen(S);
218}
219 /*}}}*/