@@ -45,6 +45,19 @@ struct progress {
4545
4646static volatile sig_atomic_t progress_update ;
4747
48+ /*
49+ * These are only intended for testing the progress output, i.e. exclusively
50+ * for 'test-tool progress'.
51+ */
52+ int progress_testing ;
53+ uint64_t progress_test_ns = 0 ;
54+ void progress_test_force_update (void ); /* To silence -Wmissing-prototypes */
55+ void progress_test_force_update (void )
56+ {
57+ progress_update = 1 ;
58+ }
59+
60+
4861static void progress_interval (int signum )
4962{
5063 progress_update = 1 ;
@@ -55,6 +68,9 @@ static void set_progress_signal(void)
5568 struct sigaction sa ;
5669 struct itimerval v ;
5770
71+ if (progress_testing )
72+ return ;
73+
5874 progress_update = 0 ;
5975
6076 memset (& sa , 0 , sizeof (sa ));
@@ -72,6 +88,10 @@ static void set_progress_signal(void)
7288static void clear_progress_signal (void )
7389{
7490 struct itimerval v = {{0 ,},};
91+
92+ if (progress_testing )
93+ return ;
94+
7595 setitimer (ITIMER_REAL , & v , NULL );
7696 signal (SIGALRM , SIG_IGN );
7797 progress_update = 0 ;
@@ -88,6 +108,7 @@ static void display(struct progress *progress, uint64_t n, const char *done)
88108 const char * tp ;
89109 struct strbuf * counters_sb = & progress -> counters_sb ;
90110 int show_update = 0 ;
111+ int last_count_len = counters_sb -> len ;
91112
92113 if (progress -> delay && (!progress_update || -- progress -> delay ))
93114 return ;
@@ -115,21 +136,27 @@ static void display(struct progress *progress, uint64_t n, const char *done)
115136 if (show_update ) {
116137 if (is_foreground_fd (fileno (stderr )) || done ) {
117138 const char * eol = done ? done : "\r" ;
139+ size_t clear_len = counters_sb -> len < last_count_len ?
140+ last_count_len - counters_sb -> len + 1 :
141+ 0 ;
142+ /* The "+ 2" accounts for the ": ". */
143+ size_t progress_line_len = progress -> title_len +
144+ counters_sb -> len + 2 ;
145+ int cols = term_columns ();
118146
119- term_clear_line ();
120147 if (progress -> split ) {
121- fprintf (stderr , " %s%s" , counters_sb -> buf ,
122- eol );
123- } else if (!done &&
124- /* The "+ 2" accounts for the ": ". */
125- term_columns () < progress -> title_len +
126- counters_sb -> len + 2 ) {
127- fprintf ( stderr , "%s:\n %s%s " ,
128- progress -> title , counters_sb -> buf , eol );
148+ fprintf (stderr , " %s%* s" , counters_sb -> buf ,
149+ ( int ) clear_len , eol );
150+ } else if (!done && cols < progress_line_len ) {
151+ clear_len = progress -> title_len + 1 < cols ?
152+ cols - progress -> title_len - 1 : 0 ;
153+ fprintf ( stderr , "%s:%*s\n %s%s" ,
154+ progress -> title , ( int ) clear_len , " " ,
155+ counters_sb -> buf , eol );
129156 progress -> split = 1 ;
130157 } else {
131- fprintf (stderr , "%s: %s%s" , progress -> title ,
132- counters_sb -> buf , eol );
158+ fprintf (stderr , "%s: %s%* s" , progress -> title ,
159+ counters_sb -> buf , ( int ) clear_len , eol );
133160 }
134161 fflush (stderr );
135162 }
@@ -147,6 +174,14 @@ static void throughput_string(struct strbuf *buf, uint64_t total,
147174 strbuf_humanise_rate (buf , rate * 1024 );
148175}
149176
177+ static uint64_t progress_getnanotime (struct progress * progress )
178+ {
179+ if (progress_testing )
180+ return progress -> start_ns + progress_test_ns ;
181+ else
182+ return getnanotime ();
183+ }
184+
150185void display_throughput (struct progress * progress , uint64_t total )
151186{
152187 struct throughput * tp ;
@@ -157,7 +192,7 @@ void display_throughput(struct progress *progress, uint64_t total)
157192 return ;
158193 tp = progress -> throughput ;
159194
160- now_ns = getnanotime ( );
195+ now_ns = progress_getnanotime ( progress );
161196
162197 if (!tp ) {
163198 progress -> throughput = tp = xcalloc (1 , sizeof (* tp ));
@@ -289,7 +324,7 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
289324 struct throughput * tp = progress -> throughput ;
290325
291326 if (tp ) {
292- uint64_t now_ns = getnanotime ( );
327+ uint64_t now_ns = progress_getnanotime ( progress );
293328 unsigned int misecs , rate ;
294329 misecs = ((now_ns - progress -> start_ns ) * 4398 ) >> 32 ;
295330 rate = tp -> curr_total / (misecs ? misecs : 1 );
0 commit comments