svn commit: trunk/busybox/findutils
vda at busybox.net
vda at busybox.net
Sun Jul 15 12:38:19 UTC 2007
Author: vda
Date: 2007-07-15 05:38:18 -0700 (Sun, 15 Jul 2007)
New Revision: 19094
Log:
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
Modified:
trunk/busybox/findutils/grep.c
Changeset:
Modified: trunk/busybox/findutils/grep.c
===================================================================
--- trunk/busybox/findutils/grep.c 2007-07-15 03:01:25 UTC (rev 19093)
+++ trunk/busybox/findutils/grep.c 2007-07-15 12:38:18 UTC (rev 19094)
@@ -91,6 +91,7 @@
static byte_t open_errors;
#if ENABLE_FEATURE_GREP_CONTEXT
+static byte_t did_print_line;
static int lines_before;
static int lines_after;
static char **before_buf;
@@ -112,11 +113,17 @@
static void print_line(const char *line, int linenum, char decoration)
{
#if ENABLE_FEATURE_GREP_CONTEXT
+ /* Happens when we go to next file, immediately hit match
+ * and try to print prev context... from prev file! Don't do it */
+ if (linenum < 1)
+ return;
/* possibly print the little '--' separator */
- if ((lines_before || lines_after) && last_line_printed &&
- last_line_printed < linenum - 1) {
+ if ((lines_before || lines_after) && did_print_line &&
+ last_line_printed != linenum - 1) {
puts("--");
}
+ /* guard against printing "--" before first line of first file */
+ did_print_line = 1;
last_line_printed = linenum;
#endif
if (print_filename)
@@ -124,7 +131,7 @@
if (PRINT_LINE_NUM)
printf("%i%c", linenum, decoration);
/* Emulate weird GNU grep behavior with -ov */
- if ((option_mask32 & (OPT_v+OPT_o)) != (OPT_v+OPT_o))
+ if ((option_mask32 & (OPT_v|OPT_o)) != (OPT_v|OPT_o))
puts(line);
}
@@ -183,19 +190,27 @@
} /* while (pattern_ptr) */
if (ret ^ invert_search) {
- if (PRINT_FILES_WITH_MATCHES || BE_QUIET)
- free(line);
-
- /* if we found a match but were told to be quiet, stop here */
- if (BE_QUIET || PRINT_FILES_WITHOUT_MATCHES)
- return -1;
-
/* keep track of matches */
nmatches++;
- /* if we're just printing filenames, we stop after the first match */
- if (PRINT_FILES_WITH_MATCHES)
- break;
+ /* quiet/print (non)matching file names only? */
+ if (option_mask32 & (OPT_q|OPT_l|OPT_L)) {
+ free(line); /* we don't need line anymore */
+ if (BE_QUIET) {
+ /* manpage says about -q:
+ * "exit immediately with zero status
+ * if any match is found,
+ * even if errors were detected" */
+ exit(0);
+ }
+ /* if we're just printing filenames, we stop after the first match */
+ if (PRINT_FILES_WITH_MATCHES) {
+ puts(cur_file);
+ /* fall thru to "return 1" */
+ }
+ /* OPT_L aka PRINT_FILES_WITHOUT_MATCHES: return early */
+ return 1; /* one match */
+ }
/* print the matched line */
if (PRINT_MATCH_COUNTS == 0) {
@@ -239,19 +254,20 @@
}
#if ENABLE_FEATURE_GREP_CONTEXT
else { /* no match */
- /* Add the line to the circular 'before' buffer */
- if (lines_before) {
+ /* if we need to print some context lines after the last match, do so */
+ if (print_n_lines_after /* && (last_line_printed != linenum) */ ) {
+ print_line(line, linenum, '-');
+ print_n_lines_after--;
+ } else if (lines_before) {
+ /* Add the line to the circular 'before' buffer */
free(before_buf[curpos]);
- before_buf[curpos] = xstrdup(line);
+ before_buf[curpos] = line;
curpos = (curpos + 1) % lines_before;
+ /* avoid free(line) - we took line */
+ continue;
}
}
- /* if we need to print some context lines after the last match, do so */
- if (print_n_lines_after && (last_line_printed != linenum)) {
- print_line(line, linenum, '-');
- print_n_lines_after--;
- }
#endif /* ENABLE_FEATURE_GREP_CONTEXT */
free(line);
}
@@ -266,16 +282,14 @@
printf("%d\n", nmatches);
}
- /* grep -l: print just the filename, but only if we grepped the line in the file */
- if (PRINT_FILES_WITH_MATCHES && nmatches > 0) {
+ /* grep -L: print just the filename */
+ if (PRINT_FILES_WITHOUT_MATCHES) {
+ /* nmatches is zero, no need to check it:
+ * we return 1 early if we detected a match
+ * and PRINT_FILES_WITHOUT_MATCHES is set */
puts(cur_file);
}
- /* grep -L: print just the filename, but only if we didn't grep the line in the file */
- if (PRINT_FILES_WITHOUT_MATCHES && nmatches == 0) {
- puts(cur_file);
- }
-
return nmatches;
}
More information about the busybox-cvs
mailing list