[PATCH] Unify progress counters
Hi,
* Rocco Rutte [06-11-14 19:19:39 +0000] wrote:
I hope I'll have some more time this week to look into again.
Alright, here's a RFC-quality patch.
It extends the progress bar feature internally into one which
understands (by now) to types of progress: either by size
(mutt_pretty_size() and friends) or just by numbers. All current
consumers of it have been updated, some others have been made to use it
(IMAP's cache evaluation, POP reading/writing folders).
So far it works nicely with both, size and message based progress, that
I've also attached a patch to display search progress based on $read_inc
using the new code.
The only real problem I still have with it is that it look totally
over-engineered now... :-/
bye, Rocco
--
:wq!
diff --git a/curs_lib.c b/curs_lib.c
index bc68335..96c5b9b 100644
--- a/curs_lib.c
+++ b/curs_lib.c
@@ -326,30 +326,63 @@ void mutt_curses_message (const char *fm
unset_option (OPTMSGERR);
}
-#ifdef USE_SOCKET
-void mutt_progress_bar (progress_t* progress, long pos)
+void mutt_progress_init (progress_t* progress, const char *msg,
+ unsigned short flags, unsigned short inc,
+ long size)
+{
+ if (!progress)
+ return;
+ memset (progress, 0, sizeof (progress_t));
+ progress->inc = inc;
+ progress->flags = flags;
+ progress->msg = msg;
+ progress->size = size;
+ mutt_progress_update (progress, 0);
+}
+
+void mutt_progress_update (progress_t* progress, long pos)
{
char posstr[SHORT_STRING];
+ short update = 0;
if (!pos)
{
- if (!NetInc)
+ if (!progress->inc)
mutt_message (progress->msg);
- else {
+ else
+ {
if (progress->size)
- mutt_pretty_size (progress->sizestr, sizeof (progress->sizestr),
progress->size);
+ {
+ if (progress->flags & PROG_SIZE)
+ mutt_pretty_size (progress->sizestr, sizeof (progress->sizestr),
progress->size);
+ else
+ snprintf (progress->sizestr, sizeof (progress->sizestr), "%ld",
progress->size);
+ }
progress->pos = 0;
}
}
- if (!NetInc)
+ if (!progress->inc)
return;
- if (pos >= progress->pos + (NetInc << 10))
+ if (progress->flags & PROG_SIZE)
+ {
+ if (pos >= progress->pos + (progress->inc << 10))
+ {
+ pos = pos / (progress->inc << 10) * (progress->inc << 10);
+ mutt_pretty_size (posstr, sizeof (posstr), pos);
+ update = 1;
+ }
+ }
+ else if (pos >= progress->pos + progress->inc)
+ {
+ snprintf (posstr, sizeof (posstr), "%ld", pos);
+ update = 1;
+ }
+
+ if (update)
{
progress->pos = pos;
- pos = pos / (NetInc << 10) * (NetInc << 10);
- mutt_pretty_size (posstr, sizeof (posstr), pos);
if (progress->size)
mutt_message ("%s %s/%s", progress->msg, posstr, progress->sizestr);
else
@@ -359,7 +392,6 @@ void mutt_progress_bar (progress_t* prog
if (pos >= progress->size)
mutt_clear_error ();
}
-#endif
void mutt_show_error (void)
{
diff --git a/imap/imap.c b/imap/imap.c
index 6a72351..03ca211 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -223,7 +223,7 @@ int imap_read_literal (FILE* fp, IMAP_DA
fputc (c, fp);
if (pbar && !(pos % 1024))
- mutt_progress_bar (pbar, pos);
+ mutt_progress_update (pbar, pos);
#ifdef DEBUG
if (debuglevel >= IMAP_LOG_LTRL)
fputc (c, debugfile);
diff --git a/imap/message.c b/imap/message.c
index 125446c..034f131 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -71,6 +71,7 @@ int imap_read_headers (IMAP_DATA* idata,
int fetchlast = 0;
int maxuid = 0;
const char *want_headers = "DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES
CONTENT-TYPE CONTENT-DESCRIPTION IN-REPLY-TO REPLY-TO LINES LIST-POST X-LABEL";
+ progress_t progress;
#if USE_HCACHE
header_cache_t *hc = NULL;
@@ -133,6 +134,9 @@ int imap_read_headers (IMAP_DATA* idata,
}
if (evalhc)
{
+ mutt_progress_init (&progress, _("Evaluating cache..."),
+ PROG_MSG, ReadInc, msgend + 1);
+
snprintf (buf, sizeof (buf),
"UID FETCH 1:%u (UID FLAGS)", *uidnext - 1);
FREE (&uidnext);
@@ -141,9 +145,7 @@ int imap_read_headers (IMAP_DATA* idata,
for (msgno = msgbegin; msgno <= msgend ; msgno++)
{
- if (ReadInc && (!msgno || ((msgno+1) % ReadInc == 0)))
- mutt_message (_("Evaluating cache... [%d/%d]"), msgno + 1,
- msgend + 1);
+ mutt_progress_update (&progress, msgno + 1);
memset (&h, 0, sizeof (h));
h.data = safe_calloc (1, sizeof (IMAP_HEADER_DATA));
@@ -211,11 +213,12 @@ int imap_read_headers (IMAP_DATA* idata,
}
#endif /* USE_HCACHE */
+ mutt_progress_init (&progress, _("Fetching message headers..."),
+ PROG_MSG, ReadInc, msgend + 1);
+
for (msgno = msgbegin; msgno <= msgend ; msgno++)
{
- if (ReadInc && (msgno == msgbegin || ((msgno+1) % ReadInc == 0)))
- mutt_message (_("Fetching message headers... [%d/%d]"), msgno + 1,
- msgend + 1);
+ mutt_progress_update (&progress, msgno + 1);
if (msgno + 1 > fetchlast)
{
@@ -454,9 +457,8 @@ int imap_fetch_message (MESSAGE *msg, CO
imap_error ("imap_fetch_message()", buf);
goto bail;
}
- progressbar.size = bytes;
- progressbar.msg = _("Fetching message...");
- mutt_progress_bar (&progressbar, 0);
+ mutt_progress_init (&progressbar, _("Fetching message..."),
+ PROG_SIZE, NetInc, bytes);
if (imap_read_literal (msg->fp, idata, bytes, &progressbar) < 0)
goto bail;
/* pick up trailing line */
@@ -593,10 +595,9 @@ int imap_append_message (CONTEXT *ctx, M
}
rewind (fp);
- progressbar.msg = _("Uploading message...");
- progressbar.size = len;
- mutt_progress_bar (&progressbar, 0);
-
+ mutt_progress_init (&progressbar, _("Uploading message..."),
+ PROG_SIZE, NetInc, len);
+
imap_munge_mbox_name (mbox, sizeof (mbox), mailbox);
snprintf (buf, sizeof (buf), "APPEND %s (%s%s%s%s%s) {%lu}", mbox,
msg->flags.read ? "\\Seen" : "",
@@ -639,7 +640,7 @@ int imap_append_message (CONTEXT *ctx, M
{
sent += len;
flush_buffer(buf, &len, idata->conn);
- mutt_progress_bar (&progressbar, sent);
+ mutt_progress_update (&progressbar, sent);
}
}
diff --git a/mutt_curses.h b/mutt_curses.h
index 8ee3d45..ac7915e 100644
--- a/mutt_curses.h
+++ b/mutt_curses.h
@@ -141,15 +141,23 @@ typedef struct color_line
struct color_line *next;
} COLOR_LINE;
+#define PROG_SIZE (1<<0) /* traffic-based progress */
+#define PROG_MSG (1<<1) /* message-based progress */
+
typedef struct
{
+ unsigned short inc;
+ unsigned short flags;
const char* msg;
long pos;
long size;
char sizestr[SHORT_STRING];
} progress_t;
-void mutt_progress_bar (progress_t* progress, long pos);
+void mutt_progress_init (progress_t* progress, const char *msg,
+ unsigned short flags, unsigned short inc,
+ long size);
+void mutt_progress_update (progress_t* progress, long pos);
extern int *ColorQuote;
extern int ColorQuoteUsed;
diff --git a/pop.c b/pop.c
index 98cd8a8..acc9181 100644
--- a/pop.c
+++ b/pop.c
@@ -197,6 +197,7 @@ static int pop_fetch_headers (CONTEXT *c
int i, ret, old_count, new_count;
unsigned short hcached = 0, bcached;
POP_DATA *pop_data = (POP_DATA *)ctx->data;
+ progress_t progress;
#ifdef USE_HCACHE
header_cache_t *hc = NULL;
@@ -235,7 +236,8 @@ static int pop_fetch_headers (CONTEXT *c
}
}
- mutt_message _("Fetching message headers...");
+ mutt_progress_init (&progress, _("Fetching message headers..."),
+ PROG_MSG, ReadInc, 0);
if (ret == 0)
{
@@ -245,10 +247,8 @@ static int pop_fetch_headers (CONTEXT *c
for (i = old_count; i < new_count; i++)
{
- if (!ctx->quiet && ReadInc && (((i - old_count) % ReadInc) == 0 || (i -
old_count) == 1))
- mutt_message (_("Fetching message headers... [%d/%d]"),
- i + 1 - old_count, new_count - old_count);
-
+ if (!ctx->quiet)
+ mutt_progress_update (&progress, i + 1 - old_count);
#if USE_HCACHE
if ((data = mutt_hcache_fetch (hc, ctx->hdrs[i]->data, strlen)))
{
@@ -509,9 +509,8 @@ int pop_fetch_message (MESSAGE* msg, CON
return -1;
}
- progressbar.size = h->content->length + h->content->offset - 1;
- progressbar.msg = _("Fetching message...");
- mutt_progress_bar (&progressbar, 0);
+ mutt_progress_init (&progressbar, _("Fetching message..."),
+ PROG_SIZE, NetInc, h->content->length +
h->content->offset - 1);
/* see if we can put in body cache; use our cache as fallback */
if (!(msg->fp = mutt_bcache_put (pop_data->bcache, h->data)))
@@ -597,6 +596,7 @@ int pop_sync_mailbox (CONTEXT *ctx, int
int i, j, ret = 0;
char buf[LONG_STRING];
POP_DATA *pop_data = (POP_DATA *)ctx->data;
+ progress_t progress;
#ifdef USE_HCACHE
header_cache_t *hc = NULL;
#endif
@@ -608,7 +608,8 @@ int pop_sync_mailbox (CONTEXT *ctx, int
if (pop_reconnect (ctx) < 0)
return -1;
- mutt_message (_("Marking %d messages deleted..."), ctx->deleted);
+ mutt_progress_init (&progress, _("Marking messages deleted..."),
+ PROG_MSG, WriteInc, ctx->deleted);
#if USE_HCACHE
hc = mutt_hcache_open (HeaderCache, ctx->path);
@@ -619,8 +620,8 @@ int pop_sync_mailbox (CONTEXT *ctx, int
if (ctx->hdrs[i]->deleted)
{
j++;
- if (!ctx->quiet && WriteInc && ((j % WriteInc) == 0 || j == 1))
- mutt_message (_("Deleting messages [%d/%d]..."), j, ctx->deleted);
+ if (!ctx->quiet)
+ mutt_progress_update (&progress, j);
snprintf (buf, sizeof (buf), "DELE %d\r\n", ctx->hdrs[i]->refno);
if ((ret = pop_query (pop_data, buf, sizeof (buf))) == 0)
{
diff --git a/pop_lib.c b/pop_lib.c
index fdd5256..7956f16 100644
--- a/pop_lib.c
+++ b/pop_lib.c
@@ -496,7 +496,7 @@ int pop_fetch_data (POP_DATA *pop_data,
else
{
if (progressbar)
- mutt_progress_bar (progressbar, pos);
+ mutt_progress_update (progressbar, pos);
if (ret == 0 && funct (inbuf, data) < 0)
ret = -3;
lenbuf = 0;
@@ -550,9 +550,8 @@ int pop_reconnect (CONTEXT *ctx)
{
int i;
- progressbar.msg = _("Verifying message indexes...");
- progressbar.size = 0;
- mutt_progress_bar (&progressbar, 0);
+ mutt_progress_init (&progressbar, _("Verifying message indexes..."),
+ PROG_SIZE, NetInc, 0);
for (i = 0; i < ctx->msgcount; i++)
ctx->hdrs[i]->refno = -1;
diff --git a/pattern.c b/pattern.c
index 1ce81f2..61cdee1 100644
--- a/pattern.c
+++ b/pattern.c
@@ -34,6 +34,7 @@
#include <stdarg.h>
#include "mutt_crypt.h"
+#include "mutt_curses.h"
#ifdef USE_IMAP
#include "mx.h"
@@ -1262,6 +1263,7 @@ int mutt_pattern_func (int op, char *pro
char buf[LONG_STRING] = "", *simple, error[STRING];
BUFFER err;
int i;
+ progress_t progress;
strfcpy (buf, NONULL (Context->pattern), sizeof (buf));
if (mutt_get_field (prompt, buf, sizeof (buf), M_PATTERN | M_CLEAR) != 0 ||
!buf[0])
@@ -1285,8 +1287,10 @@ int mutt_pattern_func (int op, char *pro
if (Context->magic == M_IMAP && imap_search (Context, pat) < 0)
return -1;
#endif
-
- mutt_message _("Executing command on matching messages...");
+
+ mutt_progress_init (&progress, _("Executing command on matching
messages..."),
+ PROG_MSG, ReadInc,
+ (op == M_LIMIT) ? Context->msgcount : Context->vcount);
#define THIS_BODY Context->hdrs[i]->content
@@ -1298,6 +1302,7 @@ int mutt_pattern_func (int op, char *pro
for (i = 0; i < Context->msgcount; i++)
{
+ mutt_progress_update (&progress, i);
/* new limit pattern implicitly uncollapses all threads */
Context->hdrs[i]->virtual = -1;
Context->hdrs[i]->limited = 0;
@@ -1318,6 +1323,7 @@ int mutt_pattern_func (int op, char *pro
{
for (i = 0; i < Context->vcount; i++)
{
+ mutt_progress_update (&progress, i);
if (mutt_pattern_exec (pat, M_MATCH_FULL_ADDRESS, Context,
Context->hdrs[Context->v2r[i]]))
{
switch (op)
@@ -1375,7 +1381,9 @@ int mutt_search_command (int cur, int op
BUFFER err;
int incr;
HEADER *h;
-
+ progress_t progress;
+ const char* msg = NULL;
+
if (op != OP_SEARCH_NEXT && op != OP_SEARCH_OPPOSITE)
{
strfcpy (buf, LastSearch, sizeof (buf));
@@ -1431,13 +1439,17 @@ int mutt_search_command (int cur, int op
if (op == OP_SEARCH_OPPOSITE)
incr = -incr;
+ mutt_progress_init (&progress, _("Searching..."), PROG_MSG,
+ ReadInc, Context->vcount);
+
for (i = cur + incr, j = 0 ; j != Context->vcount; j++)
{
+ mutt_progress_update (&progress, j);
if (i > Context->vcount - 1)
{
i = 0;
if (option (OPTWRAPSEARCH))
- mutt_message _("Search wrapped to top.");
+ msg = _("Search wrapped to top.");
else
{
mutt_message _("Search hit bottom without finding match");
@@ -1448,7 +1460,7 @@ int mutt_search_command (int cur, int op
{
i = Context->vcount - 1;
if (option (OPTWRAPSEARCH))
- mutt_message _("Search wrapped to bottom.");
+ msg = _("Search wrapped to bottom.");
else
{
mutt_message _("Search hit top without finding match");
@@ -1461,14 +1473,24 @@ int mutt_search_command (int cur, int op
{
/* if we've already evaulated this message, use the cached value */
if (h->matched)
+ {
+ mutt_clear_error();
+ if (msg && *msg)
+ mutt_message (msg);
return i;
+ }
}
else
{
/* remember that we've already searched this message */
h->searched = 1;
if ((h->matched = (mutt_pattern_exec (SearchPattern,
M_MATCH_FULL_ADDRESS, Context, h) > 0)))
+ {
+ mutt_clear_error();
+ if (msg && *msg)
+ mutt_message (msg);
return i;
+ }
}
if (SigInt)