cosmetix
[k8muffin.git] / src / pbar.c
blobdfb12c05b15de53d9bb4d33b37ab0da064bc215b
1 #include <stdint.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
7 #include <sys/ioctl.h>
9 #include "pbar.h"
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;
18 else pbar_tty = -1;
22 static int get_tty_width (void) {
23 if (pbar_tty >= 0) {
24 struct winsize ws;
25 if (ioctl(pbar_tty, TIOCGWINSZ, &ws) != 0 || ws.ws_col < 2) return 79;
26 return ws.ws_col-1;
28 return 79;
32 void pbar_draw (uint32_t cur, uint32_t total) {
33 if (pbar_tty >= 0) {
34 char cstr[64], tstr[64], wstr[1025];
35 int slen, wdt;
36 if (cur > total) cur = total;
37 snprintf(tstr, sizeof(tstr), "%u", (unsigned int)total);
38 slen = strlen(tstr);
39 snprintf(cstr, sizeof(cstr), "%*u", slen, (unsigned int)cur);
40 slen = (slen*2)+6;
41 wdt = get_tty_width();
42 if (wdt > 1024) wdt = 1024;
43 /* numbers */
44 sprintf(wstr, "\r[%s/%s]", cstr, tstr);
45 write(pbar_tty, wstr, strlen(wstr));
46 if (slen+1 <= wdt) {
47 /* dots */
48 int dc = (cur >= total ? wdt-slen : ((uint64_t)(wdt-slen))*cur/total), pos;
49 strcpy(wstr, " [");
50 pos = strlen(wstr);
51 if (cur == 0) dc = -1;
52 for (int f = 0; f < wdt-slen; ++f) wstr[pos++] = (f <= dc ? '.' : ' ');
53 wstr[pos++] = ']';
54 write(pbar_tty, wstr, pos);
60 void pbar_clear (void) {
61 static const char *cstr = "\r\x1b[K";
62 if (pbar_tty >= 0) write(pbar_tty, cstr, strlen(cstr));