| Norman James | 6a58a27 | 2015-10-07 14:34:16 -0500 | [diff] [blame] | 1 | #include <stdio.h>
 | 
 | 2 | #include <stdlib.h>
 | 
 | 3 | #include <string.h>
 | 
 | 4 | #include <limits.h>
 | 
 | 5 | #include <time.h>
 | 
 | 6 | 
 | 
 | 7 | static unsigned long progress_max;
 | 
 | 8 | static unsigned int progress_pcent;
 | 
 | 9 | static unsigned long progress_n_upd;
 | 
 | 10 | static unsigned int progress_prevsec;
 | 
 | 11 | static struct timespec progress_start;
 | 
 | 12 | 
 | 
 | 13 | #define PROGRESS_CHARS	50
 | 
 | 14 | 
 | 
 | 15 | void 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 | 
 | 
 | 31 | void 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 | 
 | 
 | 76 | void progress_end(void)
 | 
 | 77 | {
 | 
 | 78 | 	printf("\n");
 | 
 | 79 | }
 |