All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Tying loose ends on grep-pcre
@ 2012-10-10  7:55 Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 1/7] builtin/grep.c: make configuration callback more reusable Junio C Hamano
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Junio C Hamano @ 2012-10-10  7:55 UTC (permalink / raw)
  To: git

It took longer than expected, but here is a reroll of the previous
series to bring more recent "git grep" enhancements to the "--grep"
option of commands in "git log" family.

The early part of the series (1-3) refactors the code that reads
configuration items related to "grep" and the code that mixes the
result with the command line options to prepare grep_opt, which so
far lived in builtin/grep.c, and moves them to the grep.[ch] at the
top-level.

The middle part (4-6) reuses the code to set-up grep_opt refactored
by the earlier part of the series on revs->grep_filter that is used
in "git log --grep=..." processing.  It incidentally fixes a small
bug where "git log -F -E --grep='<ere>'" did not look for matches to
the pattern in extended regular expression, and adds --basic-regexp
and --perl-regexp command line options to "git log" family for
completeness.

The last one teaches "git log" family to honor the "grep.*"
configuration variables, e.g. "grep.patterntype", so that you can
say "git -c grep.patterntype=perl log --grep='(?:pcre)'".

Obviously, it is too late for this cycle and will not graduate to
'master' before the 1.8.0 final.


Junio C Hamano (7):
  builtin/grep.c: make configuration callback more reusable
  grep: move the configuration parsing logic to grep.[ch]
  grep: move pattern-type bits support to top-level grep.[ch]
  revisions: initialize revs->grep_filter using grep_init()
  log --grep: use the same helper to set -E/-F options as "git grep"
  log --grep: accept --basic-regexp and --perl-regexp
  log: honor grep.* configuration

 Documentation/rev-list-options.txt |  10 +++
 builtin/grep.c                     | 133 ++--------------------------
 builtin/log.c                      |   8 +-
 grep.c                             | 177 +++++++++++++++++++++++++++++++++++++
 grep.h                             |   6 ++
 revision.c                         |  14 ++-
 t/t4202-log.sh                     |   6 ++
 7 files changed, 225 insertions(+), 129 deletions(-)

-- 
1.8.0.rc1.76.g5a375e6

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/7] builtin/grep.c: make configuration callback more reusable
  2012-10-10  7:55 [PATCH v2 0/7] Tying loose ends on grep-pcre Junio C Hamano
@ 2012-10-10  7:55 ` Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 2/7] grep: move the configuration parsing logic to grep.[ch] Junio C Hamano
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2012-10-10  7:55 UTC (permalink / raw)
  To: git

The grep_config() function takes one instance of grep_opt as its
callback parameter, and populates it by running git_config().

This has three practical implications:

 - You have to have an instance of grep_opt already when you call
   the configuration, but that is not necessarily always true.  You
   may be trying to initialize the grep_filter member of rev_info,
   but are not ready to call init_revisions() on it yet.

 - It is not easy to enhance grep_config() in such a way to make it
   cascade to other callback functions to grab other variables in
   one call of git_config(); grep_config() can be cascaded into from
   other callbacks, but it has to be at the leaf level of a cascade.

 - If you ever need to use more than one instance of grep_opt, you
   will have to open and read the configuration file(s) every time
   you initialize them.

Rearrange the configuration mechanism and model it after how diff
configuration variables are handled.  An early call to git_config()
reads and remembers the values taken from the configuration in the
default "template", and a separate call to grep_init() uses this
template to instantiate a grep_opt.

The next step will be to move some of this out of this file so that
the other user of the grep machinery (i.e. "log") can use it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/grep.c | 104 +++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 79 insertions(+), 25 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 82530a6..83232c9 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -308,9 +308,41 @@ static void grep_pattern_type_options(const int pattern_type, struct grep_opt *o
 	}
 }
 
+static struct grep_opt grep_defaults;
+
+/*
+ * Initialize the grep_defaults template with hardcoded defaults.
+ * We could let the compiler do this, but without C99 initializers
+ * the code gets unwieldy and unreadable, so...
+ */
+static void init_grep_defaults(void)
+{
+	struct grep_opt *opt = &grep_defaults;
+
+	memset(opt, 0, sizeof(*opt));
+	opt->relative = 1;
+	opt->pathname = 1;
+	opt->regflags = REG_NEWLINE;
+	opt->max_depth = -1;
+	opt->pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
+	opt->extended_regexp_option = 0;
+	strcpy(opt->color_context, "");
+	strcpy(opt->color_filename, "");
+	strcpy(opt->color_function, "");
+	strcpy(opt->color_lineno, "");
+	strcpy(opt->color_match, GIT_COLOR_BOLD_RED);
+	strcpy(opt->color_selected, "");
+	strcpy(opt->color_sep, GIT_COLOR_CYAN);
+	opt->color = -1;
+}
+
+/*
+ * Read the configuration file once and store it in
+ * the grep_defaults template.
+ */
 static int grep_config(const char *var, const char *value, void *cb)
 {
-	struct grep_opt *opt = cb;
+	struct grep_opt *opt = &grep_defaults;
 	char *color = NULL;
 
 	if (userdiff_config(var, value) < 0)
@@ -327,7 +359,7 @@ static int grep_config(const char *var, const char *value, void *cb)
 	if (!strcmp(var, "grep.patterntype")) {
 		opt->pattern_type_option = parse_pattern_type_arg(var, value);
 		return 0;
-  }
+	}
 
 	if (!strcmp(var, "grep.linenumber")) {
 		opt->linenum = git_config_bool(var, value);
@@ -350,8 +382,7 @@ static int grep_config(const char *var, const char *value, void *cb)
 		color = opt->color_selected;
 	else if (!strcmp(var, "color.grep.separator"))
 		color = opt->color_sep;
-	else
-		return git_color_default_config(var, value, cb);
+
 	if (color) {
 		if (!value)
 			return config_error_nonbool(var);
@@ -360,6 +391,47 @@ static int grep_config(const char *var, const char *value, void *cb)
 	return 0;
 }
 
+/*
+ * Initialize one instance of grep_opt and copy the
+ * default values from the template we read the configuration
+ * information in an earlier call to git_config(grep_config).
+ */
+static void grep_init(struct grep_opt *opt, const char *prefix)
+{
+	struct grep_opt *def = &grep_defaults;
+
+	memset(opt, 0, sizeof(*opt));
+	opt->prefix = prefix;
+	opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
+	opt->pattern_tail = &opt->pattern_list;
+	opt->header_tail = &opt->header_list;
+
+	opt->color = def->color;
+	opt->extended_regexp_option = def->extended_regexp_option;
+	opt->pattern_type_option = def->pattern_type_option;
+	opt->linenum = def->linenum;
+	opt->max_depth = def->max_depth;
+	opt->pathname = def->pathname;
+	opt->regflags = def->regflags;
+	opt->relative = def->relative;
+
+	strcpy(opt->color_context, def->color_context);
+	strcpy(opt->color_filename, def->color_filename);
+	strcpy(opt->color_function, def->color_function);
+	strcpy(opt->color_lineno, def->color_lineno);
+	strcpy(opt->color_match, def->color_match);
+	strcpy(opt->color_selected, def->color_selected);
+	strcpy(opt->color_sep, def->color_sep);
+}
+
+static int grep_cmd_config(const char *var, const char *value, void *cb)
+{
+	int st = grep_config(var, value, cb);
+	if (git_color_default_config(var, value, cb) < 0)
+		st = -1;
+	return st;
+}
+
 static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
 {
 	void *data;
@@ -839,27 +911,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 	if (argc == 2 && !strcmp(argv[1], "-h"))
 		usage_with_options(grep_usage, options);
 
-	memset(&opt, 0, sizeof(opt));
-	opt.prefix = prefix;
-	opt.prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
-	opt.relative = 1;
-	opt.pathname = 1;
-	opt.pattern_tail = &opt.pattern_list;
-	opt.header_tail = &opt.header_list;
-	opt.regflags = REG_NEWLINE;
-	opt.max_depth = -1;
-	opt.pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
-	opt.extended_regexp_option = 0;
-
-	strcpy(opt.color_context, "");
-	strcpy(opt.color_filename, "");
-	strcpy(opt.color_function, "");
-	strcpy(opt.color_lineno, "");
-	strcpy(opt.color_match, GIT_COLOR_BOLD_RED);
-	strcpy(opt.color_selected, "");
-	strcpy(opt.color_sep, GIT_COLOR_CYAN);
-	opt.color = -1;
-	git_config(grep_config, &opt);
+	init_grep_defaults();
+	git_config(grep_cmd_config, NULL);
+	grep_init(&opt, prefix);
 
 	/*
 	 * If there is no -- then the paths must exist in the working
-- 
1.8.0.rc1.76.g5a375e6

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/7] grep: move the configuration parsing logic to grep.[ch]
  2012-10-10  7:55 [PATCH v2 0/7] Tying loose ends on grep-pcre Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 1/7] builtin/grep.c: make configuration callback more reusable Junio C Hamano
@ 2012-10-10  7:55 ` Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 3/7] grep: move pattern-type bits support to top-level grep.[ch] Junio C Hamano
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2012-10-10  7:55 UTC (permalink / raw)
  To: git

The configuration handling is a library-ish part of this program,
that is not specific to "git grep" command.  It should be reusable
by "log" and others.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/grep.c | 131 ---------------------------------------------------------
 grep.c         | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 grep.h         |   4 ++
 3 files changed, 134 insertions(+), 131 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 83232c9..b63a9f8 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -261,21 +261,6 @@ static int wait_all(void)
 }
 #endif
 
-static int parse_pattern_type_arg(const char *opt, const char *arg)
-{
-	if (!strcmp(arg, "default"))
-		return GREP_PATTERN_TYPE_UNSPECIFIED;
-	else if (!strcmp(arg, "basic"))
-		return GREP_PATTERN_TYPE_BRE;
-	else if (!strcmp(arg, "extended"))
-		return GREP_PATTERN_TYPE_ERE;
-	else if (!strcmp(arg, "fixed"))
-		return GREP_PATTERN_TYPE_FIXED;
-	else if (!strcmp(arg, "perl"))
-		return GREP_PATTERN_TYPE_PCRE;
-	die("bad %s argument: %s", opt, arg);
-}
-
 static void grep_pattern_type_options(const int pattern_type, struct grep_opt *opt)
 {
 	switch (pattern_type) {
@@ -308,122 +293,6 @@ static void grep_pattern_type_options(const int pattern_type, struct grep_opt *o
 	}
 }
 
-static struct grep_opt grep_defaults;
-
-/*
- * Initialize the grep_defaults template with hardcoded defaults.
- * We could let the compiler do this, but without C99 initializers
- * the code gets unwieldy and unreadable, so...
- */
-static void init_grep_defaults(void)
-{
-	struct grep_opt *opt = &grep_defaults;
-
-	memset(opt, 0, sizeof(*opt));
-	opt->relative = 1;
-	opt->pathname = 1;
-	opt->regflags = REG_NEWLINE;
-	opt->max_depth = -1;
-	opt->pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
-	opt->extended_regexp_option = 0;
-	strcpy(opt->color_context, "");
-	strcpy(opt->color_filename, "");
-	strcpy(opt->color_function, "");
-	strcpy(opt->color_lineno, "");
-	strcpy(opt->color_match, GIT_COLOR_BOLD_RED);
-	strcpy(opt->color_selected, "");
-	strcpy(opt->color_sep, GIT_COLOR_CYAN);
-	opt->color = -1;
-}
-
-/*
- * Read the configuration file once and store it in
- * the grep_defaults template.
- */
-static int grep_config(const char *var, const char *value, void *cb)
-{
-	struct grep_opt *opt = &grep_defaults;
-	char *color = NULL;
-
-	if (userdiff_config(var, value) < 0)
-		return -1;
-
-	if (!strcmp(var, "grep.extendedregexp")) {
-		if (git_config_bool(var, value))
-			opt->extended_regexp_option = 1;
-		else
-			opt->extended_regexp_option = 0;
-		return 0;
-	}
-
-	if (!strcmp(var, "grep.patterntype")) {
-		opt->pattern_type_option = parse_pattern_type_arg(var, value);
-		return 0;
-	}
-
-	if (!strcmp(var, "grep.linenumber")) {
-		opt->linenum = git_config_bool(var, value);
-		return 0;
-	}
-
-	if (!strcmp(var, "color.grep"))
-		opt->color = git_config_colorbool(var, value);
-	else if (!strcmp(var, "color.grep.context"))
-		color = opt->color_context;
-	else if (!strcmp(var, "color.grep.filename"))
-		color = opt->color_filename;
-	else if (!strcmp(var, "color.grep.function"))
-		color = opt->color_function;
-	else if (!strcmp(var, "color.grep.linenumber"))
-		color = opt->color_lineno;
-	else if (!strcmp(var, "color.grep.match"))
-		color = opt->color_match;
-	else if (!strcmp(var, "color.grep.selected"))
-		color = opt->color_selected;
-	else if (!strcmp(var, "color.grep.separator"))
-		color = opt->color_sep;
-
-	if (color) {
-		if (!value)
-			return config_error_nonbool(var);
-		color_parse(value, var, color);
-	}
-	return 0;
-}
-
-/*
- * Initialize one instance of grep_opt and copy the
- * default values from the template we read the configuration
- * information in an earlier call to git_config(grep_config).
- */
-static void grep_init(struct grep_opt *opt, const char *prefix)
-{
-	struct grep_opt *def = &grep_defaults;
-
-	memset(opt, 0, sizeof(*opt));
-	opt->prefix = prefix;
-	opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
-	opt->pattern_tail = &opt->pattern_list;
-	opt->header_tail = &opt->header_list;
-
-	opt->color = def->color;
-	opt->extended_regexp_option = def->extended_regexp_option;
-	opt->pattern_type_option = def->pattern_type_option;
-	opt->linenum = def->linenum;
-	opt->max_depth = def->max_depth;
-	opt->pathname = def->pathname;
-	opt->regflags = def->regflags;
-	opt->relative = def->relative;
-
-	strcpy(opt->color_context, def->color_context);
-	strcpy(opt->color_filename, def->color_filename);
-	strcpy(opt->color_function, def->color_function);
-	strcpy(opt->color_lineno, def->color_lineno);
-	strcpy(opt->color_match, def->color_match);
-	strcpy(opt->color_selected, def->color_selected);
-	strcpy(opt->color_sep, def->color_sep);
-}
-
 static int grep_cmd_config(const char *var, const char *value, void *cb)
 {
 	int st = grep_config(var, value, cb);
diff --git a/grep.c b/grep.c
index edc7776..621e6ec 100644
--- a/grep.c
+++ b/grep.c
@@ -6,6 +6,136 @@
 static int grep_source_load(struct grep_source *gs);
 static int grep_source_is_binary(struct grep_source *gs);
 
+static struct grep_opt grep_defaults;
+
+/*
+ * Initialize the grep_defaults template with hardcoded defaults.
+ * We could let the compiler do this, but without C99 initializers
+ * the code gets unwieldy and unreadable, so...
+ */
+void init_grep_defaults(void)
+{
+	struct grep_opt *opt = &grep_defaults;
+
+	memset(opt, 0, sizeof(*opt));
+	opt->relative = 1;
+	opt->pathname = 1;
+	opt->regflags = REG_NEWLINE;
+	opt->max_depth = -1;
+	opt->pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
+	opt->extended_regexp_option = 0;
+	strcpy(opt->color_context, "");
+	strcpy(opt->color_filename, "");
+	strcpy(opt->color_function, "");
+	strcpy(opt->color_lineno, "");
+	strcpy(opt->color_match, GIT_COLOR_BOLD_RED);
+	strcpy(opt->color_selected, "");
+	strcpy(opt->color_sep, GIT_COLOR_CYAN);
+	opt->color = -1;
+}
+
+static int parse_pattern_type_arg(const char *opt, const char *arg)
+{
+	if (!strcmp(arg, "default"))
+		return GREP_PATTERN_TYPE_UNSPECIFIED;
+	else if (!strcmp(arg, "basic"))
+		return GREP_PATTERN_TYPE_BRE;
+	else if (!strcmp(arg, "extended"))
+		return GREP_PATTERN_TYPE_ERE;
+	else if (!strcmp(arg, "fixed"))
+		return GREP_PATTERN_TYPE_FIXED;
+	else if (!strcmp(arg, "perl"))
+		return GREP_PATTERN_TYPE_PCRE;
+	die("bad %s argument: %s", opt, arg);
+}
+
+/*
+ * Read the configuration file once and store it in
+ * the grep_defaults template.
+ */
+int grep_config(const char *var, const char *value, void *cb)
+{
+	struct grep_opt *opt = &grep_defaults;
+	char *color = NULL;
+
+	if (userdiff_config(var, value) < 0)
+		return -1;
+
+	if (!strcmp(var, "grep.extendedregexp")) {
+		if (git_config_bool(var, value))
+			opt->extended_regexp_option = 1;
+		else
+			opt->extended_regexp_option = 0;
+		return 0;
+	}
+
+	if (!strcmp(var, "grep.patterntype")) {
+		opt->pattern_type_option = parse_pattern_type_arg(var, value);
+		return 0;
+	}
+
+	if (!strcmp(var, "grep.linenumber")) {
+		opt->linenum = git_config_bool(var, value);
+		return 0;
+	}
+
+	if (!strcmp(var, "color.grep"))
+		opt->color = git_config_colorbool(var, value);
+	else if (!strcmp(var, "color.grep.context"))
+		color = opt->color_context;
+	else if (!strcmp(var, "color.grep.filename"))
+		color = opt->color_filename;
+	else if (!strcmp(var, "color.grep.function"))
+		color = opt->color_function;
+	else if (!strcmp(var, "color.grep.linenumber"))
+		color = opt->color_lineno;
+	else if (!strcmp(var, "color.grep.match"))
+		color = opt->color_match;
+	else if (!strcmp(var, "color.grep.selected"))
+		color = opt->color_selected;
+	else if (!strcmp(var, "color.grep.separator"))
+		color = opt->color_sep;
+
+	if (color) {
+		if (!value)
+			return config_error_nonbool(var);
+		color_parse(value, var, color);
+	}
+	return 0;
+}
+
+/*
+ * Initialize one instance of grep_opt and copy the
+ * default values from the template we read the configuration
+ * information in an earlier call to git_config(grep_config).
+ */
+void grep_init(struct grep_opt *opt, const char *prefix)
+{
+	struct grep_opt *def = &grep_defaults;
+
+	memset(opt, 0, sizeof(*opt));
+	opt->prefix = prefix;
+	opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
+	opt->pattern_tail = &opt->pattern_list;
+	opt->header_tail = &opt->header_list;
+
+	opt->color = def->color;
+	opt->extended_regexp_option = def->extended_regexp_option;
+	opt->pattern_type_option = def->pattern_type_option;
+	opt->linenum = def->linenum;
+	opt->max_depth = def->max_depth;
+	opt->pathname = def->pathname;
+	opt->regflags = def->regflags;
+	opt->relative = def->relative;
+
+	strcpy(opt->color_context, def->color_context);
+	strcpy(opt->color_filename, def->color_filename);
+	strcpy(opt->color_function, def->color_function);
+	strcpy(opt->color_lineno, def->color_lineno);
+	strcpy(opt->color_match, def->color_match);
+	strcpy(opt->color_selected, def->color_selected);
+	strcpy(opt->color_sep, def->color_sep);
+}
 
 static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
 					const char *origin, int no,
diff --git a/grep.h b/grep.h
index c256ac6..9aa1cc7 100644
--- a/grep.h
+++ b/grep.h
@@ -138,6 +138,10 @@ struct grep_opt {
 	void *output_priv;
 };
 
+extern void init_grep_defaults(void);
+extern int grep_config(const char *var, const char *value, void *);
+extern void grep_init(struct grep_opt *, const char *prefix);
+
 extern void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
 extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
 extern void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *);
-- 
1.8.0.rc1.76.g5a375e6

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/7] grep: move pattern-type bits support to top-level grep.[ch]
  2012-10-10  7:55 [PATCH v2 0/7] Tying loose ends on grep-pcre Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 1/7] builtin/grep.c: make configuration callback more reusable Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 2/7] grep: move the configuration parsing logic to grep.[ch] Junio C Hamano
@ 2012-10-10  7:55 ` Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 4/7] revisions: initialize revs->grep_filter using grep_init() Junio C Hamano
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2012-10-10  7:55 UTC (permalink / raw)
  To: git

Switching between -E/-G/-P/-F correctly needs a lot more than just
flipping opt->regflags bit these days, and we have a nice helper
function buried in builtin/grep.c for the sole use of "git grep".

Extract it so that "log --grep" family can also use it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/grep.c | 40 +---------------------------------------
 grep.c         | 42 ++++++++++++++++++++++++++++++++++++++++++
 grep.h         |  2 ++
 3 files changed, 45 insertions(+), 39 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index b63a9f8..c296e6f 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -261,38 +261,6 @@ static int wait_all(void)
 }
 #endif
 
-static void grep_pattern_type_options(const int pattern_type, struct grep_opt *opt)
-{
-	switch (pattern_type) {
-	case GREP_PATTERN_TYPE_UNSPECIFIED:
-		/* fall through */
-
-	case GREP_PATTERN_TYPE_BRE:
-		opt->fixed = 0;
-		opt->pcre = 0;
-		opt->regflags &= ~REG_EXTENDED;
-		break;
-
-	case GREP_PATTERN_TYPE_ERE:
-		opt->fixed = 0;
-		opt->pcre = 0;
-		opt->regflags |= REG_EXTENDED;
-		break;
-
-	case GREP_PATTERN_TYPE_FIXED:
-		opt->fixed = 1;
-		opt->pcre = 0;
-		opt->regflags &= ~REG_EXTENDED;
-		break;
-
-	case GREP_PATTERN_TYPE_PCRE:
-		opt->fixed = 0;
-		opt->pcre = 1;
-		opt->regflags &= ~REG_EXTENDED;
-		break;
-	}
-}
-
 static int grep_cmd_config(const char *var, const char *value, void *cb)
 {
 	int st = grep_config(var, value, cb);
@@ -798,13 +766,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 			     PARSE_OPT_KEEP_DASHDASH |
 			     PARSE_OPT_STOP_AT_NON_OPTION |
 			     PARSE_OPT_NO_INTERNAL_HELP);
-
-	if (pattern_type_arg != GREP_PATTERN_TYPE_UNSPECIFIED)
-		grep_pattern_type_options(pattern_type_arg, &opt);
-	else if (opt.pattern_type_option != GREP_PATTERN_TYPE_UNSPECIFIED)
-		grep_pattern_type_options(opt.pattern_type_option, &opt);
-	else if (opt.extended_regexp_option)
-		grep_pattern_type_options(GREP_PATTERN_TYPE_ERE, &opt);
+	grep_commit_pattern_type(pattern_type_arg, &opt);
 
 	if (use_index && !startup_info->have_repository)
 		/* die the same way as if we did it at the beginning */
diff --git a/grep.c b/grep.c
index 621e6ec..279a559 100644
--- a/grep.c
+++ b/grep.c
@@ -137,6 +137,48 @@ void grep_init(struct grep_opt *opt, const char *prefix)
 	strcpy(opt->color_sep, def->color_sep);
 }
 
+void grep_commit_pattern_type(enum grep_pattern_type pattern_type, struct grep_opt *opt)
+{
+	if (pattern_type != GREP_PATTERN_TYPE_UNSPECIFIED)
+		grep_set_pattern_type_option(pattern_type, opt);
+	else if (opt->pattern_type_option != GREP_PATTERN_TYPE_UNSPECIFIED)
+		grep_set_pattern_type_option(opt->pattern_type_option, opt);
+	else if (opt->extended_regexp_option)
+		grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, opt);
+}
+
+void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt)
+{
+	switch (pattern_type) {
+	case GREP_PATTERN_TYPE_UNSPECIFIED:
+		/* fall through */
+
+	case GREP_PATTERN_TYPE_BRE:
+		opt->fixed = 0;
+		opt->pcre = 0;
+		opt->regflags &= ~REG_EXTENDED;
+		break;
+
+	case GREP_PATTERN_TYPE_ERE:
+		opt->fixed = 0;
+		opt->pcre = 0;
+		opt->regflags |= REG_EXTENDED;
+		break;
+
+	case GREP_PATTERN_TYPE_FIXED:
+		opt->fixed = 1;
+		opt->pcre = 0;
+		opt->regflags &= ~REG_EXTENDED;
+		break;
+
+	case GREP_PATTERN_TYPE_PCRE:
+		opt->fixed = 0;
+		opt->pcre = 1;
+		opt->regflags &= ~REG_EXTENDED;
+		break;
+	}
+}
+
 static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
 					const char *origin, int no,
 					enum grep_pat_token t,
diff --git a/grep.h b/grep.h
index 9aa1cc7..701c784 100644
--- a/grep.h
+++ b/grep.h
@@ -141,6 +141,8 @@ struct grep_opt {
 extern void init_grep_defaults(void);
 extern int grep_config(const char *var, const char *value, void *);
 extern void grep_init(struct grep_opt *, const char *prefix);
+void grep_set_pattern_type_option(enum grep_pattern_type, struct grep_opt *opt);
+void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt);
 
 extern void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
 extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
-- 
1.8.0.rc1.76.g5a375e6

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/7] revisions: initialize revs->grep_filter using grep_init()
  2012-10-10  7:55 [PATCH v2 0/7] Tying loose ends on grep-pcre Junio C Hamano
                   ` (2 preceding siblings ...)
  2012-10-10  7:55 ` [PATCH v2 3/7] grep: move pattern-type bits support to top-level grep.[ch] Junio C Hamano
@ 2012-10-10  7:55 ` Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 5/7] log --grep: use the same helper to set -E/-F options as "git grep" Junio C Hamano
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2012-10-10  7:55 UTC (permalink / raw)
  To: git

Instead of using the hand-rolled initialization sequence,
use grep_init() to populate the necessary bits.  This opens
the door to allow the calling commands to optionally read
grep.* configuration variables via git_config() if they
want to.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 grep.c     | 5 +++++
 revision.c | 6 ++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/grep.c b/grep.c
index 279a559..a947a68 100644
--- a/grep.c
+++ b/grep.c
@@ -16,6 +16,11 @@ static struct grep_opt grep_defaults;
 void init_grep_defaults(void)
 {
 	struct grep_opt *opt = &grep_defaults;
+	static int run_once;
+
+	if (run_once)
+		return;
+	run_once++;
 
 	memset(opt, 0, sizeof(*opt));
 	opt->relative = 1;
diff --git a/revision.c b/revision.c
index a09e60b..a4a9314 100644
--- a/revision.c
+++ b/revision.c
@@ -1048,9 +1048,9 @@ void init_revisions(struct rev_info *revs, const char *prefix)
 
 	revs->commit_format = CMIT_FMT_DEFAULT;
 
+	init_grep_defaults();
+	grep_init(&revs->grep_filter, prefix);
 	revs->grep_filter.status_only = 1;
-	revs->grep_filter.pattern_tail = &(revs->grep_filter.pattern_list);
-	revs->grep_filter.header_tail = &(revs->grep_filter.header_list);
 	revs->grep_filter.regflags = REG_NEWLINE;
 
 	diff_setup(&revs->diffopt);
@@ -1893,6 +1893,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 	revs->diffopt.abbrev = revs->abbrev;
 	diff_setup_done(&revs->diffopt);
 
+	grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED,
+				 &revs->grep_filter);
 	compile_grep_patterns(&revs->grep_filter);
 
 	if (revs->reverse && revs->reflog_info)
-- 
1.8.0.rc1.76.g5a375e6

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/7] log --grep: use the same helper to set -E/-F options as "git grep"
  2012-10-10  7:55 [PATCH v2 0/7] Tying loose ends on grep-pcre Junio C Hamano
                   ` (3 preceding siblings ...)
  2012-10-10  7:55 ` [PATCH v2 4/7] revisions: initialize revs->grep_filter using grep_init() Junio C Hamano
@ 2012-10-10  7:55 ` Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 6/7] log --grep: accept --basic-regexp and --perl-regexp Junio C Hamano
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2012-10-10  7:55 UTC (permalink / raw)
  To: git

The command line option parser for "git log -F -E --grep='<ere>'"
did not flip the "fixed" bit, violating the general "last option
wins" principle among conflicting options.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 revision.c     | 4 ++--
 t/t4202-log.sh | 6 ++++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/revision.c b/revision.c
index a4a9314..68545c8 100644
--- a/revision.c
+++ b/revision.c
@@ -1604,12 +1604,12 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 	} else if (!strcmp(arg, "--grep-debug")) {
 		revs->grep_filter.debug = 1;
 	} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
-		revs->grep_filter.regflags |= REG_EXTENDED;
+		grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, &revs->grep_filter);
 	} else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
 		revs->grep_filter.regflags |= REG_ICASE;
 		DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE);
 	} else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
-		revs->grep_filter.fixed = 1;
+		grep_set_pattern_type_option(GREP_PATTERN_TYPE_FIXED, &revs->grep_filter);
 	} else if (!strcmp(arg, "--all-match")) {
 		revs->grep_filter.all_match = 1;
 	} else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 924ba53..e6537ab 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -230,6 +230,12 @@ test_expect_success 'log --grep -i' '
 	test_cmp expect actual
 '
 
+test_expect_success 'log -F -E --grep=<ere> uses ere' '
+	echo second >expect &&
+	git log -1 --pretty="tformat:%s" -F -E --grep=s.c.nd >actual &&
+	test_cmp expect actual
+'
+
 cat > expect <<EOF
 * Second
 * sixth
-- 
1.8.0.rc1.76.g5a375e6

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 6/7] log --grep: accept --basic-regexp and --perl-regexp
  2012-10-10  7:55 [PATCH v2 0/7] Tying loose ends on grep-pcre Junio C Hamano
                   ` (4 preceding siblings ...)
  2012-10-10  7:55 ` [PATCH v2 5/7] log --grep: use the same helper to set -E/-F options as "git grep" Junio C Hamano
@ 2012-10-10  7:55 ` Junio C Hamano
  2012-10-10  7:55 ` [PATCH v2 7/7] log: honor grep.* configuration Junio C Hamano
  2012-10-10 15:17 ` [PATCH v2 0/7] Tying loose ends on grep-pcre Michael Haggerty
  7 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2012-10-10  7:55 UTC (permalink / raw)
  To: git

When we added the "--perl-regexp" option (or "-P") to "git grep", we
should have done the same for the commands in the "git log" family,
but somehow we forgot to do so.  This corrects it, but we will
reserve the short-and-sweet "-P" option for something else for now.

Also introduce the "--basic-regexp" option for completeness, so that
the "last one wins" principle can be used to defeat an earlier -E
option, e.g. "git log -E --basic-regexp --grep='<bre>'".  Note that
it cannot have the short "-G" option as the option is to grep in the
patch text in the context of "log" family.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/rev-list-options.txt | 10 ++++++++++
 revision.c                         |  4 ++++
 2 files changed, 14 insertions(+)

diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index ee49743..1ec14a0 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -79,6 +79,11 @@ if it is part of the log message.
 
 	Match the regexp limiting patterns without regard to letters case.
 
+--basic-regexp::
+
+	Consider the limiting patterns to be basic regular expressions;
+	this is the default.
+
 -E::
 --extended-regexp::
 
@@ -91,6 +96,11 @@ if it is part of the log message.
 	Consider the limiting patterns to be fixed strings (don't interpret
 	pattern as a regular expression).
 
+--perl-regexp::
+
+	Consider the limiting patterns to be Perl-compatible regexp.
+	Requires libpcre to be compiled in.
+
 --remove-empty::
 
 	Stop when a given path disappears from the tree.
diff --git a/revision.c b/revision.c
index 68545c8..d7d621c 100644
--- a/revision.c
+++ b/revision.c
@@ -1603,6 +1603,8 @@ 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, "--basic-regexp")) {
+		grep_set_pattern_type_option(GREP_PATTERN_TYPE_BRE, &revs->grep_filter);
 	} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
 		grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, &revs->grep_filter);
 	} else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
@@ -1610,6 +1612,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE);
 	} else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
 		grep_set_pattern_type_option(GREP_PATTERN_TYPE_FIXED, &revs->grep_filter);
+	} else if (!strcmp(arg, "--perl-regexp")) {
+		grep_set_pattern_type_option(GREP_PATTERN_TYPE_PCRE, &revs->grep_filter);
 	} else if (!strcmp(arg, "--all-match")) {
 		revs->grep_filter.all_match = 1;
 	} else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
-- 
1.8.0.rc1.76.g5a375e6

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 7/7] log: honor grep.* configuration
  2012-10-10  7:55 [PATCH v2 0/7] Tying loose ends on grep-pcre Junio C Hamano
                   ` (5 preceding siblings ...)
  2012-10-10  7:55 ` [PATCH v2 6/7] log --grep: accept --basic-regexp and --perl-regexp Junio C Hamano
@ 2012-10-10  7:55 ` Junio C Hamano
  2012-10-10 15:17 ` [PATCH v2 0/7] Tying loose ends on grep-pcre Michael Haggerty
  7 siblings, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2012-10-10  7:55 UTC (permalink / raw)
  To: git

Now the grep_config() callback is reusable from other configuration
callbacks, call it from git_log_config() so that grep.patterntype
and friends can be used with the commands in the "git log" family.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/log.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/builtin/log.c b/builtin/log.c
index 09cf43e..e7b7db1 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -351,7 +351,8 @@ static int git_log_config(const char *var, const char *value, void *cb)
 	}
 	if (!prefixcmp(var, "color.decorate."))
 		return parse_decorate_color_config(var, 15, value);
-
+	if (grep_config(var, value, cb) < 0)
+		return -1;
 	return git_diff_ui_config(var, value, cb);
 }
 
@@ -360,6 +361,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
 	struct rev_info rev;
 	struct setup_revision_opt opt;
 
+	init_grep_defaults();
 	git_config(git_log_config, NULL);
 
 	init_revisions(&rev, prefix);
@@ -450,6 +452,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
 	struct pathspec match_all;
 	int i, count, ret = 0;
 
+	init_grep_defaults();
 	git_config(git_log_config, NULL);
 
 	init_pathspec(&match_all, NULL);
@@ -530,6 +533,7 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix)
 	struct rev_info rev;
 	struct setup_revision_opt opt;
 
+	init_grep_defaults();
 	git_config(git_log_config, NULL);
 
 	init_revisions(&rev, prefix);
@@ -552,6 +556,7 @@ int cmd_log(int argc, const char **argv, const char *prefix)
 	struct rev_info rev;
 	struct setup_revision_opt opt;
 
+	init_grep_defaults();
 	git_config(git_log_config, NULL);
 
 	init_revisions(&rev, prefix);
@@ -1121,6 +1126,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 	extra_hdr.strdup_strings = 1;
 	extra_to.strdup_strings = 1;
 	extra_cc.strdup_strings = 1;
+	init_grep_defaults();
 	git_config(git_format_config, NULL);
 	init_revisions(&rev, prefix);
 	rev.commit_format = CMIT_FMT_EMAIL;
-- 
1.8.0.rc1.76.g5a375e6

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/7] Tying loose ends on grep-pcre
  2012-10-10  7:55 [PATCH v2 0/7] Tying loose ends on grep-pcre Junio C Hamano
                   ` (6 preceding siblings ...)
  2012-10-10  7:55 ` [PATCH v2 7/7] log: honor grep.* configuration Junio C Hamano
@ 2012-10-10 15:17 ` Michael Haggerty
  2012-10-10 16:52   ` Junio C Hamano
  7 siblings, 1 reply; 11+ messages in thread
From: Michael Haggerty @ 2012-10-10 15:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On 10/10/2012 09:55 AM, Junio C Hamano wrote:
> It took longer than expected, but here is a reroll of the previous
> series to bring more recent "git grep" enhancements to the "--grep"
> option of commands in "git log" family.
> 
> The early part of the series (1-3) refactors the code that reads
> configuration items related to "grep" and the code that mixes the
> result with the command line options to prepare grep_opt, which so
> far lived in builtin/grep.c, and moves them to the grep.[ch] at the
> top-level.
> 
> The middle part (4-6) reuses the code to set-up grep_opt refactored
> by the earlier part of the series on revs->grep_filter that is used
> in "git log --grep=..." processing.  It incidentally fixes a small
> bug where "git log -F -E --grep='<ere>'" did not look for matches to
> the pattern in extended regular expression, and adds --basic-regexp
> and --perl-regexp command line options to "git log" family for
> completeness.
> 
> The last one teaches "git log" family to honor the "grep.*"
> configuration variables, e.g. "grep.patterntype", so that you can
> say "git -c grep.patterntype=perl log --grep='(?:pcre)'".

Maybe this has been discussed already, but it seems to me that adding a
persistent setting that affects how "git log --grep" interprets the
pattern argument could break some scripts that assume that the "old"
interpretation is always used.  Shouldn't this at least be documented as
a backwards incompatibility?

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/7] Tying loose ends on grep-pcre
  2012-10-10 15:17 ` [PATCH v2 0/7] Tying loose ends on grep-pcre Michael Haggerty
@ 2012-10-10 16:52   ` Junio C Hamano
  2012-10-11  7:08     ` Michael Haggerty
  0 siblings, 1 reply; 11+ messages in thread
From: Junio C Hamano @ 2012-10-10 16:52 UTC (permalink / raw)
  To: Michael Haggerty; +Cc: git

Michael Haggerty <mhagger@alum.mit.edu> writes:

>> The last one teaches "git log" family to honor the "grep.*"
>> configuration variables, e.g. "grep.patterntype", so that you can
>> say "git -c grep.patterntype=perl log --grep='(?:pcre)'".
>
> Maybe this has been discussed already, but it seems to me that adding a
> persistent setting that affects how "git log --grep" interprets the
> pattern argument could break some scripts that assume that the "old"
> interpretation is always used.  Shouldn't this at least be documented as
> a backwards incompatibility?

If somebody scripts around "log" with hardcoded query "--grep=..."
strings, they can force a particular variant from such a command
line at the same time.  But as always, responsibility of doing so is
on the person who writes such a script; "log" being a Porcelain, we
value ease-of-use in interactive case more than cast-in-stone
interface stability like we do for plumbing commands.

And that is exactly why the series avoids changing the behaviour for
the "rev-list" plumbing.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/7] Tying loose ends on grep-pcre
  2012-10-10 16:52   ` Junio C Hamano
@ 2012-10-11  7:08     ` Michael Haggerty
  0 siblings, 0 replies; 11+ messages in thread
From: Michael Haggerty @ 2012-10-11  7:08 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On 10/10/2012 06:52 PM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>>> The last one teaches "git log" family to honor the "grep.*"
>>> configuration variables, e.g. "grep.patterntype", so that you can
>>> say "git -c grep.patterntype=perl log --grep='(?:pcre)'".
>>
>> Maybe this has been discussed already, but it seems to me that adding a
>> persistent setting that affects how "git log --grep" interprets the
>> pattern argument could break some scripts that assume that the "old"
>> interpretation is always used.  Shouldn't this at least be documented as
>> a backwards incompatibility?
> 
> If somebody scripts around "log" with hardcoded query "--grep=..."
> strings, they can force a particular variant from such a command
> line at the same time.  But as always, responsibility of doing so is
> on the person who writes such a script; "log" being a Porcelain, we
> value ease-of-use in interactive case more than cast-in-stone
> interface stability like we do for plumbing commands.
> 
> And that is exactly why the series avoids changing the behaviour for
> the "rev-list" plumbing.

OK, you've convinced me.  Thanks.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2012-10-11  7:08 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-10  7:55 [PATCH v2 0/7] Tying loose ends on grep-pcre Junio C Hamano
2012-10-10  7:55 ` [PATCH v2 1/7] builtin/grep.c: make configuration callback more reusable Junio C Hamano
2012-10-10  7:55 ` [PATCH v2 2/7] grep: move the configuration parsing logic to grep.[ch] Junio C Hamano
2012-10-10  7:55 ` [PATCH v2 3/7] grep: move pattern-type bits support to top-level grep.[ch] Junio C Hamano
2012-10-10  7:55 ` [PATCH v2 4/7] revisions: initialize revs->grep_filter using grep_init() Junio C Hamano
2012-10-10  7:55 ` [PATCH v2 5/7] log --grep: use the same helper to set -E/-F options as "git grep" Junio C Hamano
2012-10-10  7:55 ` [PATCH v2 6/7] log --grep: accept --basic-regexp and --perl-regexp Junio C Hamano
2012-10-10  7:55 ` [PATCH v2 7/7] log: honor grep.* configuration Junio C Hamano
2012-10-10 15:17 ` [PATCH v2 0/7] Tying loose ends on grep-pcre Michael Haggerty
2012-10-10 16:52   ` Junio C Hamano
2012-10-11  7:08     ` Michael Haggerty

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.