Eliminate egrep in Find file feature: 1st Approximation



Hi!

This patch eliminates egrep usage in Find file feature. 
So we can search desired regular expression over VFS and in binary files and
on platforms without egrep.

ChangeLog:
	* find.c (get_line_at): New function. Returns malloced null-terminated
	string from file descriptor file_fd. Input is buffered in buf 
	buf_size long. Newline(s) accounted in line variable.

	(search_content): Use get_line_at and regex.

TODO: Move regcomp and regfree calls and r variable from search_content.
Make r static. Inform user about malformed regular experssion (message can be
taken from view.c).
Add get_line_at description in comment.
Remove locate_egrep.

Regards,
Andrew.

Index: find.c
===================================================================
RCS file: /home/sav/.cvsroot/mc/src/find.c,v
retrieving revision 1.37
diff -u -p -r1.37 find.c
--- find.c	27 Apr 2001 10:07:45 -0000	1.37
+++ find.c	28 Aug 2001 06:20:25 -0000
@@ -50,6 +50,12 @@
 #include "cmd.h"		/* view_file_at_line */
 #include "../vfs/vfs.h"
 
+#if defined(HAVE_RX_H) && defined(HAVE_REGCOMP)
+#    include <rx.h>
+#else
+#    include <regex.h>
+#endif
+
 #ifndef PORT_HAS_FLUSH_EVENTS
 #    define x_flush_events()
 #endif
@@ -409,10 +414,52 @@ locate_egrep (void)
 }
 #endif
 
+static char *
+get_line_at (int file_fd, char *buf, int *pos, int *n_read, int buf_size, int *line)
+{
+    char *buffer = 0;
+    int  buffer_size = 0;
+    char ch;
+    int  i = 0;
+
+    for (;;){
+	if (*pos == *n_read){
+	    if ((*n_read = mc_read (file_fd, buf, buf_size)) <= 0)
+		break;
+	    *pos = 0;
+	}
+
+	ch = buf [(*pos)++];
+	/* skip over all the possible zeros in the file */
+	if (ch == 0) {
+	    if (i == 0)
+		continue;
+	    else
+		break;
+	}
+
+	if (i >= buffer_size - 1){
+	    buffer = g_realloc (buffer, buffer_size += 80);
+	}
+
+	buffer [i++] = ch;
+	if (ch == '\n'){
+	    (*line)++;
+	    break;
+	}
+    } 
+
+    if (buffer){
+	buffer [i] = 0;
+    }
+
+    return buffer;
+}
+
 /* 
  * search_content:
  *
- * Search with egrep the global (FIXME) content_pattern string in the
+ * Search the global (FIXME) content_pattern string in the
  * DIRECTORY/FILE.  It will add the found entries to the find listbox.
  */
 static void
@@ -421,12 +468,11 @@ search_content (Dlg_head *h, char *direc
     struct stat s;
     char buffer [BUF_SMALL];
     char *fname, *p;
-    int file_fd, pipe, ignoring;
-    char c;
+    int file_fd;
     int i;
-    pid_t pid;
-    char *egrep_path = "egrep";
-    char *egrep_opts = case_sensitive ? "-n" : "-in";
+    int pos, n_read;
+    regex_t r;
+    int flags = REG_EXTENDED|REG_NOSUB;
 
     fname = concat_dir_and_file (directory, filename);
 
@@ -441,57 +487,33 @@ search_content (Dlg_head *h, char *direc
     if (file_fd == -1)
 	return;
 
-#ifndef GREP_STDIN
-    pipe = mc_doublepopen (file_fd, -1, &pid, egrep_path, egrep_path, egrep_opts, content_pattern, NULL);
-#else /* GREP_STDIN */
-    pipe = mc_doublepopen (file_fd, -1, &pid, egrep_path, egrep_path, egrep_opts, content_pattern, "-", NULL);
-#endif /* GREP STDIN */
-
-    if (pipe == -1){
-	mc_close (file_fd);
-	return;
-    }
-
     g_snprintf (buffer, sizeof (buffer), _("Grepping in %s"), name_trunc (filename, FIND2_X_USE));
 
     status_update (buffer);
     mc_refresh ();
-    p = buffer;
-    ignoring = 0;
 
     enable_interrupt_key ();
     got_interrupt ();
 
-    while ((i = read (pipe, &c, 1)) == 1){
-
-	if (c == '\n'){
-	    p = buffer;
-	    ignoring = 0;
-	}
-
-	if (ignoring)
-	    continue;
-
-	if (c == ':'){
-	    char *the_name;
+    if (!case_sensitive)
+	flags |= REG_ICASE;
 
-	    *p = 0;
-	    ignoring = 1;
-	    the_name = g_strconcat (buffer, ":", filename, NULL);
-	    find_add_match (h, directory, the_name);
-	    g_free (the_name);
-	} else {
-	    if (p - buffer < (sizeof (buffer)-1) && ISASCII (c) && isdigit (c))
-		*p++ = c;
-	    else
-		*p = 0;
+    if (regcomp (&r, content_pattern, flags) == 0){
+	i = 1;
+	pos = 0;
+	n_read = 0;
+
+	while ((p = get_line_at (file_fd, buffer, &pos, &n_read, sizeof (buffer), &i))){
+	    if (regexec (&r, p, 1, 0, 0) == 0){
+		char *the_name = g_strdup_printf ("%d:%s", i, filename);
+		find_add_match (h, directory, the_name);
+		g_free (the_name);
+	    }
+	    g_free (p);
 	}
     }
+    regfree (&r);
     disable_interrupt_key ();
-    if (i == -1)
-	message (1, _(" Find/read "), _(" Problem reading from child "));
-
-    mc_doublepclose (pipe, pid);
     mc_close (file_fd);
 }
 




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]