[PATCH] git-log: added --grep-begin .. --grep-end syntax

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is useful to specify more complicated pattern as with '--grep'.

Signed-off-by: Christoph Junghans <ottxor@xxxxxxxxxx>
---
 builtin/grep.c | 73 +++++-----------------------------------------------------
 grep.c         | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
 grep.h         | 10 ++++++++
 revision.c     | 56 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 134 insertions(+), 67 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 4063882..0127fa0 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -551,67 +551,6 @@ static int context_callback(const struct option *opt, const char *arg,
 	return 0;
 }
 
-static int file_callback(const struct option *opt, const char *arg, int unset)
-{
-	struct grep_opt *grep_opt = opt->value;
-	int from_stdin = !strcmp(arg, "-");
-	FILE *patterns;
-	int lno = 0;
-	struct strbuf sb = STRBUF_INIT;
-
-	patterns = from_stdin ? stdin : fopen(arg, "r");
-	if (!patterns)
-		die_errno(_("cannot open '%s'"), arg);
-	while (strbuf_getline(&sb, patterns, '\n') == 0) {
-		/* ignore empty line like grep does */
-		if (sb.len == 0)
-			continue;
-
-		append_grep_pat(grep_opt, sb.buf, sb.len, arg, ++lno,
-				GREP_PATTERN);
-	}
-	if (!from_stdin)
-		fclose(patterns);
-	strbuf_release(&sb);
-	return 0;
-}
-
-static int not_callback(const struct option *opt, const char *arg, int unset)
-{
-	struct grep_opt *grep_opt = opt->value;
-	append_grep_pattern(grep_opt, "--not", "command line", 0, GREP_NOT);
-	return 0;
-}
-
-static int and_callback(const struct option *opt, const char *arg, int unset)
-{
-	struct grep_opt *grep_opt = opt->value;
-	append_grep_pattern(grep_opt, "--and", "command line", 0, GREP_AND);
-	return 0;
-}
-
-static int open_callback(const struct option *opt, const char *arg, int unset)
-{
-	struct grep_opt *grep_opt = opt->value;
-	append_grep_pattern(grep_opt, "(", "command line", 0, GREP_OPEN_PAREN);
-	return 0;
-}
-
-static int close_callback(const struct option *opt, const char *arg, int unset)
-{
-	struct grep_opt *grep_opt = opt->value;
-	append_grep_pattern(grep_opt, ")", "command line", 0, GREP_CLOSE_PAREN);
-	return 0;
-}
-
-static int pattern_callback(const struct option *opt, const char *arg,
-			    int unset)
-{
-	struct grep_opt *grep_opt = opt->value;
-	append_grep_pattern(grep_opt, arg, "-e option", 0, GREP_PATTERN);
-	return 0;
-}
-
 static int help_callback(const struct option *opt, const char *arg, int unset)
 {
 	return -1;
@@ -710,21 +649,21 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 			N_("show the surrounding function")),
 		OPT_GROUP(""),
 		OPT_CALLBACK('f', NULL, &opt, N_("file"),
-			N_("read patterns from file"), file_callback),
+			N_("read patterns from file"), grep_file_callback),
 		{ OPTION_CALLBACK, 'e', NULL, &opt, N_("pattern"),
-			N_("match <pattern>"), PARSE_OPT_NONEG, pattern_callback },
+			N_("match <pattern>"), PARSE_OPT_NONEG, grep_pattern_callback },
 		{ OPTION_CALLBACK, 0, "and", &opt, NULL,
 		  N_("combine patterns specified with -e"),
-		  PARSE_OPT_NOARG | PARSE_OPT_NONEG, and_callback },
+		  PARSE_OPT_NOARG | PARSE_OPT_NONEG, grep_and_callback },
 		OPT_BOOL(0, "or", &dummy, ""),
 		{ OPTION_CALLBACK, 0, "not", &opt, NULL, "",
-		  PARSE_OPT_NOARG | PARSE_OPT_NONEG, not_callback },
+		  PARSE_OPT_NOARG | PARSE_OPT_NONEG, grep_not_callback },
 		{ OPTION_CALLBACK, '(', NULL, &opt, NULL, "",
 		  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
-		  open_callback },
+		  grep_open_callback },
 		{ OPTION_CALLBACK, ')', NULL, &opt, NULL, "",
 		  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
-		  close_callback },
+		  grep_close_callback },
 		OPT__QUIET(&opt.status_only,
 			   N_("indicate hit with exit status without output")),
 		OPT_BOOL(0, "all-match", &opt.all_match,
diff --git a/grep.c b/grep.c
index 6e085f8..0c9a977 100644
--- a/grep.c
+++ b/grep.c
@@ -1796,3 +1796,65 @@ static int grep_source_is_binary(struct grep_source *gs)
 
 	return 0;
 }
+
+int grep_file_callback(const struct option *opt, const char *arg, int unset)
+{
+	struct grep_opt *grep_opt = opt->value;
+	int from_stdin = !strcmp(arg, "-");
+	FILE *patterns;
+	int lno = 0;
+	struct strbuf sb = STRBUF_INIT;
+
+	patterns = from_stdin ? stdin : fopen(arg, "r");
+	if (!patterns)
+		die_errno(_("cannot open '%s'"), arg);
+	while (strbuf_getline(&sb, patterns, '\n') == 0) {
+		/* ignore empty line like grep does */
+		if (sb.len == 0)
+			continue;
+
+		append_grep_pat(grep_opt, sb.buf, sb.len, arg, ++lno,
+				GREP_PATTERN);
+	}
+	if (!from_stdin)
+		fclose(patterns);
+	strbuf_release(&sb);
+	return 0;
+}
+
+int grep_not_callback(const struct option *opt, const char *arg, int unset)
+{
+	struct grep_opt *grep_opt = opt->value;
+	append_grep_pattern(grep_opt, "--not", "command line", 0, GREP_NOT);
+	return 0;
+}
+
+int grep_and_callback(const struct option *opt, const char *arg, int unset)
+{
+	struct grep_opt *grep_opt = opt->value;
+	append_grep_pattern(grep_opt, "--and", "command line", 0, GREP_AND);
+	return 0;
+}
+
+int grep_open_callback(const struct option *opt, const char *arg, int unset)
+{
+	struct grep_opt *grep_opt = opt->value;
+	append_grep_pattern(grep_opt, "(", "command line", 0, GREP_OPEN_PAREN);
+	return 0;
+}
+
+int grep_close_callback(const struct option *opt, const char *arg, int unset)
+{
+	struct grep_opt *grep_opt = opt->value;
+	append_grep_pattern(grep_opt, ")", "command line", 0, GREP_CLOSE_PAREN);
+	return 0;
+}
+
+int grep_pattern_callback(const struct option *opt, const char *arg,
+			    int unset)
+{
+	struct grep_opt *grep_opt = opt->value;
+	append_grep_pattern(grep_opt, arg, "-e option", 0, GREP_PATTERN);
+	return 0;
+}
+
diff --git a/grep.h b/grep.h
index 95f197a..d85fdb4 100644
--- a/grep.h
+++ b/grep.h
@@ -10,6 +10,7 @@ typedef int pcre_extra;
 #include "kwset.h"
 #include "thread-utils.h"
 #include "userdiff.h"
+#include "parse-options.h"
 
 enum grep_pat_token {
 	GREP_PATTERN,
@@ -181,6 +182,15 @@ void grep_source_load_driver(struct grep_source *gs);
 
 int grep_source(struct grep_opt *opt, struct grep_source *gs);
 
+
+int grep_file_callback(const struct option *opt, const char *arg, int unset);
+int grep_not_callback(const struct option *opt, const char *arg, int unset);
+int grep_and_callback(const struct option *opt, const char *arg, int unset);
+int grep_open_callback(const struct option *opt, const char *arg, int unset);
+int grep_close_callback(const struct option *opt, const char *arg, int unset);
+int grep_pattern_callback(const struct option *opt, const char *arg, int unset);
+
+
 extern struct grep_opt *grep_opt_dup(const struct grep_opt *opt);
 extern int grep_threads_ok(const struct grep_opt *opt);
 
diff --git a/revision.c b/revision.c
index 75dda92..4fe9085 100644
--- a/revision.c
+++ b/revision.c
@@ -1998,6 +1998,62 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		return argcount;
 	} else if (!strcmp(arg, "--grep-debug")) {
 		revs->grep_filter.debug = 1;
+	} else if (!strcmp(arg, "--grep-begin")) {
+		if (argc <= 1)
+			return error("--grep-begin requires an argument");
+		int dummy;
+		struct option options[] = {
+			OPT_CALLBACK('f', NULL, &revs->grep_filter, N_("file"),
+				N_("read patterns from file"), grep_file_callback),
+			{ OPTION_CALLBACK, 'e', NULL, &revs->grep_filter, N_("pattern"),
+				N_("match <pattern>"), PARSE_OPT_NONEG, grep_pattern_callback },
+			{ OPTION_CALLBACK, 0, "and", &revs->grep_filter, NULL,
+			  N_("combine patterns specified with -e"),
+			  PARSE_OPT_NOARG | PARSE_OPT_NONEG, grep_and_callback },
+			OPT_BOOL(0, "or", &dummy, ""),
+			{ OPTION_CALLBACK, 0, "not", &revs->grep_filter, NULL, "",
+			  PARSE_OPT_NOARG | PARSE_OPT_NONEG, grep_not_callback },
+			{ OPTION_CALLBACK, '(', NULL, &revs->grep_filter, NULL, "",
+			  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
+			  grep_open_callback },
+			{ OPTION_CALLBACK, ')', NULL, &revs->grep_filter, NULL, "",
+			  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
+			  grep_close_callback },
+			OPT_END()
+		};
+		char const * const grep_usage[] = {
+			N_("git log [log-options] --begin-grep [grep-options] --end-grep ..."), 
+			NULL 
+		};
+		struct parse_opt_ctx_t ctx;
+
+		parse_options_start(&ctx, argc, argv, revs->prefix, options,
+				PARSE_OPT_STOP_AT_NON_OPTION | PARSE_OPT_NO_INTERNAL_HELP);
+		if (parse_options_step(&ctx, options, grep_usage) != PARSE_OPT_UNKNOWN) {
+			error("--grep-end expected");
+			usage_with_options(grep_usage, options);
+		}
+		if(strcmp(ctx.argv[0], "--grep-end")) {
+			if (ctx.argv[0][1] == '-') {
+			error("unknown option `%s'", ctx.argv[0] + 2);
+			} else if (isascii(*ctx.opt)) {
+				error("unknown switch `%c'", *ctx.opt);
+			} else {
+			error("unknown non-ascii option in string: `%s'",
+			      ctx.argv[0]);
+			}	
+			usage_with_options(grep_usage, options);
+		}
+
+		precompose_argv(argc, argv);
+		argcount = argc + 1 - parse_options_end(&ctx);
+		if (argcount == 2 ) {
+			return error("There should be options between --grep-begin and --grep-end ;-)");
+		}
+
+		grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED, &revs->grep_filter);
+
+		return argcount;
 	} else if (!strcmp(arg, "--basic-regexp")) {
 		grep_set_pattern_type_option(GREP_PATTERN_TYPE_BRE, &revs->grep_filter);
 	} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
-- 
2.0.5

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]