blob: 80526352ed206eaf7d5c2b6402007e2a86648036 [file] [log] [blame]
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#include <assert.h>
#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);
}