<<< Date Index >>>     <<< Thread Index >>>

[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)