Hello,

here is a better version of the previous patch, fixed and separated.

1) copy.patch - fixes the event handling in copy file dialog
2) findfile.patch - adds additional event checking into the grepping 
function to make the dialog react during grepping inside a file (I agree 
this is a bit hackish but seems to work and without threads it's hard to 
make a better solution)
3) vfsopen.patch - makes it possible to interrupt file load operation on 
vfs (typically slow ftp & accidentally pressing f3 on a large file)
4) viewintr.patch - Ctrl-G during file load without MMAP reverts to 
growing view (test - eg. NTFS partition); get_bottom_first in growing 
view can be interrupted (test - M-! ls -lR on root and pressing End); 
search can be interrupted
5) viewsearch.patch - block_search modified to use a lookup table to 
lower comparison count

Regards,

-- 
Jindrich Makovicka

diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/file.c 
mc-4.6.0-pre1/src/file.c
--- vanilla/mc-4.6.0-pre1/src/file.c    Fri Jul  5 06:04:41 2002
+++ mc-4.6.0-pre1/src/file.c    Tue Sep 24 19:14:44 2002
@@ -733,7 +733,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 --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/dlg.c 
mc-4.6.0-pre1/src/dlg.c
--- vanilla/mc-4.6.0-pre1/src/dlg.c     Fri Aug  2 06:36:04 2002
+++ mc-4.6.0-pre1/src/dlg.c     Tue Sep 24 19:16:40 2002
@@ -833,6 +833,9 @@
                (*h->callback) (h, 0, DLG_IDLE);
            }
        }
+       
+       /* to allow terminating the dlg from idle handler */
+       if (!h->running) break;
 
        update_cursor (h);
        (*h->callback)(h, 0, DLG_PRE_EVENT);
diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/find.c 
mc-4.6.0-pre1/src/find.c
--- vanilla/mc-4.6.0-pre1/src/find.c    Wed Aug 21 09:31:20 2002
+++ mc-4.6.0-pre1/src/find.c    Tue Sep 24 19:29:11 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"
 
 /* Size of the find parameters window */
@@ -79,6 +80,11 @@
 static int is_start;           /* Status of the start/stop toggle button */
 static char *old_dir;
 
+/* Where did we stop */
+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 */
@@ -420,27 +426,31 @@
  *
  * Search the global (FIXME) regexp compiled content_pattern string in the
  * DIRECTORY/FILE.  It will add the found entries to the find listbox.
+ * 
+ * returns 0 if do_search should look for another file
+ *         1 if do_search should exit and proceed to the event handler
  */
-static void
+static int
 search_content (Dlg_head *h, char *directory, char *filename)
 {
     struct stat s;
     char buffer [BUF_SMALL];
     char *fname;
     int file_fd;
+    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));
 
@@ -457,6 +467,15 @@
        int has_newline;
        char *p;
        int found = 0;
+       Gpm_Event event;
+       int c;
+
+       if (resuming) {
+           /* We've been previously suspended, start from the previous position */
+           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 */
@@ -472,10 +491,37 @@
                found = 0;
            }
            g_free (p);
+ 
+           /* check for events */
+           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) {
+                       /* closing events */
+                       stop_idle (h);
+                       ret_val = 1;
+                       break;
+                   }
+                   if (!h->send_idle_msg) {
+                       /* suspended */
+                       resuming = 1;
+                       last_line = line;
+                       last_pos = pos;
+                       ret_val = 1;
+                       break;
+                   }
+               }
+           }
+ 
        }
     }
     disable_interrupt_key ();
     mc_close (file_fd);
+    return ret_val;
 }
 
 static int
@@ -571,9 +617,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);
     }
     
@@ -817,6 +866,7 @@
 static int
 run_process (void)
 {
+    resuming = 0;
     set_idle_proc (find_dlg, 1);
     run_dlg (find_dlg);
     return find_dlg->ret_value;
diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/ext.c 
mc-4.6.0-pre1/src/ext.c
--- vanilla/mc-4.6.0-pre1/src/ext.c     Tue Aug 20 04:57:25 2002
+++ mc-4.6.0-pre1/src/ext.c     Tue Sep 24 19:14:44 2002
@@ -482,7 +482,9 @@
                                content_string [hasread] = 0;
                            }
                            mc_close (remotehandle);
-                       }
+                       } else {
+                           ret = 1;
+                       }
 #endif /* _OS_NT */
                    }
                    asked_file = 1;
diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/vfs/direntry.c 
mc-4.6.0-pre1/vfs/direntry.c
--- vanilla/mc-4.6.0-pre1/vfs/direntry.c        Tue Aug 20 04:57:26 2002
+++ mc-4.6.0-pre1/vfs/direntry.c        Tue Sep 24 19:14:44 2002
@@ -949,7 +949,9 @@
         goto error_3;
 
     /* Clear the interrupt status */
-    
+    got_interrupt();
+    enable_interrupt_key();
+
     while ((n = MEDATA->linear_read (me, &fh, buffer, sizeof(buffer)))) {
 
        if (n < 0)
@@ -957,6 +959,9 @@
 
        total += n;
        vfs_print_stats (me->name, _("Getting file"), ino->ent->name, total, 
stat_size);
+
+       if (got_interrupt())
+           goto error_1;
 
         if (write(handle, buffer, n) < 0) {
            me->verrno = errno;
diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/view.c 
mc-4.6.0-pre1/src/view.c
--- vanilla/mc-4.6.0-pre1/src/view.c    Wed Aug 21 09:31:29 2002
+++ mc-4.6.0-pre1/src/view.c    Tue Sep 24 20:02:32 2002
@@ -207,6 +207,23 @@
        delete_hook (&select_file_hook, view_hook);
 }
 
+/* check if the event is an interrupt key
+ * unfortunately we cannot enable SIGINT because then CTRL-C can
+ * stop the page reading in the middle and viewer gets confused
+ */
+static int int_key() 
+{
+    Gpm_Event event;
+    int c;
+
+    c = get_event (&event, 0, 0);
+    if (c == XCTRL('g') || c == ESC_CHAR || c == KEY_F(10) || c == XCTRL('c')) {
+       return 1;
+    }
+    return 0;
+}
+
+
 static int
 get_byte (WView *view, unsigned int byte_index)
 {
@@ -241,7 +258,7 @@
                        view->last_byte = view->first + view->bytes_read;
                }
                /* To force loading the next page */
-               if (n == VIEW_PAGE_SIZE && view->reading_pipe){
+               if (n == VIEW_PAGE_SIZE && (view->reading_pipe || view->partial)){
                    view->last_byte++;
                }
            }
@@ -424,6 +441,7 @@
 {
     view->growing_buffer = 0;
     view->reading_pipe   = 0;
+    view->partial        = 0;
     view->first = 0;
     view->last_byte = 0;
     if (msg){
@@ -433,6 +451,45 @@
     return 0;
 }
 
+/* read a file into memory, can be interrupted */
+#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;
+
+    if (verbose) {
+        d = message (D_INSERT, _(" View "), _("Reading %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 (int_key ()) break;
+       if (verbose) {
+           view_percent (view, total, w, TRUE);
+           mc_refresh ();
+       }
+       buf += to_read;
+       count -= to_read;
+    }
+    if (verbose) {
+       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)
@@ -473,6 +530,8 @@
 */
 static char *load_view_file (WView *view, int fd)
 {
+    int intr_flag = 0;
+    
     view->file = fd;
 
     if (view->s.st_size == 0){
@@ -500,12 +559,17 @@
     view->data = (unsigned char*) g_malloc (view->s.st_size);
     if (view->data == NULL
        || mc_lseek(view->file, 0, SEEK_SET) != 0
-       || mc_read(view->file, view->data, view->s.st_size) != view->s.st_size){
+       || (intr_flag = mc_read_interruptible(view) != view->s.st_size)){
         if (view->data != NULL)
            g_free (view->data);
        close_view_file (view);
+       if (intr_flag) {
+           view->partial = 1;
+           view->s.st_size = 0;
+       }
        return init_growing_view (view, 0, view->filename);
     }
+
     view->first = 0;
     view->bytes_read = view->s.st_size;
     return NULL;
@@ -528,6 +592,7 @@
     view->data = NULL;
     view->growing_buffer = 0;
     view->reading_pipe = 0;
+    view->partial = 0;
     view->mmapping = 0;
     view->blocks = 0;
     view->block_ptr = 0;
@@ -721,7 +786,9 @@
         }
        if (w > 70){
            printw (" ");
-           if (view->growing_buffer)
+           if (view->growing_buffer && view->growing_loading)
+               addstr (_("  [loading]"));
+           else if (view->growing_buffer)
                addstr (_("  [grow]"));
        }
         if (w > 26) {
@@ -1252,11 +1319,27 @@
     if (view->growing_buffer){
        int old_last_byte;
 
+       view->growing_loading = 1;
        old_last_byte = -1;
        while (old_last_byte != view->last_byte){
            old_last_byte = view->last_byte;
+           if (verbose) {
+               view_status(view, TRUE);
+               mc_refresh ();
+           }
+           attrset (NORMAL_COLOR);
+
            get_byte (view, view->last_byte+VIEW_PAGE_SIZE);
+           if (int_key()) break;
        }
+       view->growing_loading = 0;
+
+       if (verbose) {
+           view_status(view, TRUE);
+           mc_refresh ();
+       }
+       attrset (NORMAL_COLOR);
+
     }
 
     bottom_first = move_backward2 (view, view->last_byte, vheight - 1);
@@ -1265,7 +1348,7 @@
        bottom_first = (bottom_first + view->bytes_per_line - 1)
            / view->bytes_per_line * view->bytes_per_line;
     view->bottom_first = bottom_first;
-    
+
     return view->bottom_first;
 }
 
@@ -1475,8 +1558,6 @@
     long forward_line_start;
     long reverse_line_start;
     long t;
-    /* Clear interrupt status */
-    got_interrupt ();
 
     if (verbose){
        d = message (D_INSERT, _(" Search "), _("Searching %s"), text);
@@ -1504,14 +1585,11 @@
                view_percent (view, p, w, TRUE);
                mc_refresh ();
            }
-           if (got_interrupt ())
-               break;
+           if (int_key()) 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,7 +1630,6 @@
        g_free (s);
        break;
     }
-    disable_interrupt_key ();
     if (verbose) {
        dlg_run_done (d);
        destroy_dlg (d);
diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/view.h 
mc-4.6.0-pre1/src/view.h
--- vanilla/mc-4.6.0-pre1/src/view.h    Sat Jul 20 04:54:52 2002
+++ mc-4.6.0-pre1/src/view.h    Tue Sep 24 19:37:36 2002
@@ -28,6 +28,8 @@
     int file;                  /* File descriptor (for mmap and munmap) */
     FILE *stdfile;             /* Stdio struct for reading file in parts */
     int reading_pipe;          /* Flag: Reading from pipe(use popen/pclose) */
+    int partial;                /* Flag: File reading was interrupted,
+                                  reverted to growing view */
     unsigned long bytes_read;   /* How much of file is read */
     int mmapping;              /* Did we use mmap on the file? */
 
@@ -60,6 +62,7 @@
     
     /* Growing buffers information */
     int growing_buffer;                /* Use the growing buffers? */
+    int growing_loading;        /* Loading additional blocks NOW */
     block_ptr_t *block_ptr;    /* Pointer to the block pointers */
     int          blocks;       /* The number of blocks in *block_ptr */
 
diff --exclude-from dontdiff -urN vanilla/mc-4.6.0-pre1/src/view.c 
mc-4.6.0-pre1/src/view.c
--- vanilla/mc-4.6.0-pre1/src/view.c    Wed Aug 21 09:31:29 2002
+++ mc-4.6.0-pre1/src/view.c    Tue Sep 24 19:51:40 2002
@@ -1571,40 +1651,51 @@
     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 */
-    got_interrupt ();
-    enable_interrupt_key ();
     e = view->found_len ? view->search_start + 1 : view->search_start;
 
     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){
                view_percent (view, e, w, TRUE);
                mc_refresh ();
            }
-           if (got_interrupt ())
-               break;
+           if (int_key()) 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) {
+           /* possible match, need to compare whole string */
            d = buffer;
+           while (1) {
+               b = get_byte (view, e++);
+               if (*d != b) break;
+               d++;
+               if (d - buffer == len) {
+                   /* match */
+                   return e - len;
+               }
+           }
+           step = 1;
        }
+       e += step;
     }
-    disable_interrupt_key ();
     return -1;
 }
 

Reply via email to