#include "ghash.h"
#include "cc.h"
-#ifndef PATHSEP
-# if defined(__riscos)
-# define PATHSEP '.'
-# elif defined(__unix) || defined(unix)
-# define PATHSEP '/'
-# else
-# define PATHSEP '\\'
-# endif
-#endif
-
/*----- Static variables --------------------------------------------------*/
#define f_binary 1u
* Use: Hashes a file.
*/
-struct unit {
- const char *name;
- int m;
-};
-
-static void prhuman_time(FILE *fp, unsigned long n)
-{
- const static struct unit utime[] = {
- { "s", 60 }, { "m", 60 }, { "h", 24 }, { "d", 0 }
- };
-
- unsigned long m = 0;
- const struct unit *u = utime;
-
- while (u[1].m && n > u[0].m*u[1].m) { n /= u->m; u++; }
- m = n / u[1].m; n %= u[0].m;
- if (m) fprintf(fp, "%3lu%s%02lu%s", m, u[1].name, n, u[0].name);
- else fprintf(fp, " %2lu%s", n, u[0].name);
-}
-
-static void prhuman_data(FILE *fp, off_t n)
-{
- const static struct unit udata[] = {
- { " ", 1024 }, { "k", 1024 }, { "M", 1024 }, { "G", 1024 },
- { "T", 1024 }, { "P", 1024 }, { "E", 1024 }, { "Z", 1024 },
- { "Y", 0 }
- };
-
- double x = n;
- const struct unit *u = udata;
-
- while (u->m && x >= u->m) { x /= u->m; u++; }
- fprintf(fp, "%6.1f%s", x, u->name);
-}
-
static int fhash(const char *file, unsigned f, const gchash *gch, void *buf)
{
FILE *fp;
size_t sz;
ghash *h;
int e;
- off_t fsz = -1, fo;
- const char *p;
- dstr d = DSTR_INIT;
- static char baton[] = "-\\|/";
- char *bp = baton;
- time_t now, last, start;
- int i, pc;
+ fprogress ff;
if (!file || strcmp(file, "-") == 0)
fp = stdin;
return (-1);
if (f & f_progress) {
- if ((fo = ftello(fp)) >= 0 &&
- fseeko(fp, 0, SEEK_END) >= 0 &&
- (fsz = ftello(fp),
- fseeko(fp, fo, SEEK_SET) < 0))
- return (-1);
- if (fo != -1 && fsz != -1) fsz -= fo;
- fo = 0;
- sz = strlen(file);
- if (sz < 24)
- dstr_puts(&d, file);
- else if ((p = strchr(file + sz - 20, PATHSEP)) != 0) {
- dstr_puts(&d, "..."); dstr_puts(&d, p);
- } else {
- p = strrchr(file, PATHSEP);
- if (!p) dstr_putf(&d, "%.20s...", file);
- else dstr_putf(&d, "...%.17s...", p);
- }
- start = last = time(0);
+ if (fprogress_init(&ff, file, fp)) return (-1);
}
h = GH_INIT(gch);
while ((sz = fread(fbuf, 1, sizeof(fbuf), fp)) > 0) {
GH_HASH(h, fbuf, sz);
- if (f & f_progress) {
- fo += sz;
- now = time(0);
- if (difftime(now, last) < 1) continue;
- last = now;
- fprintf(stderr, "\r%-24s", d.buf);
- fprintf(stderr, "%c ", *bp++); if (!*bp) bp = baton;
- prhuman_data(stderr, fo);
- if (fsz >= fo) {
- fputc('/', stderr);
- prhuman_data(stderr, fsz);
- fputs(" [", stderr);
- pc = (fo*16 + fsz/2)/fsz;
- for (i = 0; i < pc; i++) fputc('.', stderr);
- for (; i < 16; i++) fputc(' ', stderr);
- fprintf(stderr, "] %3d%%", (int)((fo*100 + 50)/fsz));
- fprintf(stderr, " ETA ");
- prhuman_time(stderr, difftime(now, start)*(fsz - fo)/fo);
- }
- }
+ if (f & f_progress) fprogress_update(&ff, sz);
}
GH_DONE(h, buf);
GH_DESTROY(h);
- if (f & f_progress) fprintf(stderr, "\r%78s\r", "");
+ if (f & f_progress) fprogress_done(&ff);
e = ferror(fp);
if (file)
fclose(fp);