Eliminate egrep in Find file feature: 1st Approximation
Andrew V. Samoilov
sav at bcs.zp.ua
Tue Aug 28 11:53:25 UTC 2001
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);
}
More information about the mc-devel
mailing list