free(tty->capbuf); tty->capbuf = 0;
}
-#if defined(USE_TERMINFO)
-static const struct progress_ttyinfo *curtty = 0;
-static int putty(int ch) { return (putc(ch, curtty->fp)); }
-static void put_sequence(const struct progress_ttyinfo *tty,
- const char *p, unsigned nlines)
- { if (p) { curtty = tty; tputs(p, nlines, putty); } }
-static void set_fgcolour(const struct progress_ttyinfo *tty, int colour)
- { put_sequence(tty, tgoto(tty->cap.af, -1, colour), 1); }
-static void set_bgcolour(const struct progress_ttyinfo *tty, int colour)
- { put_sequence(tty, tgoto(tty->cap.ab, -1, colour), 1); }
-#elif defined(USE_TERMCAP)
-static const struct progress_ttyinfo *curtty = 0;
-static int putty(int ch) { return (putc(ch, curtty->fp)); }
-static void put_sequence(const struct progress_ttyinfo *tty,
- const char *p, unsigned nlines)
- { if (p) { curtty = tty; tputs(p, nlines, putty); } }
-static void set_fgcolour(const struct progress_ttyinfo *tty, int colour)
- { put_sequence(tty, tgoto(tty->cap.af, -1, colour), 1); }
-static void set_bgcolour(const struct progress_ttyinfo *tty, int colour)
- { put_sequence(tty, tgoto(tty->cap.ab, -1, colour), 1); }
-#else
-static void put_sequence(const struct progress_ttyinfo *tty,
- const char *p, unsigned nlines) { ; }
-static void set_fgcolour(const struct progress_ttyinfo *tty, int colour)
- { ; }
-static void set_bgcolour(const struct progress_ttyinfo *tty, int colour)
- { ; }
-#endif
-
-#define CLRF_ALL 1u
-static int clear_progress(struct progress_state *progress,
- struct progress_render_state *render, unsigned f)
+int progress_additem(struct progress_state *progress,
+ struct progress_item *item)
{
- const struct progress_ttyinfo *tty = &progress->tty;
- unsigned ndel, nleave;
- unsigned i;
-
- if (!tty->fp) return (-1);
+ if (item->parent) return (-1);
+ item->prev = progress->end_item; item->next = 0;
+ if (progress->end_item) progress->end_item->next = item;
+ else progress->items = item;
+ progress->end_item = item; item->parent = progress;
+ progress->nitems++;
- put_sequence(tty, tty->cap.cr, 1);
- if (progress->last_lines) {
- if (f&CLRF_ALL)
- { ndel = progress->last_lines; nleave = 0; }
- else {
- if (progress->nitems >= progress->last_lines) ndel = 0;
- else ndel = progress->last_lines - progress->nitems;
- nleave = progress->last_lines - ndel;
- }
- if (!ndel)
- for (i = 0; i < nleave - 1; i++) put_sequence(tty, tty->cap.up, 1);
- else {
- for (i = 0; i < ndel - 1; i++) put_sequence(tty, tty->cap.up, 1);
- put_sequence(tty, tty->cap.cd, ndel);
- for (i = 0; i < nleave; i++) put_sequence(tty, tty->cap.up, 1);
- }
- }
- progress->last_lines = 0;
- if (ferror(tty->fp)) return (-1);
return (0);
}
-static int grow_linebuf(struct progress_render_state *render, size_t want)
-{
- char *newbuf; size_t newsz;
-
- if (want <= render->linesz) return (0);
- if (!render->linesz) newsz = 4*render->width + 1;
- else newsz = render->linesz;
- while (newsz < want) newsz *= 2;
- newbuf = malloc(newsz + 1); if (!newbuf) return (-1);
- newbuf[newsz] = 0;
- if (render->leftsz)
- memcpy(newbuf, render->linebuf, render->leftsz);
- if (render->rightsz)
- memcpy(newbuf + newsz - render->rightsz,
- render->linebuf + render->linesz - render->rightsz,
- render->rightsz);
- free(render->linebuf); render->linebuf = newbuf; render->linesz = newsz;
- return (0);
-}
-
-static int grow_tempbuf(struct progress_render_state *render, size_t want)
+int progress_removeitem(struct progress_state *progress,
+ struct progress_item *item)
{
- char *newbuf; size_t newsz;
+ if (!item->parent) return (-1);
+ if (item->next) item->next->prev = item->prev;
+ else (progress->end_item) = item->prev;
+ if (item->prev) item->prev->next = item->next;
+ else (progress->items) = item->next;
+ progress->nitems--; item->parent = 0;
- if (want <= render->tempsz) return (0);
- if (!render->tempsz) newsz = 4*render->width + 1;
- else newsz = render->tempsz;
- while (newsz < want) newsz *= 2;
- newbuf = malloc(newsz + 1); if (!newbuf) return (-1);
- newbuf[newsz] = 0;
- if (render->tempsz) memcpy(newbuf, render->tempbuf, render->tempsz);
- free(render->tempbuf); render->tempbuf = newbuf; render->tempsz = newsz;
return (0);
}
}
}
+static int grow_linebuf(struct progress_render_state *render, size_t want)
+{
+ char *newbuf; size_t newsz;
+
+ if (want <= render->linesz) return (0);
+ if (!render->linesz) newsz = 4*render->width + 1;
+ else newsz = render->linesz;
+ while (newsz < want) newsz *= 2;
+ newbuf = malloc(newsz + 1); if (!newbuf) return (-1);
+ newbuf[newsz] = 0;
+ if (render->leftsz)
+ memcpy(newbuf, render->linebuf, render->leftsz);
+ if (render->rightsz)
+ memcpy(newbuf + newsz - render->rightsz,
+ render->linebuf + render->linesz - render->rightsz,
+ render->rightsz);
+ free(render->linebuf); render->linebuf = newbuf; render->linesz = newsz;
+ return (0);
+}
+
+static int grow_tempbuf(struct progress_render_state *render, size_t want)
+{
+ char *newbuf; size_t newsz;
+
+ if (want <= render->tempsz) return (0);
+ if (!render->tempsz) newsz = 4*render->width + 1;
+ else newsz = render->tempsz;
+ while (newsz < want) newsz *= 2;
+ newbuf = malloc(newsz + 1); if (!newbuf) return (-1);
+ newbuf[newsz] = 0;
+ if (render->tempsz) memcpy(newbuf, render->tempbuf, render->tempsz);
+ free(render->tempbuf); render->tempbuf = newbuf; render->tempsz = newsz;
+ return (0);
+}
+
enum { LEFT, RIGHT };
static int putstr(struct progress_render_state *render, unsigned side,
const char *p, size_t n)
return (rc);
}
+#if defined(USE_TERMINFO)
+static const struct progress_ttyinfo *curtty = 0;
+static int putty(int ch) { return (putc(ch, curtty->fp)); }
+static void put_sequence(const struct progress_ttyinfo *tty,
+ const char *p, unsigned nlines)
+ { if (p) { curtty = tty; tputs(p, nlines, putty); } }
+static void set_fgcolour(const struct progress_ttyinfo *tty, int colour)
+ { put_sequence(tty, tgoto(tty->cap.af, -1, colour), 1); }
+static void set_bgcolour(const struct progress_ttyinfo *tty, int colour)
+ { put_sequence(tty, tgoto(tty->cap.ab, -1, colour), 1); }
+#elif defined(USE_TERMCAP)
+static const struct progress_ttyinfo *curtty = 0;
+static int putty(int ch) { return (putc(ch, curtty->fp)); }
+static void put_sequence(const struct progress_ttyinfo *tty,
+ const char *p, unsigned nlines)
+ { if (p) { curtty = tty; tputs(p, nlines, putty); } }
+static void set_fgcolour(const struct progress_ttyinfo *tty, int colour)
+ { put_sequence(tty, tgoto(tty->cap.af, -1, colour), 1); }
+static void set_bgcolour(const struct progress_ttyinfo *tty, int colour)
+ { put_sequence(tty, tgoto(tty->cap.ab, -1, colour), 1); }
+#else
+static void put_sequence(const struct progress_ttyinfo *tty,
+ const char *p, unsigned nlines) { ; }
+static void set_fgcolour(const struct progress_ttyinfo *tty, int colour)
+ { ; }
+static void set_bgcolour(const struct progress_ttyinfo *tty, int colour)
+ { ; }
+#endif
+
+#define CLRF_ALL 1u
+static int clear_progress(struct progress_state *progress,
+ struct progress_render_state *render, unsigned f)
+{
+ const struct progress_ttyinfo *tty = &progress->tty;
+ unsigned ndel, nleave;
+ unsigned i;
+
+ if (!tty->fp) return (-1);
+
+ put_sequence(tty, tty->cap.cr, 1);
+ if (progress->last_lines) {
+ if (f&CLRF_ALL)
+ { ndel = progress->last_lines; nleave = 0; }
+ else {
+ if (progress->nitems >= progress->last_lines) ndel = 0;
+ else ndel = progress->last_lines - progress->nitems;
+ nleave = progress->last_lines - ndel;
+ }
+ if (!ndel)
+ for (i = 0; i < nleave - 1; i++) put_sequence(tty, tty->cap.up, 1);
+ else {
+ for (i = 0; i < ndel - 1; i++) put_sequence(tty, tty->cap.up, 1);
+ put_sequence(tty, tty->cap.cd, ndel);
+ for (i = 0; i < nleave; i++) put_sequence(tty, tty->cap.up, 1);
+ }
+ }
+ progress->last_lines = 0;
+ if (ferror(tty->fp)) return (-1);
+ return (0);
+}
+
+int progress_clear(struct progress_state *progress)
+{
+ struct progress_render_state render;
+
+ if (!progress->tty.fp) return (-1);
+ if (setup_render_state(progress, &render)) return (-1);
+ clear_progress(progress, &render, CLRF_ALL);
+ free_render_state(&render);
+ return (0);
+}
+
+int progress_update(struct progress_state *progress)
+{
+ struct progress_render_state render;
+ const struct progress_ttyinfo *tty = &progress->tty;
+ struct progress_item *item;
+ unsigned f = 0;
+#define f_any 1u
+
+ if (!progress->tty.fp) return (-1);
+ if (setup_render_state(progress, &render)) return (-1);
+ clear_progress(progress, &render, 0);
+
+ for (item = progress->items; item; item = item->next) {
+ if (f&f_any) put_sequence(tty, tty->cap.nw, 1);
+ render.leftsz = render.rightsz = 0;
+ render.leftwd = render.rightwd = 0;
+ item->render(item, &render); progress->last_lines++; f |= f_any;
+ if (progress->last_lines > render.height) break;
+ }
+ if (f&f_any) put_sequence(tty, tty->cap.cr, 1);
+ free_render_state(&render);
+ return (0);
+}
+
enum {
LEFT_COLOUR,
LEFT_MONO,
return (0);
}
-
-int progress_additem(struct progress_state *progress,
- struct progress_item *item)
-{
- if (item->parent) return (-1);
- item->prev = progress->end_item; item->next = 0;
- if (progress->end_item) progress->end_item->next = item;
- else progress->items = item;
- progress->end_item = item; item->parent = progress;
- progress->nitems++;
-
- return (0);
-}
-
-int progress_clear(struct progress_state *progress)
-{
- struct progress_render_state render;
-
- if (!progress->tty.fp) return (-1);
- if (setup_render_state(progress, &render)) return (-1);
- clear_progress(progress, &render, CLRF_ALL);
- free_render_state(&render);
- return (0);
-}
-
-int progress_update(struct progress_state *progress)
-{
- struct progress_render_state render;
- const struct progress_ttyinfo *tty = &progress->tty;
- struct progress_item *item;
- unsigned f = 0;
-#define f_any 1u
-
- if (!progress->tty.fp) return (-1);
- if (setup_render_state(progress, &render)) return (-1);
- clear_progress(progress, &render, 0);
-
- for (item = progress->items; item; item = item->next) {
- if (f&f_any) put_sequence(tty, tty->cap.nw, 1);
- render.leftsz = render.rightsz = 0;
- render.leftwd = render.rightwd = 0;
- item->render(item, &render); progress->last_lines++; f |= f_any;
- if (progress->last_lines > render.height) break;
- }
- if (f&f_any) put_sequence(tty, tty->cap.cr, 1);
- free_render_state(&render);
- return (0);
-}
-
-int progress_removeitem(struct progress_state *progress,
- struct progress_item *item)
-{
- if (!item->parent) return (-1);
- if (item->next) item->next->prev = item->prev;
- else (progress->end_item) = item->prev;
- if (item->prev) item->prev->next = item->next;
- else (progress->items) = item->next;
- progress->nitems--; item->parent = 0;
-
- return (0);
-}