aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-07-15 12:38:18 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-07-15 12:38:18 +0000
commit8d5aa870a66b2196d2b756813cebb25c22b128ed (patch)
treef498c7f94aaa10d6903e220011759bd484d3b66b
parentbdc406d15d5efa45970ebaf404f0d2a411abff91 (diff)
downloadbusybox-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.c70
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;
91static byte_t open_errors; 91static byte_t open_errors;
92 92
93#if ENABLE_FEATURE_GREP_CONTEXT 93#if ENABLE_FEATURE_GREP_CONTEXT
94static byte_t did_print_line;
94static int lines_before; 95static int lines_before;
95static int lines_after; 96static int lines_after;
96static char **before_buf; 97static char **before_buf;
@@ -112,11 +113,17 @@ typedef struct grep_list_data_t {
112static void print_line(const char *line, int linenum, char decoration) 113static 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