diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-15 12:38:18 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-15 12:38:18 +0000 |
commit | 8d5aa870a66b2196d2b756813cebb25c22b128ed (patch) | |
tree | f498c7f94aaa10d6903e220011759bd484d3b66b | |
parent | bdc406d15d5efa45970ebaf404f0d2a411abff91 (diff) | |
download | busybox-w32-8d5aa870a66b2196d2b756813cebb25c22b128ed.tar.gz busybox-w32-8d5aa870a66b2196d2b756813cebb25c22b128ed.tar.bz2 busybox-w32-8d5aa870a66b2196d2b756813cebb25c22b128ed.zip |
grep: fix buglets with context printing
print_line 152 170 +18
did_print_line - 1 +1
grep_file 788 771 -17
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 19/-17) Total: 2 bytes
text data bss dec hex filename
673368 2740 13968 690076 a879c busybox_old
673368 2740 13968 690076 a879c busybox_unstripped
-rw-r--r-- | findutils/grep.c | 70 |
1 files changed, 42 insertions, 28 deletions
diff --git a/findutils/grep.c b/findutils/grep.c index 75425b4df..7bade87cb 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -91,6 +91,7 @@ static byte_t print_filename; | |||
91 | static byte_t open_errors; | 91 | static byte_t open_errors; |
92 | 92 | ||
93 | #if ENABLE_FEATURE_GREP_CONTEXT | 93 | #if ENABLE_FEATURE_GREP_CONTEXT |
94 | static byte_t did_print_line; | ||
94 | static int lines_before; | 95 | static int lines_before; |
95 | static int lines_after; | 96 | static int lines_after; |
96 | static char **before_buf; | 97 | static char **before_buf; |
@@ -112,11 +113,17 @@ typedef struct grep_list_data_t { | |||
112 | static void print_line(const char *line, int linenum, char decoration) | 113 | static void print_line(const char *line, int linenum, char decoration) |
113 | { | 114 | { |
114 | #if ENABLE_FEATURE_GREP_CONTEXT | 115 | #if ENABLE_FEATURE_GREP_CONTEXT |
116 | /* Happens when we go to next file, immediately hit match | ||
117 | * and try to print prev context... from prev file! Don't do it */ | ||
118 | if (linenum < 1) | ||
119 | return; | ||
115 | /* possibly print the little '--' separator */ | 120 | /* possibly print the little '--' separator */ |
116 | if ((lines_before || lines_after) && last_line_printed && | 121 | if ((lines_before || lines_after) && did_print_line && |
117 | last_line_printed < linenum - 1) { | 122 | last_line_printed != linenum - 1) { |
118 | puts("--"); | 123 | puts("--"); |
119 | } | 124 | } |
125 | /* guard against printing "--" before first line of first file */ | ||
126 | did_print_line = 1; | ||
120 | last_line_printed = linenum; | 127 | last_line_printed = linenum; |
121 | #endif | 128 | #endif |
122 | if (print_filename) | 129 | if (print_filename) |
@@ -124,7 +131,7 @@ static void print_line(const char *line, int linenum, char decoration) | |||
124 | if (PRINT_LINE_NUM) | 131 | if (PRINT_LINE_NUM) |
125 | printf("%i%c", linenum, decoration); | 132 | printf("%i%c", linenum, decoration); |
126 | /* Emulate weird GNU grep behavior with -ov */ | 133 | /* Emulate weird GNU grep behavior with -ov */ |
127 | if ((option_mask32 & (OPT_v+OPT_o)) != (OPT_v+OPT_o)) | 134 | if ((option_mask32 & (OPT_v|OPT_o)) != (OPT_v|OPT_o)) |
128 | puts(line); | 135 | puts(line); |
129 | } | 136 | } |
130 | 137 | ||
@@ -183,19 +190,27 @@ static int grep_file(FILE *file) | |||
183 | } /* while (pattern_ptr) */ | 190 | } /* while (pattern_ptr) */ |
184 | 191 | ||
185 | if (ret ^ invert_search) { | 192 | if (ret ^ invert_search) { |
186 | if (PRINT_FILES_WITH_MATCHES || BE_QUIET) | ||
187 | free(line); | ||
188 | |||
189 | /* if we found a match but were told to be quiet, stop here */ | ||
190 | if (BE_QUIET || PRINT_FILES_WITHOUT_MATCHES) | ||
191 | return -1; | ||
192 | |||
193 | /* keep track of matches */ | 193 | /* keep track of matches */ |
194 | nmatches++; | 194 | nmatches++; |
195 | 195 | ||
196 | /* if we're just printing filenames, we stop after the first match */ | 196 | /* quiet/print (non)matching file names only? */ |
197 | if (PRINT_FILES_WITH_MATCHES) | 197 | if (option_mask32 & (OPT_q|OPT_l|OPT_L)) { |
198 | break; | 198 | free(line); /* we don't need line anymore */ |
199 | if (BE_QUIET) { | ||
200 | /* manpage says about -q: | ||
201 | * "exit immediately with zero status | ||
202 | * if any match is found, | ||
203 | * even if errors were detected" */ | ||
204 | exit(0); | ||
205 | } | ||
206 | /* if we're just printing filenames, we stop after the first match */ | ||
207 | if (PRINT_FILES_WITH_MATCHES) { | ||
208 | puts(cur_file); | ||
209 | /* fall thru to "return 1" */ | ||
210 | } | ||
211 | /* OPT_L aka PRINT_FILES_WITHOUT_MATCHES: return early */ | ||
212 | return 1; /* one match */ | ||
213 | } | ||
199 | 214 | ||
200 | /* print the matched line */ | 215 | /* print the matched line */ |
201 | if (PRINT_MATCH_COUNTS == 0) { | 216 | if (PRINT_MATCH_COUNTS == 0) { |
@@ -239,19 +254,20 @@ static int grep_file(FILE *file) | |||
239 | } | 254 | } |
240 | #if ENABLE_FEATURE_GREP_CONTEXT | 255 | #if ENABLE_FEATURE_GREP_CONTEXT |
241 | else { /* no match */ | 256 | else { /* no match */ |
242 | /* Add the line to the circular 'before' buffer */ | 257 | /* if we need to print some context lines after the last match, do so */ |
243 | if (lines_before) { | 258 | if (print_n_lines_after /* && (last_line_printed != linenum) */ ) { |
259 | print_line(line, linenum, '-'); | ||
260 | print_n_lines_after--; | ||
261 | } else if (lines_before) { | ||
262 | /* Add the line to the circular 'before' buffer */ | ||
244 | free(before_buf[curpos]); | 263 | free(before_buf[curpos]); |
245 | before_buf[curpos] = xstrdup(line); | 264 | before_buf[curpos] = line; |
246 | curpos = (curpos + 1) % lines_before; | 265 | curpos = (curpos + 1) % lines_before; |
266 | /* avoid free(line) - we took line */ | ||
267 | continue; | ||
247 | } | 268 | } |
248 | } | 269 | } |
249 | 270 | ||
250 | /* if we need to print some context lines after the last match, do so */ | ||
251 | if (print_n_lines_after && (last_line_printed != linenum)) { | ||
252 | print_line(line, linenum, '-'); | ||
253 | print_n_lines_after--; | ||
254 | } | ||
255 | #endif /* ENABLE_FEATURE_GREP_CONTEXT */ | 271 | #endif /* ENABLE_FEATURE_GREP_CONTEXT */ |
256 | free(line); | 272 | free(line); |
257 | } | 273 | } |
@@ -266,13 +282,11 @@ static int grep_file(FILE *file) | |||
266 | printf("%d\n", nmatches); | 282 | printf("%d\n", nmatches); |
267 | } | 283 | } |
268 | 284 | ||
269 | /* grep -l: print just the filename, but only if we grepped the line in the file */ | 285 | /* grep -L: print just the filename */ |
270 | if (PRINT_FILES_WITH_MATCHES && nmatches > 0) { | 286 | if (PRINT_FILES_WITHOUT_MATCHES) { |
271 | puts(cur_file); | 287 | /* nmatches is zero, no need to check it: |
272 | } | 288 | * we return 1 early if we detected a match |
273 | 289 | * and PRINT_FILES_WITHOUT_MATCHES is set */ | |
274 | /* grep -L: print just the filename, but only if we didn't grep the line in the file */ | ||
275 | if (PRINT_FILES_WITHOUT_MATCHES && nmatches == 0) { | ||
276 | puts(cur_file); | 290 | puts(cur_file); |
277 | } | 291 | } |
278 | 292 | ||