grep: implement -o option. Patch by Jac Goudsmit.
This commit is contained in:
parent
266bc17690
commit
51937534fb
@ -14,7 +14,10 @@
|
|||||||
* 2004,2006 (C) Vladimir Oleynik <dzo@simtreas.ru> -
|
* 2004,2006 (C) Vladimir Oleynik <dzo@simtreas.ru> -
|
||||||
* correction "-e pattern1 -e pattern2" logic and more optimizations.
|
* correction "-e pattern1 -e pattern2" logic and more optimizations.
|
||||||
* precompiled regex
|
* precompiled regex
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* (C) 2006 Jac Goudsmit added -o option
|
||||||
|
*/
|
||||||
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
#include "xregex.h"
|
#include "xregex.h"
|
||||||
@ -22,7 +25,7 @@
|
|||||||
|
|
||||||
/* options */
|
/* options */
|
||||||
static unsigned long opt;
|
static unsigned long opt;
|
||||||
#define GREP_OPTS "lnqvscFiHhe:f:L"
|
#define GREP_OPTS "lnqvscFiHhe:f:Lo"
|
||||||
#define GREP_OPT_l (1<<0)
|
#define GREP_OPT_l (1<<0)
|
||||||
#define PRINT_FILES_WITH_MATCHES (opt & GREP_OPT_l)
|
#define PRINT_FILES_WITH_MATCHES (opt & GREP_OPT_l)
|
||||||
#define GREP_OPT_n (1<<1)
|
#define GREP_OPT_n (1<<1)
|
||||||
@ -44,19 +47,20 @@ static invert_search_t invert_search;
|
|||||||
#define GREP_OPT_e (1<<10)
|
#define GREP_OPT_e (1<<10)
|
||||||
#define GREP_OPT_f (1<<11)
|
#define GREP_OPT_f (1<<11)
|
||||||
#define GREP_OPT_L (1<<12)
|
#define GREP_OPT_L (1<<12)
|
||||||
#define PRINT_FILES_WITHOUT_MATCHES ((opt & GREP_OPT_L) != 0)
|
#define PRINT_FILES_WITHOUT_MATCHES (opt & GREP_OPT_L)
|
||||||
|
#define GREP_OPT_o (1<<13)
|
||||||
#if ENABLE_FEATURE_GREP_CONTEXT
|
#if ENABLE_FEATURE_GREP_CONTEXT
|
||||||
#define GREP_OPT_CONTEXT "A:B:C:"
|
#define GREP_OPT_CONTEXT "A:B:C:"
|
||||||
#define GREP_OPT_A (1<<13)
|
#define GREP_OPT_A (1<<14)
|
||||||
#define GREP_OPT_B (1<<14)
|
#define GREP_OPT_B (1<<15)
|
||||||
#define GREP_OPT_C (1<<15)
|
#define GREP_OPT_C (1<<16)
|
||||||
#define GREP_OPT_E (1<<16)
|
#define GREP_OPT_E (1<<17)
|
||||||
#else
|
#else
|
||||||
#define GREP_OPT_CONTEXT ""
|
#define GREP_OPT_CONTEXT ""
|
||||||
#define GREP_OPT_A (0)
|
#define GREP_OPT_A 0
|
||||||
#define GREP_OPT_B (0)
|
#define GREP_OPT_B 0
|
||||||
#define GREP_OPT_C (0)
|
#define GREP_OPT_C 0
|
||||||
#define GREP_OPT_E (1<<13)
|
#define GREP_OPT_E (1<<14)
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_FEATURE_GREP_EGREP_ALIAS
|
#if ENABLE_FEATURE_GREP_EGREP_ALIAS
|
||||||
# define OPT_EGREP "E"
|
# define OPT_EGREP "E"
|
||||||
@ -100,7 +104,9 @@ static void print_line(const char *line, int linenum, char decoration)
|
|||||||
printf("%s%c", cur_file, decoration);
|
printf("%s%c", cur_file, decoration);
|
||||||
if (PRINT_LINE_NUM)
|
if (PRINT_LINE_NUM)
|
||||||
printf("%i%c", linenum, decoration);
|
printf("%i%c", linenum, decoration);
|
||||||
puts(line);
|
/* Emulate weird GNU grep behavior with -ov */
|
||||||
|
if ((opt & (GREP_OPT_v+GREP_OPT_o)) != (GREP_OPT_v+GREP_OPT_o))
|
||||||
|
puts(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -110,6 +116,7 @@ static int grep_file(FILE *file)
|
|||||||
invert_search_t ret;
|
invert_search_t ret;
|
||||||
int linenum = 0;
|
int linenum = 0;
|
||||||
int nmatches = 0;
|
int nmatches = 0;
|
||||||
|
regmatch_t regmatch;
|
||||||
#if ENABLE_FEATURE_GREP_CONTEXT
|
#if ENABLE_FEATURE_GREP_CONTEXT
|
||||||
int print_n_lines_after = 0;
|
int print_n_lines_after = 0;
|
||||||
int curpos = 0; /* track where we are in the circular 'before' buffer */
|
int curpos = 0; /* track where we are in the circular 'before' buffer */
|
||||||
@ -137,12 +144,14 @@ static int grep_file(FILE *file)
|
|||||||
gl->flg_mem_alocated_compiled |= COMPILED;
|
gl->flg_mem_alocated_compiled |= COMPILED;
|
||||||
xregcomp(&(gl->preg), gl->pattern, reflags);
|
xregcomp(&(gl->preg), gl->pattern, reflags);
|
||||||
}
|
}
|
||||||
ret |= regexec(&(gl->preg), line, 0, NULL, 0) == 0;
|
regmatch.rm_so = 0;
|
||||||
|
regmatch.rm_eo = 0;
|
||||||
|
ret |= regexec(&(gl->preg), line, 1, ®match, 0) == 0;
|
||||||
}
|
}
|
||||||
pattern_ptr = pattern_ptr->link;
|
pattern_ptr = pattern_ptr->link;
|
||||||
} /* while (pattern_ptr) */
|
} /* while (pattern_ptr) */
|
||||||
|
|
||||||
if ((ret ^ invert_search)) {
|
if (ret ^ invert_search) {
|
||||||
|
|
||||||
if (PRINT_FILES_WITH_MATCHES || BE_QUIET)
|
if (PRINT_FILES_WITH_MATCHES || BE_QUIET)
|
||||||
free(line);
|
free(line);
|
||||||
@ -190,7 +199,12 @@ static int grep_file(FILE *file)
|
|||||||
/* make a note that we need to print 'after' lines */
|
/* make a note that we need to print 'after' lines */
|
||||||
print_n_lines_after = lines_after;
|
print_n_lines_after = lines_after;
|
||||||
#endif
|
#endif
|
||||||
print_line(line, linenum, ':');
|
if (opt & GREP_OPT_o) {
|
||||||
|
line[regmatch.rm_eo] = '\0';
|
||||||
|
print_line(line + regmatch.rm_so, linenum, ':');
|
||||||
|
} else {
|
||||||
|
print_line(line, linenum, ':');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if ENABLE_FEATURE_GREP_CONTEXT
|
#if ENABLE_FEATURE_GREP_CONTEXT
|
||||||
@ -212,7 +226,6 @@ static int grep_file(FILE *file)
|
|||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* special-case file post-processing for options where we don't print line
|
/* special-case file post-processing for options where we don't print line
|
||||||
* matches, just filenames and possibly match counts */
|
* matches, just filenames and possibly match counts */
|
||||||
|
|
||||||
@ -284,7 +297,6 @@ int grep_main(int argc, char **argv)
|
|||||||
|
|
||||||
/* do normal option parsing */
|
/* do normal option parsing */
|
||||||
#if ENABLE_FEATURE_GREP_CONTEXT
|
#if ENABLE_FEATURE_GREP_CONTEXT
|
||||||
{
|
|
||||||
char *junk;
|
char *junk;
|
||||||
char *slines_after;
|
char *slines_after;
|
||||||
char *slines_before;
|
char *slines_before;
|
||||||
@ -316,13 +328,12 @@ int grep_main(int argc, char **argv)
|
|||||||
bb_error_msg_and_die(bb_msg_invalid_arg, slines_before, "-B");
|
bb_error_msg_and_die(bb_msg_invalid_arg, slines_before, "-B");
|
||||||
}
|
}
|
||||||
/* sanity checks after parse may be invalid numbers ;-) */
|
/* sanity checks after parse may be invalid numbers ;-) */
|
||||||
if ((opt & (GREP_OPT_c|GREP_OPT_q|GREP_OPT_l|GREP_OPT_L))) {
|
if (opt & (GREP_OPT_c|GREP_OPT_q|GREP_OPT_l|GREP_OPT_L)) {
|
||||||
opt &= ~GREP_OPT_n;
|
opt &= ~GREP_OPT_n;
|
||||||
lines_before = 0;
|
lines_before = 0;
|
||||||
lines_after = 0;
|
lines_after = 0;
|
||||||
} else if(lines_before > 0)
|
} else if(lines_before > 0)
|
||||||
before_buf = (char **)xzalloc(lines_before * sizeof(char *));
|
before_buf = (char **)xzalloc(lines_before * sizeof(char *));
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
/* with auto sanity checks */
|
/* with auto sanity checks */
|
||||||
bb_opt_complementally = "H-h:e::f::c-n:q-n:l-n";
|
bb_opt_complementally = "H-h:e::f::c-n:q-n:l-n";
|
||||||
@ -348,11 +359,12 @@ int grep_main(int argc, char **argv)
|
|||||||
if(ENABLE_FEATURE_GREP_FGREP_ALIAS && bb_applet_name[0] == 'f')
|
if(ENABLE_FEATURE_GREP_FGREP_ALIAS && bb_applet_name[0] == 'f')
|
||||||
opt |= GREP_OPT_F;
|
opt |= GREP_OPT_F;
|
||||||
|
|
||||||
|
if(!(opt & GREP_OPT_o))
|
||||||
|
reflags = REG_NOSUB;
|
||||||
|
|
||||||
if(ENABLE_FEATURE_GREP_EGREP_ALIAS &&
|
if(ENABLE_FEATURE_GREP_EGREP_ALIAS &&
|
||||||
(bb_applet_name[0] == 'e' || (opt & GREP_OPT_E)))
|
(bb_applet_name[0] == 'e' || (opt & GREP_OPT_E)))
|
||||||
reflags = REG_EXTENDED | REG_NOSUB;
|
reflags |= REG_EXTENDED;
|
||||||
else
|
|
||||||
reflags = REG_NOSUB;
|
|
||||||
|
|
||||||
if(opt & GREP_OPT_i)
|
if(opt & GREP_OPT_i)
|
||||||
reflags |= REG_ICASE;
|
reflags |= REG_ICASE;
|
||||||
|
Loading…
Reference in New Issue
Block a user