aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-09-29 20:58:53 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-09-29 20:58:53 +0000
commit51937534fb6ae25b4197ac03635bb09a405957ba (patch)
tree2d623f9e65f1429349dc38e16a23ea52722d0790
parent266bc17690cd8e98bf30514a19f95891b6ccd1d3 (diff)
downloadbusybox-w32-51937534fb6ae25b4197ac03635bb09a405957ba.tar.gz
busybox-w32-51937534fb6ae25b4197ac03635bb09a405957ba.tar.bz2
busybox-w32-51937534fb6ae25b4197ac03635bb09a405957ba.zip
grep: implement -o option. Patch by Jac Goudsmit.
-rw-r--r--findutils/grep.c56
1 files changed, 34 insertions, 22 deletions
diff --git a/findutils/grep.c b/findutils/grep.c
index ebd9596e0..f301b535d 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -14,7 +14,10 @@
14 * 2004,2006 (C) Vladimir Oleynik <dzo@simtreas.ru> - 14 * 2004,2006 (C) Vladimir Oleynik <dzo@simtreas.ru> -
15 * correction "-e pattern1 -e pattern2" logic and more optimizations. 15 * correction "-e pattern1 -e pattern2" logic and more optimizations.
16 * precompiled regex 16 * precompiled regex
17*/ 17 */
18/*
19 * (C) 2006 Jac Goudsmit added -o option
20 */
18 21
19#include "busybox.h" 22#include "busybox.h"
20#include "xregex.h" 23#include "xregex.h"
@@ -22,7 +25,7 @@
22 25
23/* options */ 26/* options */
24static unsigned long opt; 27static unsigned long opt;
25#define GREP_OPTS "lnqvscFiHhe:f:L" 28#define GREP_OPTS "lnqvscFiHhe:f:Lo"
26#define GREP_OPT_l (1<<0) 29#define GREP_OPT_l (1<<0)
27#define PRINT_FILES_WITH_MATCHES (opt & GREP_OPT_l) 30#define PRINT_FILES_WITH_MATCHES (opt & GREP_OPT_l)
28#define GREP_OPT_n (1<<1) 31#define GREP_OPT_n (1<<1)
@@ -44,19 +47,20 @@ static invert_search_t invert_search;
44#define GREP_OPT_e (1<<10) 47#define GREP_OPT_e (1<<10)
45#define GREP_OPT_f (1<<11) 48#define GREP_OPT_f (1<<11)
46#define GREP_OPT_L (1<<12) 49#define GREP_OPT_L (1<<12)
47#define PRINT_FILES_WITHOUT_MATCHES ((opt & GREP_OPT_L) != 0) 50#define PRINT_FILES_WITHOUT_MATCHES (opt & GREP_OPT_L)
51#define GREP_OPT_o (1<<13)
48#if ENABLE_FEATURE_GREP_CONTEXT 52#if ENABLE_FEATURE_GREP_CONTEXT
49#define GREP_OPT_CONTEXT "A:B:C:" 53#define GREP_OPT_CONTEXT "A:B:C:"
50#define GREP_OPT_A (1<<13) 54#define GREP_OPT_A (1<<14)
51#define GREP_OPT_B (1<<14) 55#define GREP_OPT_B (1<<15)
52#define GREP_OPT_C (1<<15) 56#define GREP_OPT_C (1<<16)
53#define GREP_OPT_E (1<<16) 57#define GREP_OPT_E (1<<17)
54#else 58#else
55#define GREP_OPT_CONTEXT "" 59#define GREP_OPT_CONTEXT ""
56#define GREP_OPT_A (0) 60#define GREP_OPT_A 0
57#define GREP_OPT_B (0) 61#define GREP_OPT_B 0
58#define GREP_OPT_C (0) 62#define GREP_OPT_C 0
59#define GREP_OPT_E (1<<13) 63#define GREP_OPT_E (1<<14)
60#endif 64#endif
61#if ENABLE_FEATURE_GREP_EGREP_ALIAS 65#if ENABLE_FEATURE_GREP_EGREP_ALIAS
62# define OPT_EGREP "E" 66# define OPT_EGREP "E"
@@ -100,7 +104,9 @@ static void print_line(const char *line, int linenum, char decoration)
100 printf("%s%c", cur_file, decoration); 104 printf("%s%c", cur_file, decoration);
101 if (PRINT_LINE_NUM) 105 if (PRINT_LINE_NUM)
102 printf("%i%c", linenum, decoration); 106 printf("%i%c", linenum, decoration);
103 puts(line); 107 /* Emulate weird GNU grep behavior with -ov */
108 if ((opt & (GREP_OPT_v+GREP_OPT_o)) != (GREP_OPT_v+GREP_OPT_o))
109 puts(line);
104} 110}
105 111
106 112
@@ -110,6 +116,7 @@ static int grep_file(FILE *file)
110 invert_search_t ret; 116 invert_search_t ret;
111 int linenum = 0; 117 int linenum = 0;
112 int nmatches = 0; 118 int nmatches = 0;
119 regmatch_t regmatch;
113#if ENABLE_FEATURE_GREP_CONTEXT 120#if ENABLE_FEATURE_GREP_CONTEXT
114 int print_n_lines_after = 0; 121 int print_n_lines_after = 0;
115 int curpos = 0; /* track where we are in the circular 'before' buffer */ 122 int curpos = 0; /* track where we are in the circular 'before' buffer */
@@ -137,12 +144,14 @@ static int grep_file(FILE *file)
137 gl->flg_mem_alocated_compiled |= COMPILED; 144 gl->flg_mem_alocated_compiled |= COMPILED;
138 xregcomp(&(gl->preg), gl->pattern, reflags); 145 xregcomp(&(gl->preg), gl->pattern, reflags);
139 } 146 }
140 ret |= regexec(&(gl->preg), line, 0, NULL, 0) == 0; 147 regmatch.rm_so = 0;
148 regmatch.rm_eo = 0;
149 ret |= regexec(&(gl->preg), line, 1, &regmatch, 0) == 0;
141 } 150 }
142 pattern_ptr = pattern_ptr->link; 151 pattern_ptr = pattern_ptr->link;
143 } /* while (pattern_ptr) */ 152 } /* while (pattern_ptr) */
144 153
145 if ((ret ^ invert_search)) { 154 if (ret ^ invert_search) {
146 155
147 if (PRINT_FILES_WITH_MATCHES || BE_QUIET) 156 if (PRINT_FILES_WITH_MATCHES || BE_QUIET)
148 free(line); 157 free(line);
@@ -190,7 +199,12 @@ static int grep_file(FILE *file)
190 /* make a note that we need to print 'after' lines */ 199 /* make a note that we need to print 'after' lines */
191 print_n_lines_after = lines_after; 200 print_n_lines_after = lines_after;
192#endif 201#endif
193 print_line(line, linenum, ':'); 202 if (opt & GREP_OPT_o) {
203 line[regmatch.rm_eo] = '\0';
204 print_line(line + regmatch.rm_so, linenum, ':');
205 } else {
206 print_line(line, linenum, ':');
207 }
194 } 208 }
195 } 209 }
196#if ENABLE_FEATURE_GREP_CONTEXT 210#if ENABLE_FEATURE_GREP_CONTEXT
@@ -212,7 +226,6 @@ static int grep_file(FILE *file)
212 free(line); 226 free(line);
213 } 227 }
214 228
215
216 /* special-case file post-processing for options where we don't print line 229 /* special-case file post-processing for options where we don't print line
217 * matches, just filenames and possibly match counts */ 230 * matches, just filenames and possibly match counts */
218 231
@@ -284,7 +297,6 @@ int grep_main(int argc, char **argv)
284 297
285 /* do normal option parsing */ 298 /* do normal option parsing */
286#if ENABLE_FEATURE_GREP_CONTEXT 299#if ENABLE_FEATURE_GREP_CONTEXT
287 {
288 char *junk; 300 char *junk;
289 char *slines_after; 301 char *slines_after;
290 char *slines_before; 302 char *slines_before;
@@ -316,13 +328,12 @@ int grep_main(int argc, char **argv)
316 bb_error_msg_and_die(bb_msg_invalid_arg, slines_before, "-B"); 328 bb_error_msg_and_die(bb_msg_invalid_arg, slines_before, "-B");
317 } 329 }
318 /* sanity checks after parse may be invalid numbers ;-) */ 330 /* sanity checks after parse may be invalid numbers ;-) */
319 if ((opt & (GREP_OPT_c|GREP_OPT_q|GREP_OPT_l|GREP_OPT_L))) { 331 if (opt & (GREP_OPT_c|GREP_OPT_q|GREP_OPT_l|GREP_OPT_L)) {
320 opt &= ~GREP_OPT_n; 332 opt &= ~GREP_OPT_n;
321 lines_before = 0; 333 lines_before = 0;
322 lines_after = 0; 334 lines_after = 0;
323 } else if(lines_before > 0) 335 } else if(lines_before > 0)
324 before_buf = (char **)xzalloc(lines_before * sizeof(char *)); 336 before_buf = (char **)xzalloc(lines_before * sizeof(char *));
325 }
326#else 337#else
327 /* with auto sanity checks */ 338 /* with auto sanity checks */
328 bb_opt_complementally = "H-h:e::f::c-n:q-n:l-n"; 339 bb_opt_complementally = "H-h:e::f::c-n:q-n:l-n";
@@ -348,11 +359,12 @@ int grep_main(int argc, char **argv)
348 if(ENABLE_FEATURE_GREP_FGREP_ALIAS && bb_applet_name[0] == 'f') 359 if(ENABLE_FEATURE_GREP_FGREP_ALIAS && bb_applet_name[0] == 'f')
349 opt |= GREP_OPT_F; 360 opt |= GREP_OPT_F;
350 361
362 if(!(opt & GREP_OPT_o))
363 reflags = REG_NOSUB;
364
351 if(ENABLE_FEATURE_GREP_EGREP_ALIAS && 365 if(ENABLE_FEATURE_GREP_EGREP_ALIAS &&
352 (bb_applet_name[0] == 'e' || (opt & GREP_OPT_E))) 366 (bb_applet_name[0] == 'e' || (opt & GREP_OPT_E)))
353 reflags = REG_EXTENDED | REG_NOSUB; 367 reflags |= REG_EXTENDED;
354 else
355 reflags = REG_NOSUB;
356 368
357 if(opt & GREP_OPT_i) 369 if(opt & GREP_OPT_i)
358 reflags |= REG_ICASE; 370 reflags |= REG_ICASE;