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