Eliminate egrep in Find file feature: 1st Approximation
- From: "Andrew V. Samoilov" <sav bcs zp ua>
- To: proski gnu org, mc-devel gnome org
- Subject: Eliminate egrep in Find file feature: 1st Approximation
- Date: Tue, 28 Aug 2001 14:53:25 +0300
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]