12 static int pbar_tty
; // fd or -1
15 static __attribute__((constructor
)) void _ctor_pbar (void) {
16 if (isatty(STDOUT_FILENO
)) pbar_tty
= STDOUT_FILENO
;
17 else if (isatty(STDERR_FILENO
)) pbar_tty
= STDERR_FILENO
;
22 static int get_tty_width (void) {
25 if (ioctl(pbar_tty
, TIOCGWINSZ
, &ws
) != 0 || ws
.ws_col
< 2) return 79;
32 void pbar_u2s (char *dest
, uint64_t i
) {
33 char num
[128], *p
= num
+sizeof(num
);
38 if ((i
/= 10) == 0) break;
39 if (--cnt
== 0) { *(--p
) = ','; cnt
= 3; }
45 /* return number of dots */
46 static int pbar_draw_ex (uint64_t cur
, uint64_t total
, uint64_t taken
, int silent
) {
48 char cstr
[128], tstr
[128], wstr
[1025];
50 if (cur
> total
) cur
= total
;
51 if (taken
> total
) taken
= total
;
53 pbar_u2s(tstr
, total
);
54 wdt
= get_tty_width();
55 if (wdt
> 1024) wdt
= 1024;
57 sprintf(wstr
, "\r[%*s/%s]", strlen(tstr
), cstr
, tstr
);
59 if (!silent
) write(pbar_tty
, wstr
, slen
);
64 int dc
= (cur
>= total
? wdt
-slen
: ((uint64_t)(wdt
-slen
))*cur
/total
);
65 int tc
= (taken
>= total
? wdt
-slen
: ((uint64_t)(wdt
-slen
))*taken
/total
);
68 if (cur
== 0) dc
= -1;
69 if (silent
) return ((tc
+1)<<16)|(dc
+1); /* just return number of dots */
70 for (int f
= 0; f
< wdt
-slen
; ++f
) {
72 wstr
[pos
++] = (f
<= tc
? ':' : '.');
74 wstr
[pos
++] = (f
<= tc
? '*' : ' ');
78 write(pbar_tty
, wstr
, pos
);
79 sprintf(cstr
, "%4d%%", (int)(total
> 0 ? (uint64_t)100*cur
/total
: 100));
80 write(pbar_tty
, cstr
, strlen(cstr
));
87 void pbar_draw (uint64_t cur
, uint64_t total
, uint64_t taken
) { pbar_draw_ex(cur
, total
, taken
, 0); }
88 int pbar_dot_count (uint64_t cur
, uint64_t total
, uint64_t taken
) { return pbar_draw_ex(cur
, total
, taken
, 1); }
91 void pbar_clear (void) {
92 static const char *cstr
= "\r\x1b[K";
93 if (pbar_tty
>= 0) write(pbar_tty
, cstr
, strlen(cstr
));
97 void pbar_newline (void) {
98 if (pbar_tty
>= 0) write(pbar_tty
, "\r\n", 2); /* "\r\n" for strange tty modes */