#include #include #include #include #include "progbar.h" static char bar[128], spaces[128]; static const char spinner[] = "\\|/-"; void progbar_init(struct progbar *ctx, const char *units, FILE *fp) { memset(ctx, 0, sizeof (*ctx)); if (!bar[0]) memset(bar, '=', sizeof(bar)-1); if (!spaces[0]) memset(spaces, ' ', sizeof(spaces)-1); strncpy(ctx->units, units, sizeof(ctx->units)); ctx->file = fp; } void progbar_clear(struct progbar * ctx) { if (!(ctx->flags & E2F_FLAG_PROG_BAR)) return; fprintf(ctx->file, "\r%*s\r", 80, " "); fflush(ctx->file); ctx->flags &= ~E2F_FLAG_PROG_BAR; } int progbar_update(struct progbar * ctx, const char *label, int curr, int max, unsigned int dpynum) { int i; unsigned int tick; struct timeval tv; int dpywidth; int fixed_percent; assert (curr >= 0); assert (max > 0); float percent = ((float) curr) / ((float) max) * 100; if (ctx->flags & E2F_FLAG_PROG_SUPPRESS) return 0; /* * Calculate the new progress position. If the * percentage hasn't changed, then we skip out right * away. */ fixed_percent = (int) ((10 * percent) + 0.5); if (ctx->progress_last_percent == fixed_percent) return 0; ctx->progress_last_percent = fixed_percent; /* * If we've already updated the spinner once within * the last 1/8th of a second, no point doing it * again. */ gettimeofday(&tv, NULL); tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8)); if ((tick == ctx->progress_last_time) && (fixed_percent != 0) && (fixed_percent != 1000)) return 0; ctx->progress_last_time = tick; /* * Advance the spinner, and note that the progress bar * will be on the screen */ ctx->progress_pos = (ctx->progress_pos+1) & 3; ctx->flags |= E2F_FLAG_PROG_BAR; dpywidth = 66 - strlen(label); dpywidth = 8 * (dpywidth / 8); if (dpynum) dpywidth -= 8; i = ((percent * dpywidth) + 50) / 100; fprintf(ctx->file, "\r%s: |%s%s", label, bar + (sizeof(bar) - (i+1)), spaces + (sizeof(spaces) - (dpywidth - i + 1))); if (fixed_percent == 1000) fputc('|', ctx->file); else fputc(spinner[ctx->progress_pos & 3], ctx->file); fprintf(ctx->file, " %4.1f%% ", percent); if (dpynum) fprintf(ctx->file, "%u%s\r", dpynum, ctx->units); else fputs(" \r", ctx->file); if (fixed_percent == 1000) progbar_clear(ctx); fflush(ctx->file); return 0; } void spinner_init(struct spinner *ctx, FILE *fp) { memset(ctx, 0, sizeof (*ctx)); ctx->file = fp; } void spinner_touch(struct spinner *ctx) { fprintf(ctx->file, "%c", spinner[ctx->count++ % 4]); } void spinner_clear(struct spinner *ctx) { fputs("", ctx->file); }