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 static void i2n (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
, int silent
) {
48 char cstr
[128], tstr
[128], wstr
[1025];
50 if (cur
> total
) cur
= total
;
53 wdt
= get_tty_width();
54 if (wdt
> 1024) wdt
= 1024;
56 sprintf(wstr
, "\r[%*s/%s]", strlen(tstr
), cstr
, tstr
);
58 if (!silent
) write(pbar_tty
, wstr
, slen
);
62 int dc
= (cur
>= total
? wdt
-slen
: ((uint64_t)(wdt
-slen
))*cur
/total
), pos
;
65 if (cur
== 0) dc
= -1;
66 if (silent
) return dc
+1; /* just return number of dots */
67 for (int f
= 0; f
< wdt
-slen
; ++f
) wstr
[pos
++] = (f
<= dc
? '.' : ' ');
69 write(pbar_tty
, wstr
, pos
);
70 sprintf(cstr
, "%4d%%", (int)(total
> 0 ? (uint64_t)100*cur
/total
: 100));
71 write(pbar_tty
, cstr
, strlen(cstr
));
78 void pbar_draw (uint64_t cur
, uint64_t total
) { pbar_draw_ex(cur
, total
, 0); }
79 int pbar_dot_count (uint64_t cur
, uint64_t total
) { return pbar_draw_ex(cur
, total
, 1); }
82 void pbar_clear (void) {
83 static const char *cstr
= "\r\x1b[K";
84 if (pbar_tty
>= 0) write(pbar_tty
, cstr
, strlen(cstr
));