#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <limits.h> | |
#include <time.h> | |
static unsigned long progress_max; | |
static unsigned int progress_pcent; | |
static unsigned long progress_n_upd; | |
static unsigned int progress_prevsec; | |
static struct timespec progress_start; | |
#define PROGRESS_CHARS 50 | |
void progress_init(unsigned long count) | |
{ | |
unsigned int i; | |
progress_max = count; | |
progress_pcent = 0; | |
progress_n_upd = ULONG_MAX; | |
progress_prevsec = UINT_MAX; | |
printf("\r["); | |
for (i = 0; i < PROGRESS_CHARS; i++) | |
printf(" "); | |
printf("] 0%%"); | |
fflush(stdout); | |
clock_gettime(CLOCK_MONOTONIC, &progress_start);} | |
void progress_tick(unsigned long cur) | |
{ | |
unsigned int pcent, i, pos, sec; | |
struct timespec now; | |
pcent = (cur * 100) / progress_max; | |
if (progress_pcent == pcent && cur < progress_n_upd && | |
cur < progress_max) | |
return; | |
progress_pcent = pcent; | |
pos = (pcent * PROGRESS_CHARS) / 101; | |
clock_gettime(CLOCK_MONOTONIC, &now); | |
printf("\r["); | |
for (i = 0; i <= pos; i++) | |
printf("="); | |
for (; i < PROGRESS_CHARS; i++) | |
printf(" "); | |
printf("] %d%%", pcent); | |
sec = now.tv_sec - progress_start.tv_sec; | |
if (sec >= 5 && pcent > 0) { | |
unsigned int persec = cur / sec; | |
unsigned int rem_sec; | |
if (!persec) | |
persec = 1; | |
progress_n_upd = cur + persec; | |
rem_sec = ((sec * 100) + (pcent / 2)) / pcent - sec; | |
if (rem_sec > progress_prevsec) | |
rem_sec = progress_prevsec; | |
progress_prevsec = rem_sec; | |
if (rem_sec < 60) | |
printf(" ETA:%ds ", rem_sec); | |
else { | |
printf(" ETA:%d:%02d:%02d ", | |
rem_sec / 3600, | |
(rem_sec / 60) % 60, | |
rem_sec % 60); | |
} | |
} | |
fflush(stdout); | |
} | |
void progress_end(void) | |
{ | |
printf("\n"); | |
} |