svn commit: trunk/busybox: findutils include libbb

vda at busybox.net vda at busybox.net
Sat Oct 14 07:24:31 PDT 2006


Author: vda
Date: 2006-10-14 07:24:30 -0700 (Sat, 14 Oct 2006)
New Revision: 16381

Log:
grep: add support for -r


Modified:
   trunk/busybox/findutils/find.c
   trunk/busybox/findutils/grep.c
   trunk/busybox/include/libbb.h
   trunk/busybox/include/usage.h
   trunk/busybox/libbb/recursive_action.c


Changeset:
Modified: trunk/busybox/findutils/find.c
===================================================================
--- trunk/busybox/findutils/find.c	2006-10-14 11:47:02 UTC (rev 16380)
+++ trunk/busybox/findutils/find.c	2006-10-14 14:24:30 UTC (rev 16381)
@@ -74,7 +74,7 @@
 			tmp = fileName;
 		else
 			tmp++;
-		if (!(fnmatch(pattern, tmp, FNM_PERIOD) == 0))
+		if (fnmatch(pattern, tmp, FNM_PERIOD) != 0)
 			goto no_match;
 	}
 #ifdef CONFIG_FEATURE_FIND_TYPE
@@ -143,8 +143,8 @@
 #else
 	puts(fileName);
 #endif
-no_match:
-	return (TRUE);
+ no_match:
+	return TRUE;
 }
 
 #ifdef CONFIG_FEATURE_FIND_TYPE
@@ -153,27 +153,27 @@
 	int mask = 0;
 
 	switch (type[0]) {
-		case 'b':
-			mask = S_IFBLK;
-			break;
-		case 'c':
-			mask = S_IFCHR;
-			break;
-		case 'd':
-			mask = S_IFDIR;
-			break;
-		case 'p':
-			mask = S_IFIFO;
-			break;
-		case 'f':
-			mask = S_IFREG;
-			break;
-		case 'l':
-			mask = S_IFLNK;
-			break;
-		case 's':
-			mask = S_IFSOCK;
-			break;
+	case 'b':
+		mask = S_IFBLK;
+		break;
+	case 'c':
+		mask = S_IFCHR;
+		break;
+	case 'd':
+		mask = S_IFDIR;
+		break;
+	case 'p':
+		mask = S_IFIFO;
+		break;
+	case 'f':
+		mask = S_IFREG;
+		break;
+	case 'l':
+		mask = S_IFLNK;
+		break;
+	case 's':
+		mask = S_IFSOCK;
+		break;
 	}
 
 	if (mask == 0 || type[1] != '\0')
@@ -306,12 +306,12 @@
 	}
 
 	if (firstopt == 1) {
-		if (! recursive_action(".", TRUE, dereference, FALSE, fileAction,
+		if (!recursive_action(".", TRUE, dereference, FALSE, fileAction,
 					fileAction, NULL))
 			status = EXIT_FAILURE;
 	} else {
 		for (i = 1; i < firstopt; i++) {
-			if (! recursive_action(argv[i], TRUE, dereference, FALSE, fileAction,
+			if (!recursive_action(argv[i], TRUE, dereference, FALSE, fileAction,
 						fileAction, NULL))
 				status = EXIT_FAILURE;
 		}

Modified: trunk/busybox/findutils/grep.c
===================================================================
--- trunk/busybox/findutils/grep.c	2006-10-14 11:47:02 UTC (rev 16380)
+++ trunk/busybox/findutils/grep.c	2006-10-14 14:24:30 UTC (rev 16381)
@@ -24,43 +24,41 @@
 
 
 /* options */
-static unsigned opt;
-#define GREP_OPTS "lnqvscFiHhe:f:Lo"
+#define GREP_OPTS "lnqvscFiHhe:f:Lor"
 #define GREP_OPT_l (1<<0)
-#define PRINT_FILES_WITH_MATCHES (opt & GREP_OPT_l)
+#define PRINT_FILES_WITH_MATCHES (option_mask32 & GREP_OPT_l)
 #define GREP_OPT_n (1<<1)
-#define PRINT_LINE_NUM (opt & GREP_OPT_n)
+#define PRINT_LINE_NUM (option_mask32 & GREP_OPT_n)
 #define GREP_OPT_q (1<<2)
-#define BE_QUIET (opt & GREP_OPT_q)
+#define BE_QUIET (option_mask32 & GREP_OPT_q)
 #define GREP_OPT_v (1<<3)
-typedef char invert_search_t;
-static invert_search_t invert_search;
 #define GREP_OPT_s (1<<4)
-#define SUPPRESS_ERR_MSGS (opt & GREP_OPT_s)
+#define SUPPRESS_ERR_MSGS (option_mask32 & GREP_OPT_s)
 #define GREP_OPT_c (1<<5)
-#define PRINT_MATCH_COUNTS (opt & GREP_OPT_c)
+#define PRINT_MATCH_COUNTS (option_mask32 & GREP_OPT_c)
 #define GREP_OPT_F (1<<6)
-#define FGREP_FLAG (opt & GREP_OPT_F)
+#define FGREP_FLAG (option_mask32 & GREP_OPT_F)
 #define GREP_OPT_i (1<<7)
 #define GREP_OPT_H (1<<8)
 #define GREP_OPT_h (1<<9)
 #define GREP_OPT_e (1<<10)
 #define GREP_OPT_f (1<<11)
 #define GREP_OPT_L (1<<12)
-#define PRINT_FILES_WITHOUT_MATCHES (opt & GREP_OPT_L)
+#define PRINT_FILES_WITHOUT_MATCHES (option_mask32 & GREP_OPT_L)
 #define GREP_OPT_o (1<<13)
+#define GREP_OPT_r (1<<14)
 #if ENABLE_FEATURE_GREP_CONTEXT
-#define GREP_OPT_CONTEXT "A:B:C:"
-#define GREP_OPT_A (1<<14)
-#define GREP_OPT_B (1<<15)
-#define GREP_OPT_C (1<<16)
-#define GREP_OPT_E (1<<17)
+# define GREP_OPT_CONTEXT "A:B:C:"
+# define GREP_OPT_A (1<<15)
+# define GREP_OPT_B (1<<16)
+# define GREP_OPT_C (1<<17)
+# define GREP_OPT_E (1<<18)
 #else
-#define GREP_OPT_CONTEXT ""
-#define GREP_OPT_A 0
-#define GREP_OPT_B 0
-#define GREP_OPT_C 0
-#define GREP_OPT_E (1<<14)
+# define GREP_OPT_CONTEXT ""
+# define GREP_OPT_A 0
+# define GREP_OPT_B 0
+# define GREP_OPT_C 0
+# define GREP_OPT_E (1<<15)
 #endif
 #if ENABLE_FEATURE_GREP_EGREP_ALIAS
 # define OPT_EGREP "E"
@@ -68,8 +66,12 @@
 # define OPT_EGREP ""
 #endif
 
+typedef unsigned char byte_t;
+
 static int reflags;
-static int print_filename;
+static byte_t invert_search;
+static byte_t print_filename;
+static byte_t open_errors;
 
 #if ENABLE_FEATURE_GREP_CONTEXT
 static int lines_before;
@@ -80,7 +82,7 @@
 
 /* globals used internally */
 static llist_t *pattern_head;   /* growable list of patterns to match */
-static char *cur_file;          /* the current file we are reading */
+static const char *cur_file;    /* the current file we are reading */
 
 typedef struct GREP_LIST_DATA {
 	char *pattern;
@@ -100,12 +102,12 @@
 	}
 	last_line_printed = linenum;
 #endif
-	if (print_filename > 0)
+	if (print_filename)
 		printf("%s%c", cur_file, decoration);
 	if (PRINT_LINE_NUM)
 		printf("%i%c", linenum, decoration);
 	/* Emulate weird GNU grep behavior with -ov */
-	if ((opt & (GREP_OPT_v+GREP_OPT_o)) != (GREP_OPT_v+GREP_OPT_o))
+	if ((option_mask32 & (GREP_OPT_v+GREP_OPT_o)) != (GREP_OPT_v+GREP_OPT_o))
 		puts(line);
 }
 
@@ -113,7 +115,7 @@
 static int grep_file(FILE *file)
 {
 	char *line;
-	invert_search_t ret;
+	byte_t ret;
 	int linenum = 0;
 	int nmatches = 0;
 	regmatch_t regmatch;
@@ -199,7 +201,7 @@
 					/* make a note that we need to print 'after' lines */
 					print_n_lines_after = lines_after;
 #endif
-					if (opt & GREP_OPT_o) {
+					if (option_mask32 & GREP_OPT_o) {
 						line[regmatch.rm_eo] = '\0';
 						print_line(line + regmatch.rm_so, linenum, ':');
 					} else {
@@ -231,7 +233,7 @@
 
 	/* grep -c: print [filename:]count, even if count is zero */
 	if (PRINT_MATCH_COUNTS) {
-		if (print_filename > 0)
+		if (print_filename)
 			printf("%s:", cur_file);
 		printf("%d\n", nmatches);
 	}
@@ -288,48 +290,71 @@
 }
 
 
+static int file_action_grep(const char *filename, struct stat *statbuf, void* matched)
+{
+	FILE *file = fopen(filename, "r");
+	if (file == NULL) {
+		if (!SUPPRESS_ERR_MSGS)
+			bb_perror_msg("%s", cur_file);
+		open_errors = 1;
+		return 0;
+	}
+	cur_file = filename;
+	*(int*)matched += grep_file(file);
+	return 1;
+}
+
+
+static int grep_dir(const char *dir)
+{
+	int matched = 0;
+	recursive_action(dir,
+		/* recurse= */ 1,
+		/* followLinks= */ 0,
+		/* depthFirst= */ 1,
+		/* fileAction= */ file_action_grep,
+		/* dirAction= */ NULL,
+		/* userData= */ &matched);
+	return matched;
+}
+
+
 int grep_main(int argc, char **argv)
 {
 	FILE *file;
 	int matched;
 	llist_t *fopt = NULL;
-	int error_open_count = 0;
 
 	/* do normal option parsing */
 #if ENABLE_FEATURE_GREP_CONTEXT
-	char *junk;
 	char *slines_after;
 	char *slines_before;
 	char *Copt;
 
 	opt_complementary = "H-h:e::f::C-AB";
-	opt = getopt32(argc, argv,
+	getopt32(argc, argv,
 		GREP_OPTS GREP_OPT_CONTEXT OPT_EGREP,
 		&pattern_head, &fopt,
 		&slines_after, &slines_before, &Copt);
 
-	if (opt & GREP_OPT_C) {
+	if (option_mask32 & GREP_OPT_C) {
 		/* C option unseted A and B options, but next -A or -B
 		   may be ovewrite own option */
-		if (!(opt & GREP_OPT_A))         /* not overwtited */
+		if (!(option_mask32 & GREP_OPT_A))         /* not overwtited */
 			slines_after = Copt;
-		if (!(opt & GREP_OPT_B))         /* not overwtited */
+		if (!(option_mask32 & GREP_OPT_B))         /* not overwtited */
 			slines_before = Copt;
-		opt |= GREP_OPT_A|GREP_OPT_B;   /* set for parse now */
+		option_mask32 |= GREP_OPT_A|GREP_OPT_B;   /* set for parse now */
 	}
-	if (opt & GREP_OPT_A) {
-		lines_after = strtoul(slines_after, &junk, 10);
-		if (*junk != '\0')
-			bb_error_msg_and_die(bb_msg_invalid_arg, slines_after, "-A");
+	if (option_mask32 & GREP_OPT_A) {
+		lines_after = xatoi_u(slines_after);
 	}
-	if (opt & GREP_OPT_B) {
-		lines_before = strtoul(slines_before, &junk, 10);
-		if (*junk != '\0')
-			bb_error_msg_and_die(bb_msg_invalid_arg, slines_before, "-B");
+	if (option_mask32 & GREP_OPT_B) {
+		lines_before = xatoi_u(slines_before);
 	}
 	/* sanity checks after parse may be invalid numbers ;-) */
-	if (opt & (GREP_OPT_c|GREP_OPT_q|GREP_OPT_l|GREP_OPT_L)) {
-		opt &= ~GREP_OPT_n;
+	if (option_mask32 & (GREP_OPT_c|GREP_OPT_q|GREP_OPT_l|GREP_OPT_L)) {
+		option_mask32 &= ~GREP_OPT_n;
 		lines_before = 0;
 		lines_after = 0;
 	} else if (lines_before > 0)
@@ -337,15 +362,15 @@
 #else
 	/* with auto sanity checks */
 	opt_complementary = "H-h:e::f::c-n:q-n:l-n";
-	opt = getopt32(argc, argv, GREP_OPTS OPT_EGREP,
+	getopt32(argc, argv, GREP_OPTS OPT_EGREP,
 		&pattern_head, &fopt);
 #endif
-	invert_search = (opt & GREP_OPT_v) != 0;        /* 0 | 1 */
+	invert_search = (option_mask32 & GREP_OPT_v) != 0;        /* 0 | 1 */
 
-	if (opt & GREP_OPT_H)
-		print_filename++;
-	if (opt & GREP_OPT_h)
-		print_filename--;
+	if (option_mask32 & GREP_OPT_H)
+		print_filename = 1;
+	if (option_mask32 & GREP_OPT_h)
+		print_filename = 0;
 	if (pattern_head != NULL) {
 		/* convert char *argv[] to grep_list_data_t */
 		llist_t *cur;
@@ -353,20 +378,20 @@
 		for (cur = pattern_head; cur; cur = cur->link)
 			cur->data = new_grep_list_data(cur->data, 0);
 	}
-	if (opt & GREP_OPT_f)
+	if (option_mask32 & GREP_OPT_f)
 		load_regexes_from_file(fopt);
 
 	if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f')
-		opt |= GREP_OPT_F;
+		option_mask32 |= GREP_OPT_F;
 
-	if (!(opt & GREP_OPT_o))
+	if (!(option_mask32 & GREP_OPT_o))
 		reflags = REG_NOSUB;
 
 	if (ENABLE_FEATURE_GREP_EGREP_ALIAS &&
-			(applet_name[0] == 'e' || (opt & GREP_OPT_E)))
+			(applet_name[0] == 'e' || (option_mask32 & GREP_OPT_E)))
 		reflags |= REG_EXTENDED;
 
-	if (opt & GREP_OPT_i)
+	if (option_mask32 & GREP_OPT_i)
 		reflags |= REG_ICASE;
 
 	argv += optind;
@@ -386,9 +411,9 @@
 	}
 
 	/* argv[(optind)..(argc-1)] should be names of file to grep through. If
-	 * there is more than one file to grep, we will print the filenames */
+	 * there is more than one file to grep, we will print the filenames. */
 	if (argc > 1) {
-		print_filename++;
+		print_filename = 1;
 
 	/* If no files were specified, or '-' was specified, take input from
 	 * stdin. Otherwise, we grep through all the files specified. */
@@ -398,25 +423,35 @@
 	matched = 0;
 	while (argc--) {
 		cur_file = *argv++;
+		file = stdin;
 		if (!cur_file || (*cur_file == '-' && !cur_file[1])) {
 			cur_file = "(standard input)";
-			file = stdin;
 		} else {
+			if (option_mask32 & GREP_OPT_r) {
+				struct stat st;
+				if (stat(cur_file, &st) == 0 && S_ISDIR(st.st_mode)) {
+					print_filename = 1;
+					matched += grep_dir(cur_file);
+					goto grep_done;
+				}
+			}
+			/* else: fopen(dir) will succeed, but reading won't */
 			file = fopen(cur_file, "r");
-		}
-		if (file == NULL) {
-			if (!SUPPRESS_ERR_MSGS)
-				bb_perror_msg("%s", cur_file);
-			error_open_count++;
-		} else {
-			matched += grep_file(file);
-			if (matched < 0) {
-				/* we found a match but were told to be quiet, stop here and
-				* return success */
-				break;
+			if (file == NULL) {
+				if (!SUPPRESS_ERR_MSGS)
+					bb_perror_msg("%s", cur_file);
+				open_errors = 1;
+				continue;
 			}
-			fclose(file);
 		}
+		matched += grep_file(file);
+ grep_done:
+		if (matched < 0) {
+			/* we found a match but were told to be quiet, stop here and
+			* return success */
+			break;
+		}
+		bb_fclose_nonstdin(file);
 	}
 
 	/* destroy all the elments in the pattern list */
@@ -439,7 +474,7 @@
 	 * if an input line is selected, even if an error was detected.  */
 	if (BE_QUIET && matched)
 		return 0;
-	if (error_open_count)
+	if (open_errors)
 		return 2;
 	return !matched; /* invert return value 0 = success, 1 = failed */
 }

Modified: trunk/busybox/include/libbb.h
===================================================================
--- trunk/busybox/include/libbb.h	2006-10-14 11:47:02 UTC (rev 16380)
+++ trunk/busybox/include/libbb.h	2006-10-14 14:24:30 UTC (rev 16381)
@@ -252,8 +252,8 @@
 extern FILE *bb_wfopen_input(const char *filename);
 extern FILE *xfopen(const char *path, const char *mode);
 
-extern int   bb_fclose_nonstdin(FILE *f);
-extern void  bb_fflush_stdout_and_exit(int retval) ATTRIBUTE_NORETURN;
+extern int bb_fclose_nonstdin(FILE *f);
+extern void bb_fflush_stdout_and_exit(int retval) ATTRIBUTE_NORETURN;
 
 extern void xstat(char *filename, struct stat *buf);
 extern int  xsocket(int domain, int type, int protocol);

Modified: trunk/busybox/include/usage.h
===================================================================
--- trunk/busybox/include/usage.h	2006-10-14 11:47:02 UTC (rev 16380)
+++ trunk/busybox/include/usage.h	2006-10-14 14:24:30 UTC (rev 16381)
@@ -992,7 +992,7 @@
 	"\t-H login_host\tLog login_host into the utmp file as the hostname"
 
 #define grep_trivial_usage \
-	"[-ihHnqvso" \
+	"[-rihHnqvso" \
 	USE_FEATURE_GREP_EGREP_ALIAS("E") \
 	USE_FEATURE_GREP_CONTEXT("ABC") \
 	"] PATTERN [FILEs...]"
@@ -1001,6 +1001,7 @@
 	"Options:\n" \
 	"\t-H\tprefix output lines with filename where match was found\n" \
 	"\t-h\tsuppress the prefixing filename on output\n" \
+	"\t-r\trecurse subdirectories\n" \
 	"\t-i\tignore case distinctions\n" \
 	"\t-l\tlist names of files that match\n" \
 	"\t-L\tlist names of files that do not match\n" \

Modified: trunk/busybox/libbb/recursive_action.c
===================================================================
--- trunk/busybox/libbb/recursive_action.c	2006-10-14 11:47:02 UTC (rev 16380)
+++ trunk/busybox/libbb/recursive_action.c	2006-10-14 14:24:30 UTC (rev 16381)
@@ -46,14 +46,14 @@
 		return FALSE;
 	}
 
-	if (! followLinks && (S_ISLNK(statbuf.st_mode))) {
+	if (!followLinks && (S_ISLNK(statbuf.st_mode))) {
 		if (fileAction == NULL)
 			return TRUE;
 		else
 			return fileAction(fileName, &statbuf, userData);
 	}
 
-	if (! recurse) {
+	if (!recurse) {
 		if (S_ISDIR(statbuf.st_mode)) {
 			if (dirAction != NULL)
 				return (dirAction(fileName, &statbuf, userData));
@@ -65,9 +65,9 @@
 	if (S_ISDIR(statbuf.st_mode)) {
 		DIR *dir;
 
-		if (dirAction != NULL && ! depthFirst) {
+		if (dirAction != NULL && !depthFirst) {
 			status = dirAction(fileName, &statbuf, userData);
-			if (! status) {
+			if (!status) {
 				bb_perror_msg("%s", fileName);
 				return FALSE;
 			} else if (status == SKIP)
@@ -84,7 +84,7 @@
 			nextFile = concat_subpath_file(fileName, next->d_name);
 			if(nextFile == NULL)
 				continue;
-			if (! recursive_action(nextFile, TRUE, followLinks, depthFirst,
+			if (!recursive_action(nextFile, TRUE, followLinks, depthFirst,
 						fileAction, dirAction, userData)) {
 				status = FALSE;
 			}
@@ -92,12 +92,12 @@
 		}
 		closedir(dir);
 		if (dirAction != NULL && depthFirst) {
-			if (! dirAction(fileName, &statbuf, userData)) {
+			if (!dirAction(fileName, &statbuf, userData)) {
 				bb_perror_msg("%s", fileName);
 				return FALSE;
 			}
 		}
-		if (! status)
+		if (!status)
 			return FALSE;
 	} else {
 		if (fileAction == NULL)



More information about the busybox-cvs mailing list