[PATCH] copy_file_file bugfix & other responsiveness fixes

Jindrich Makovicka makovick at kmlinux.fjfi.cvut.cz
Thu Feb 14 18:57:15 UTC 2002


This patch addresses the following issues

1) in file.c/copy_file_file, an event is read twice but only the second 
one is checked, which makes copying extremely hard to abort
2) view.c/search - added missing enable_interrupt_key(), also added 
checking for ESC
3) view.c/block_search - rewritten the search algorithm to use a lookup 
table - a little speedup
4) view.c - added an interruptible version of mc_read, displaying also 
the reading progress
5) find.c - content_search now check for events and searching can be 
suspended anytime (this is however a bit dirty hack, requiring a subtle 
change in dlg.c)

Please cc: to my private email, I am not a subscriber.

Regards,

-- 
Jindrich Makovicka


8<-------- snip
diff -urN vanilla/mc-4.5.99a/src/dlg.c mc-4.5.99a/src/dlg.c
--- vanilla/mc-4.5.99a/src/dlg.c    Wed Nov  7 13:15:11 2001
+++ mc-4.5.99a/src/dlg.c    Wed Feb 13 23:25:58 2002
@@ -848,6 +848,8 @@
         (*h->callback) (h, 0, DLG_IDLE);
         }
     }
+   
+    if (!h->running) break;
 
     update_cursor (h);
     (*h->callback)(h, 0, DLG_PRE_EVENT);
diff -urN vanilla/mc-4.5.99a/src/file.c mc-4.5.99a/src/file.c
--- vanilla/mc-4.5.99a/src/file.c    Wed Jan 30 16:30:20 2002
+++ mc-4.5.99a/src/file.c    Wed Feb 13 22:01:51 2002
@@ -734,7 +734,11 @@
         }
 
         file_progress_set_stalled_label (ctx, stalled_msg);
-        file_progress_show_bytes (ctx, *progress_bytes + n_read_total, 
ctx->progress_bytes);
+        return_status = file_progress_show_bytes (ctx, *progress_bytes 
+ n_read_total, ctx->progress_bytes);
+        if (return_status != FILE_CONT) {
+            mc_refresh ();
+            goto ret;
+        }
         return_status = file_progress_show (ctx, n_read_total, file_size);
         mc_refresh ();
         if (return_status != FILE_CONT)
diff -urN vanilla/mc-4.5.99a/src/find.c mc-4.5.99a/src/find.c
--- vanilla/mc-4.5.99a/src/find.c    Wed Nov 14 21:54:55 2001
+++ mc-4.5.99a/src/find.c    Thu Feb 14 09:06:58 2002
@@ -44,6 +44,7 @@
 #include "wtools.h"
 #include "cmd.h"        /* view_file_at_line */
 #include "boxes.h"
+#include "key.h"
 #include "../vfs/vfs.h"
 
 #if defined(HAVE_RX_H) && defined(HAVE_REGCOMP)
@@ -85,6 +86,10 @@
 static int is_start;        /* Status of the start/stop toggle button */
 static char *old_dir;
 
+static int resuming;
+static int last_line;
+static int last_pos;
+
 static Dlg_head *find_dlg;    /* The dialog */
 
 static WButton *stop_button;    /* pointer to the stop button */
@@ -410,7 +415,7 @@
  * Search the global (FIXME) content_pattern string in the
  * DIRECTORY/FILE.  It will add the found entries to the find listbox.
  */
-static void
+static int
 search_content (Dlg_head *h, char *directory, char *filename)
 {
     struct stat s;
@@ -419,19 +424,20 @@
     int file_fd;
     regex_t r; /* FIXME: move from search_content and make static */
     int flags = REG_EXTENDED|REG_NOSUB;
+    int ret_val = 0;
 
     fname = concat_dir_and_file (directory, filename);
 
     if (mc_stat (fname, &s) != 0 || !S_ISREG (s.st_mode)){
     g_free (fname);
-    return;
+    return 0;
     }
 
     file_fd = mc_open (fname, O_RDONLY);
     g_free (fname);
 
     if (file_fd == -1)
-    return;
+    return 0;
 
     g_snprintf (buffer, sizeof (buffer), _("Grepping in %s"), 
name_trunc (filename, FIND2_X_USE));
 
@@ -454,6 +460,14 @@
     int has_newline;
     char *p;
     int found = 0;
+    Gpm_Event event;
+    int c;
+
+    if (resuming) {
+        resuming = 0;
+        line = last_line;
+        pos = last_pos;
+    }
 
     while ((p = get_line_at (file_fd, buffer, &pos, &n_read, sizeof 
(buffer), &has_newline))){
         if (found == 0){    /* Search in binary line once */
@@ -469,11 +483,35 @@
         found = 0;
         }
         g_free (p);
+
+        if ((line & 0x3f) == 0) {
+        c = get_event (&event, h->mouse_status == MOU_REPEAT, 0);
+        if (c != EV_NONE) {
+                dlg_process_event (h, c, &event);
+            if (h->ret_value == B_ENTER
+            || h->ret_value == B_CANCEL
+            || h->ret_value == B_AGAIN
+            || h->ret_value == B_PANELIZE) {
+            stop_idle (h);
+            ret_val = 1;
+            break;
+            }
+            if (!h->send_idle_msg) {
+            resuming = 1;
+            last_line = line;
+            last_pos = pos;
+            ret_val = 1;
+            break;
+            }
+        }
+        }
+
     }
     regfree (&r);
     }
     disable_interrupt_key ();
     mc_close (file_fd);
+    return ret_val;
 }
 
 static int
@@ -569,9 +607,12 @@
     }
 
     if (regexp_match (find_pattern, dp->d_name, match_file)){
-    if (content_pattern)
-        search_content (h, directory, dp->d_name);
-    else
+    if (content_pattern) {
+        if (search_content (h, directory, dp->d_name)) {
+            g_free (tmp_name);
+        return 1;
+        }
+    } else
         find_add_match (h, directory, dp->d_name);
     }
    
@@ -815,6 +856,7 @@
 static int
 run_process (void)
 {
+    resuming = 0;
     set_idle_proc (find_dlg, 1);
     run_dlg (find_dlg);
     return find_dlg->ret_value;
diff -urN vanilla/mc-4.5.99a/src/view.c mc-4.5.99a/src/view.c
--- vanilla/mc-4.5.99a/src/view.c    Thu Nov 15 00:20:38 2001
+++ mc-4.5.99a/src/view.c    Thu Feb 14 11:54:48 2002
@@ -424,6 +424,56 @@
     return 0;
 }
 
+#define READ_PAGE_SIZE 32768
+ssize_t
+mc_read_interruptible (WView *view)
+{
+    int w = view->widget.cols - view->have_frame + 1;
+    int fd = view->file;
+    void *buf = view->data;
+    size_t count = view->s.st_size;
+    ssize_t to_read, res;
+    ssize_t total = 0;
+    Dlg_head *d = 0;
+    Gpm_Event event;
+    int c;
+
+    got_interrupt ();
+    enable_interrupt_key ();
+
+    if (verbose) {
+        d = message (D_INSERT, _(" View "), _("Readingz %s"), 
view->filename);
+    mc_refresh ();
+    }
+   
+    while (count) {
+    to_read = count > READ_PAGE_SIZE ? READ_PAGE_SIZE : count;
+    res = mc_read(fd, buf, to_read);
+    total += res;
+    if (res != to_read)
+        break;
+    if (got_interrupt ())
+        break;
+        event.x = -1;
+    if (verbose) {
+        view_percent (view, total, w, TRUE);
+        mc_refresh ();
+            c = get_event (&event, 0, 0);
+        if (c != EV_NONE) {
+                dlg_process_event (d, c, &event);
+            if (d->ret_value == B_CANCEL)
+                    break;
+            }
+    }
+    buf += to_read;
+    count -= to_read;
+    }
+    disable_interrupt_key ();
+    dlg_run_done (d);
+    destroy_dlg (d);
+    return total;
+}
+
 /* return values: NULL for success, else points to error message */
 static char *
 init_growing_view (WView *view, char *name, char *filename)
@@ -491,7 +541,7 @@
     view->data = (unsigned char*) g_malloc (view->s.st_size);
     if (view->data == NULL
     || mc_lseek(view->file,0,0) != 0
-    || mc_read(view->file, view->data, view->s.st_size) != 
view->s.st_size){
+    || mc_read_interruptible(view) != view->s.st_size){
         if (view->data != NULL)
         g_free (view->data);
     close_view_file (view);
@@ -1449,6 +1499,8 @@
     int found_len, search_start;
     int search_status;
     Dlg_head *d = 0;
+    Gpm_Event event;
+    int c;
    
     /* Used to keep track of where the line starts, when looking forward */
     /* is the index before transfering the line; the reverse case uses   */
@@ -1456,8 +1508,10 @@
     long forward_line_start;
     long reverse_line_start;
     long t;
+
     /* Clear interrupt status */
     got_interrupt ();
+    enable_interrupt_key ();
 
     if (verbose){
     d = message (D_INSERT, _(" Search "), _("Searching %s"), text);
@@ -1487,12 +1541,19 @@
         }
         if (got_interrupt ())
         break;
+        if (verbose) {
+                event.x = -1;
+            c = get_event (&event, 0, 0);
+            if (c != EV_NONE) {
+            dlg_process_event (d, c, &event);
+                if (d->ret_value == B_CANCEL)
+            break;
+        }
+        }
     }
     forward_line_start = p;
-    disable_interrupt_key ();
     s = get_line_at (view, &p, &t);
     reverse_line_start = p;
-    enable_interrupt_key ();
 
     if (!s)
         break;
@@ -1552,6 +1613,8 @@
     int w = view->widget.cols - view->have_frame + 1;
 
     char *d = buffer, b;
+    int lookup[256];
+    int i, step;
     unsigned long e;
 
     /* clear interrupt status */
@@ -1561,8 +1624,15 @@
 
     search_update_steps (view);
     update_activate = 0;
+
+    for (i = 0; i < 256; i++)
+    lookup[i] = len;
+    for (i = len-1; i >= 0; i--, d++)
+    lookup[(unsigned char)*d] = i;
+
+    d = buffer;
    
-    while (e < view->last_byte){
+    while (e+len-1 < view->last_byte){
     if (e >= update_activate){
         update_activate += update_steps;
         if (verbose){
@@ -1572,18 +1642,24 @@
         if (got_interrupt ())
         break;
     }
-    b = get_byte (view, e++);
-   
-    if (*d == b){
-        d++;
-        if (d - buffer == len){
-        disable_interrupt_key ();
-        return e - len;
-        }
-    } else {
-        e -= d - buffer;
+
+    b = get_byte(view, e+len-1);
+    step = lookup[(unsigned char)b];
+
+    if (step == 0) {
         d = buffer;
+        while (1) {
+            b = get_byte (view, e++);
+        if (*d != b) break;
+        d++;
+        if (d - buffer == len) {
+            disable_interrupt_key ();
+            return e - len;
+        }
+        }
+        step = 1;
     }
+    e += step;
     }
     disable_interrupt_key ();
     return -1;






More information about the mc-devel mailing list