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