From owner-freebsd-bugs@FreeBSD.ORG Thu Nov 6 11:50:01 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4CB2F1065679 for ; Thu, 6 Nov 2008 11:50:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 2819A8FC1B for ; Thu, 6 Nov 2008 11:50:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id mA6Bo1Bf087998 for ; Thu, 6 Nov 2008 11:50:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id mA6Bo0P0087997; Thu, 6 Nov 2008 11:50:01 GMT (envelope-from gnats) Resent-Date: Thu, 6 Nov 2008 11:50:01 GMT Resent-Message-Id: <200811061150.mA6Bo0P0087997@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, "Bjoern A. Zeeb" Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6128F1065676 for ; Thu, 6 Nov 2008 11:40:48 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 165958FC19 for ; Thu, 6 Nov 2008 11:40:48 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id mA6Beluq084166 for ; Thu, 6 Nov 2008 11:40:47 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id mA6BelUO084165; Thu, 6 Nov 2008 11:40:47 GMT (envelope-from nobody) Message-Id: <200811061140.mA6BelUO084165@www.freebsd.org> Date: Thu, 6 Nov 2008 11:40:47 GMT From: "Bjoern A. Zeeb" To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: gnu/128645: teach grep -r to how to ignore directories X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Nov 2008 11:50:01 -0000 >Number: 128645 >Category: gnu >Synopsis: teach grep -r to how to ignore directories >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu Nov 06 11:50:00 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Bjoern A. Zeeb >Release: 8.0-CURRENT >Organization: Zabbadoz.NeT >Environment: >Description: With for example a SVN tree checked out grep -r is a pain as it also finds the .svn/* copies and thus gives duplicate results, ... There is no way to tell grep to ignore .svn directories but only to ignore filenames based on patterns which works but not very well. >How-To-Repeat: checkout freebsd src tree from svn. From the toplevel do a grep -r XXX-BZ sys/ >Fix: I have a patch is not great but it adds an --exclude-dir option so one could do grep -r --exlcude-dir .svn XXX-BZ sys/ It would need review and someone brave enough to commit to gnu/ ;-) The patch is under GPLv2. Patch attached with submission follows: Index: gnu/usr.bin/grep/savedir.c =================================================================== --- gnu/usr.bin/grep/savedir.c (revision 184265) +++ gnu/usr.bin/grep/savedir.c (working copy) @@ -100,13 +100,34 @@ Return NULL if DIR cannot be opened or if out of memory. */ char * savedir (const char *dir, off_t name_size, struct exclude *included_patterns, - struct exclude *excluded_patterns) + struct exclude *excluded_patterns, struct exclude *excluded_dirs_patterns) { DIR *dirp; struct dirent *dp; char *name_space; char *namep; + if (excluded_dirs_patterns && isdir (dir)) + { + const char *d; + + d = strrchr(dir, '/'); + if (d != NULL) + d++; + else + d = dir; + if (excluded_filename (excluded_dirs_patterns, d, 0)) + { + if (name_size < 2) + name_size = 2; + name_space = (char *) malloc (name_size); + if (name_space == NULL) + return NULL; + memset (name_space, '\0', name_size); + return name_space; + } + } + dirp = opendir (dir); if (dirp == NULL) return NULL; Index: gnu/usr.bin/grep/savedir.h =================================================================== --- gnu/usr.bin/grep/savedir.h (revision 184265) +++ gnu/usr.bin/grep/savedir.h (working copy) @@ -13,6 +13,6 @@ extern char * savedir PARAMS ((const char *dir, off_t name_size, - struct exclude *, struct exclude *)); + struct exclude *, struct exclude *, struct exclude *)); #endif Index: gnu/usr.bin/grep/grep.c =================================================================== --- gnu/usr.bin/grep/grep.c (revision 184265) +++ gnu/usr.bin/grep/grep.c (working copy) @@ -89,6 +89,7 @@ static const char *grep_color = "01;31"; static struct exclude *excluded_patterns; +static struct exclude *excluded_dirs_patterns; static struct exclude *included_patterns; /* Short options. */ static char const short_options[] = @@ -103,7 +104,8 @@ EXCLUDE_OPTION, EXCLUDE_FROM_OPTION, LINE_BUFFERED_OPTION, - LABEL_OPTION + LABEL_OPTION, + EXCLUDE_DIR_OPTION }; /* Long options equivalences. */ @@ -122,6 +124,7 @@ {"directories", required_argument, NULL, 'd'}, {"extended-regexp", no_argument, NULL, 'E'}, {"exclude", required_argument, NULL, EXCLUDE_OPTION}, + {"exclude-dir", required_argument, NULL, EXCLUDE_DIR_OPTION}, {"exclude-from", required_argument, NULL, EXCLUDE_FROM_OPTION}, {"file", required_argument, NULL, 'f'}, {"files-with-matches", no_argument, NULL, 'l'}, @@ -1065,7 +1068,7 @@ } name_space = savedir (dir, stats->stat.st_size, included_patterns, - excluded_patterns); + excluded_patterns, excluded_dirs_patterns); if (! name_space) { @@ -1166,6 +1169,7 @@ -R, -r, --recursive equivalent to --directories=recurse\n\ --include=PATTERN files that match PATTERN will be examined\n\ --exclude=PATTERN files that match PATTERN will be skipped.\n\ + --exclude-dir=PATTERN directories that match PATTERN will be skipped.\n\ --exclude-from=FILE files that match PATTERN in FILE will be skipped.\n\ -L, --files-without-match only print FILE names containing no match\n\ -l, --files-with-matches only print FILE names containing matches\n\ @@ -1685,6 +1689,12 @@ add_exclude (excluded_patterns, optarg); break; + case EXCLUDE_DIR_OPTION: + if (!excluded_dirs_patterns) + excluded_dirs_patterns = new_exclude (); + add_exclude (excluded_dirs_patterns, optarg); + break; + case EXCLUDE_FROM_OPTION: if (!excluded_patterns) excluded_patterns = new_exclude (); @@ -1837,6 +1847,18 @@ do { char *file = argv[optind]; + if (excluded_dirs_patterns && isdir (file)) + { + char *d; + + d = strrchr(file, '/'); + if (d != NULL) + d++; + else + d = file; + if (excluded_filename (excluded_dirs_patterns, d, 0)) + continue; + } if ((included_patterns || excluded_patterns) && !isdir (file)) { >Release-Note: >Audit-Trail: >Unformatted: