🌐 AI搜索 & 代理 主页
blob: 4344f4eed5e46c4e013018af8ef9ab062f740d8f [file] [log] [blame]
Nicolas Pitre96a02f82007-04-18 18:27:451#include "git-compat-util.h"
2#include "progress.h"
3
4static volatile sig_atomic_t progress_update;
5
6static void progress_interval(int signum)
7{
8 progress_update = 1;
9}
10
11static void set_progress_signal(void)
12{
13 struct sigaction sa;
14 struct itimerval v;
15
Nicolas Pitre180a9f22007-04-20 19:05:2716 progress_update = 0;
17
Nicolas Pitre96a02f82007-04-18 18:27:4518 memset(&sa, 0, sizeof(sa));
19 sa.sa_handler = progress_interval;
20 sigemptyset(&sa.sa_mask);
21 sa.sa_flags = SA_RESTART;
22 sigaction(SIGALRM, &sa, NULL);
23
24 v.it_interval.tv_sec = 1;
25 v.it_interval.tv_usec = 0;
26 v.it_value = v.it_interval;
27 setitimer(ITIMER_REAL, &v, NULL);
28}
29
30static void clear_progress_signal(void)
31{
32 struct itimerval v = {{0,},};
33 setitimer(ITIMER_REAL, &v, NULL);
34 signal(SIGALRM, SIG_IGN);
35 progress_update = 0;
36}
37
38int display_progress(struct progress *progress, unsigned n)
39{
Nicolas Pitre180a9f22007-04-20 19:05:2740 if (progress->delay) {
41 char buf[80];
42 if (!progress_update || --progress->delay)
43 return 0;
44 if (progress->total) {
45 unsigned percent = n * 100 / progress->total;
46 if (percent > progress->delayed_percent_treshold) {
47 /* inhibit this progress report entirely */
48 clear_progress_signal();
49 progress->delay = -1;
50 progress->total = 0;
51 return 0;
52 }
53 }
54 if (snprintf(buf, sizeof(buf),
55 progress->delayed_title, progress->total))
56 fprintf(stderr, "%s\n", buf);
57 }
Nicolas Pitre96a02f82007-04-18 18:27:4558 if (progress->total) {
59 unsigned percent = n * 100 / progress->total;
60 if (percent != progress->last_percent || progress_update) {
61 progress->last_percent = percent;
62 fprintf(stderr, "%s%4u%% (%u/%u) done\r",
Nicolas Pitre13aaf142007-04-20 18:10:0763 progress->prefix, percent, n, progress->total);
Nicolas Pitre96a02f82007-04-18 18:27:4564 progress_update = 0;
Alex Riesen421f9d12007-05-23 16:07:2565 progress->need_lf = 1;
Nicolas Pitre96a02f82007-04-18 18:27:4566 return 1;
67 }
68 } else if (progress_update) {
Nicolas Pitre13aaf142007-04-20 18:10:0769 fprintf(stderr, "%s%u\r", progress->prefix, n);
Nicolas Pitre96a02f82007-04-18 18:27:4570 progress_update = 0;
Alex Riesen421f9d12007-05-23 16:07:2571 progress->need_lf = 1;
Nicolas Pitre96a02f82007-04-18 18:27:4572 return 1;
73 }
74 return 0;
75}
76
Nicolas Pitre13aaf142007-04-20 18:10:0777void start_progress(struct progress *progress, const char *title,
78 const char *prefix, unsigned total)
Nicolas Pitre96a02f82007-04-18 18:27:4579{
Nicolas Pitre13aaf142007-04-20 18:10:0780 char buf[80];
81 progress->prefix = prefix;
Nicolas Pitre96a02f82007-04-18 18:27:4582 progress->total = total;
83 progress->last_percent = -1;
Nicolas Pitre180a9f22007-04-20 19:05:2784 progress->delay = 0;
Alex Riesen421f9d12007-05-23 16:07:2585 progress->need_lf = 0;
Nicolas Pitre13aaf142007-04-20 18:10:0786 if (snprintf(buf, sizeof(buf), title, total))
87 fprintf(stderr, "%s\n", buf);
Nicolas Pitre96a02f82007-04-18 18:27:4588 set_progress_signal();
89}
90
Nicolas Pitre180a9f22007-04-20 19:05:2791void start_progress_delay(struct progress *progress, const char *title,
92 const char *prefix, unsigned total,
93 unsigned percent_treshold, unsigned delay)
94{
95 progress->prefix = prefix;
96 progress->total = total;
97 progress->last_percent = -1;
98 progress->delayed_percent_treshold = percent_treshold;
99 progress->delayed_title = title;
100 progress->delay = delay;
Alex Riesen421f9d12007-05-23 16:07:25101 progress->need_lf = 0;
Nicolas Pitre180a9f22007-04-20 19:05:27102 set_progress_signal();
103}
104
Nicolas Pitre96a02f82007-04-18 18:27:45105void stop_progress(struct progress *progress)
106{
107 clear_progress_signal();
Alex Riesen421f9d12007-05-23 16:07:25108 if (progress->need_lf)
Nicolas Pitre96a02f82007-04-18 18:27:45109 fputc('\n', stderr);
110}