blob: 3ca644f724f1771fd495f2e7c68ad8ae33951481 [file] [log] [blame]
Norman James6a58a272015-10-07 14:34:16 -05001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <limits.h>
5#include <time.h>
6
7static unsigned long progress_max;
8static unsigned int progress_pcent;
9static unsigned long progress_n_upd;
10static unsigned int progress_prevsec;
11static struct timespec progress_start;
12
13#define PROGRESS_CHARS 50
14
15void progress_init(unsigned long count)
16{
17 unsigned int i;
18
19 progress_max = count;
20 progress_pcent = 0;
21 progress_n_upd = ULONG_MAX;
22 progress_prevsec = UINT_MAX;
23
24 printf("\r[");
25 for (i = 0; i < PROGRESS_CHARS; i++)
26 printf(" ");
27 printf("] 0%%");
28 fflush(stdout);
29 clock_gettime(CLOCK_MONOTONIC, &progress_start);}
30
31void progress_tick(unsigned long cur)
32{
33 unsigned int pcent, i, pos, sec;
34 struct timespec now;
35
36 pcent = (cur * 100) / progress_max;
37 if (progress_pcent == pcent && cur < progress_n_upd &&
38 cur < progress_max)
39 return;
40 progress_pcent = pcent;
41 pos = (pcent * PROGRESS_CHARS) / 101;
42 clock_gettime(CLOCK_MONOTONIC, &now);
43
44 printf("\r[");
45 for (i = 0; i <= pos; i++)
46 printf("=");
47 for (; i < PROGRESS_CHARS; i++)
48 printf(" ");
49 printf("] %d%%", pcent);
50
51 sec = now.tv_sec - progress_start.tv_sec;
52 if (sec >= 5 && pcent > 0) {
53 unsigned int persec = cur / sec;
54 unsigned int rem_sec;
55
56 if (!persec)
57 persec = 1;
58 progress_n_upd = cur + persec;
59 rem_sec = ((sec * 100) + (pcent / 2)) / pcent - sec;
60 if (rem_sec > progress_prevsec)
61 rem_sec = progress_prevsec;
62 progress_prevsec = rem_sec;
63 if (rem_sec < 60)
64 printf(" ETA:%ds ", rem_sec);
65 else {
66 printf(" ETA:%d:%02d:%02d ",
67 rem_sec / 3600,
68 (rem_sec / 60) % 60,
69 rem_sec % 60);
70 }
71 }
72
73 fflush(stdout);
74}
75
76void progress_end(void)
77{
78 printf("\n");
79}