Skip to content

Commit

Permalink
Merge branch 'jc/grep-pcre-loose-ends'
Browse files Browse the repository at this point in the history
"git log -F -E --grep='<ere>'" failed to use the given <ere>
pattern as extended regular expression, and instead looked for the
string literally.  The early part of this series is a fix for it;
the latter part teaches log to respect the grep.* configuration.

* jc/grep-pcre-loose-ends:
  log: honor grep.* configuration
  log --grep: accept --basic-regexp and --perl-regexp
  log --grep: use the same helper to set -E/-F options as "git grep"
  revisions: initialize revs->grep_filter using grep_init()
  grep: move pattern-type bits support to top-level grep.[ch]
  grep: move the configuration parsing logic to grep.[ch]
  builtin/grep.c: make configuration callback more reusable
  • Loading branch information
Jeff King committed Oct 29, 2012
2 parents fdb4d27 + 0657bcb commit d2f4469
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 129 deletions.
10 changes: 10 additions & 0 deletions Documentation/rev-list-options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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::

Expand All @@ -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.
Expand Down
133 changes: 9 additions & 124 deletions builtin/grep.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,103 +261,12 @@ static int wait_all(void)
}
#endif

static int parse_pattern_type_arg(const char *opt, const char *arg)
static int grep_cmd_config(const char *var, const char *value, void *cb)
{
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) {
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_config(const char *var, const char *value, void *cb)
{
struct grep_opt *opt = cb;
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;
else
return git_color_default_config(var, value, cb);
if (color) {
if (!value)
return config_error_nonbool(var);
color_parse(value, var, color);
}
return 0;
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)
Expand Down Expand Up @@ -839,27 +748,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
Expand All @@ -875,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 */
Expand Down
8 changes: 7 additions & 1 deletion builtin/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit d2f4469

Please sign in to comment.