[PATCH] File search responsiveness

David Sterba dave at jikos.cz
Thu Jul 3 00:43:02 UTC 2003


Hi,

I forgot to remove some debugging code and sent it with the patch.


 David

-------------- next part --------------
diff -X .diffignore -urNp mc/src/ChangeLog mc-find/src/ChangeLog
--- mc/src/ChangeLog	Thu Jul  3 01:39:14 CEST 2003
+++ mc-find/src/ChangeLog	Thu Jul  3 01:39:14 CEST 2003
@@ -0,0 +1,7 @@
+
+	* file.c: New enum for find progress state. Add context vars
+	for last position.
+	(check_find_events): New func.
+	(search_content): Resume operation and return status to the caller.
+	(run_process): Init.
+
diff -X .diffignore -urNp mc/src/find.c mc-find/src/find.c
--- mc/src/find.c	Wed Apr 16 17:26:29 2003
+++ mc-find/src/find.c	Thu Jul  3 01:39:10 2003
@@ -43,6 +43,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 */
@@ -64,6 +65,12 @@ enum {
     B_VIEW
 };
 
+typedef enum {
+    FIND_CONT,
+    FIND_SUSPEND,
+    FIND_ABORT
+} FindProgressStatus;
+
 /* List of directories to be ignored, separated by ':' */
 char *find_ignore_dirs = 0;
 
@@ -80,6 +87,11 @@ static int matches;		/* Number of matche
 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 */
@@ -437,32 +449,61 @@ get_line_at (int file_fd, char *buf, int
     return buffer;
 }
 
-/* 
+static FindProgressStatus
+check_find_events(Dlg_head *h)
+{
+    Gpm_Event event;
+    int c;
+
+    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) {
+           /* dialog terminated */
+           return FIND_ABORT;
+       }
+       if (!h->send_idle_msg) {
+           /* searching suspended */
+           return FIND_SUSPEND;
+       }
+    }
+
+    return FIND_CONT;
+}
+
+/*
  * search_content:
  *
  * 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));
 
@@ -480,7 +521,15 @@ search_content (Dlg_head *h, char *direc
 	char *p;
 	int found = 0;
 
-	while ((p = get_line_at (file_fd, buffer, &pos, &n_read, sizeof (buffer), &has_newline))){
+	if (resuming) {
+	   /* We've been previously suspended, start from the previous positio n */
+	   resuming = 0;
+	   line = last_line;
+	   pos = last_pos;
+	}
+
+        while ((p = get_line_at (file_fd, buffer, &pos, &n_read, sizeof (buffer), &has_newline))
+		&& (ret_val == 0)) {
 	    if (found == 0){	/* Search in binary line once */
 		if (regexec (r, p, 1, 0, 0) == 0){
 		    g_free (p);
@@ -494,10 +543,34 @@ search_content (Dlg_head *h, char *direc
 		found = 0;
 	    }
 	    g_free (p);
+
+	    if ((line & 0xff) == 0) {
+		FindProgressStatus res;
+
+		res = check_find_events(h);
+		switch (res) {
+		case FIND_ABORT:
+		    stop_idle (h);
+		    ret_val = 1;
+		    break;
+
+		case FIND_SUSPEND:
+		    resuming = 1;
+		    last_line = line;
+		    last_pos = pos;
+		    ret_val = 1;
+		    break;
+
+		default:
+		    break;
+		}
+	    }
 	}
     }
     disable_interrupt_key ();
     mc_close (file_fd);
+
+    return ret_val;
 }
 
 static int
@@ -593,9 +666,12 @@ do_search (struct Dlg_head *h)
     }
 
     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);
     }
     
@@ -849,6 +925,7 @@ setup_gui (void)
 static int
 run_process (void)
 {
+    resuming = 0;
     set_idle_proc (find_dlg, 1);
     run_dlg (find_dlg);
     return find_dlg->ret_value;


More information about the mc-devel mailing list