[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