Merge branch 'ab/grep-patterntype'
Some code clean-up in the "git grep" machinery. * ab/grep-patterntype: grep: simplify config parsing and option parsing grep.c: do "if (bool && memchr())" not "if (memchr() && bool)" grep.h: make "grep_opt.pattern_type_option" use its enum grep API: call grep_config() after grep_init() grep.c: don't pass along NULL callback value built-ins: trust the "prefix" from run_builtin() grep tests: add missing "grep.patternType" config tests grep tests: create a helper function for "BRE" or "ERE" log tests: check if grep_config() is called by "log"-like cmds grep.h: remove unused "regex_t regexp" from grep_opt
This commit is contained in:
113
grep.c
113
grep.c
@ -19,27 +19,6 @@ static void std_output(struct grep_opt *opt, const void *buf, size_t size)
|
||||
fwrite(buf, size, 1, stdout);
|
||||
}
|
||||
|
||||
static struct grep_opt grep_defaults = {
|
||||
.relative = 1,
|
||||
.pathname = 1,
|
||||
.max_depth = -1,
|
||||
.pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED,
|
||||
.colors = {
|
||||
[GREP_COLOR_CONTEXT] = "",
|
||||
[GREP_COLOR_FILENAME] = GIT_COLOR_MAGENTA,
|
||||
[GREP_COLOR_FUNCTION] = "",
|
||||
[GREP_COLOR_LINENO] = GIT_COLOR_GREEN,
|
||||
[GREP_COLOR_COLUMNNO] = GIT_COLOR_GREEN,
|
||||
[GREP_COLOR_MATCH_CONTEXT] = GIT_COLOR_BOLD_RED,
|
||||
[GREP_COLOR_MATCH_SELECTED] = GIT_COLOR_BOLD_RED,
|
||||
[GREP_COLOR_SELECTED] = "",
|
||||
[GREP_COLOR_SEP] = GIT_COLOR_CYAN,
|
||||
},
|
||||
.only_matching = 0,
|
||||
.color = -1,
|
||||
.output = std_output,
|
||||
};
|
||||
|
||||
static const char *color_grep_slots[] = {
|
||||
[GREP_COLOR_CONTEXT] = "context",
|
||||
[GREP_COLOR_FILENAME] = "filename",
|
||||
@ -75,20 +54,12 @@ define_list_config_array_extra(color_grep_slots, {"match"});
|
||||
*/
|
||||
int grep_config(const char *var, const char *value, void *cb)
|
||||
{
|
||||
struct grep_opt *opt = &grep_defaults;
|
||||
struct grep_opt *opt = cb;
|
||||
const char *slot;
|
||||
|
||||
if (userdiff_config(var, value) < 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* The instance of grep_opt that we set up here is copied by
|
||||
* grep_init() to be used by each individual invocation.
|
||||
* When populating a new field of this structure here, be
|
||||
* sure to think about ownership -- e.g., you might need to
|
||||
* override the shallow copy in grep_init() with a deep copy.
|
||||
*/
|
||||
|
||||
if (!strcmp(var, "grep.extendedregexp")) {
|
||||
opt->extended_regexp_option = git_config_bool(var, value);
|
||||
return 0;
|
||||
@ -134,78 +105,16 @@ 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).
|
||||
*/
|
||||
void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix)
|
||||
void grep_init(struct grep_opt *opt, struct repository *repo)
|
||||
{
|
||||
*opt = grep_defaults;
|
||||
struct grep_opt blank = GREP_OPT_INIT;
|
||||
memcpy(opt, &blank, sizeof(*opt));
|
||||
|
||||
opt->repo = repo;
|
||||
opt->prefix = prefix;
|
||||
opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
|
||||
opt->pattern_tail = &opt->pattern_list;
|
||||
opt->header_tail = &opt->header_list;
|
||||
}
|
||||
|
||||
static void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt)
|
||||
{
|
||||
/*
|
||||
* When committing to the pattern type by setting the relevant
|
||||
* fields in grep_opt it's generally not necessary to zero out
|
||||
* the fields we're not choosing, since they won't have been
|
||||
* set by anything. The extended_regexp_option field is the
|
||||
* only exception to this.
|
||||
*
|
||||
* This is because in the process of parsing grep.patternType
|
||||
* & grep.extendedRegexp we set opt->pattern_type_option and
|
||||
* opt->extended_regexp_option, respectively. We then
|
||||
* internally use opt->extended_regexp_option to see if we're
|
||||
* compiling an ERE. It must be unset if that's not actually
|
||||
* the case.
|
||||
*/
|
||||
if (pattern_type != GREP_PATTERN_TYPE_ERE &&
|
||||
opt->extended_regexp_option)
|
||||
opt->extended_regexp_option = 0;
|
||||
|
||||
switch (pattern_type) {
|
||||
case GREP_PATTERN_TYPE_UNSPECIFIED:
|
||||
/* fall through */
|
||||
|
||||
case GREP_PATTERN_TYPE_BRE:
|
||||
break;
|
||||
|
||||
case GREP_PATTERN_TYPE_ERE:
|
||||
opt->extended_regexp_option = 1;
|
||||
break;
|
||||
|
||||
case GREP_PATTERN_TYPE_FIXED:
|
||||
opt->fixed = 1;
|
||||
break;
|
||||
|
||||
case GREP_PATTERN_TYPE_PCRE:
|
||||
opt->pcre2 = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
/*
|
||||
* This branch *must* happen after setting from the
|
||||
* opt->pattern_type_option above, we don't want
|
||||
* grep.extendedRegexp to override grep.patternType!
|
||||
*/
|
||||
grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, opt);
|
||||
}
|
||||
|
||||
static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
|
||||
const char *origin, int no,
|
||||
enum grep_pat_token t,
|
||||
@ -523,11 +432,17 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
|
||||
int err;
|
||||
int regflags = REG_NEWLINE;
|
||||
|
||||
if (opt->pattern_type_option == GREP_PATTERN_TYPE_UNSPECIFIED)
|
||||
opt->pattern_type_option = (opt->extended_regexp_option
|
||||
? GREP_PATTERN_TYPE_ERE
|
||||
: GREP_PATTERN_TYPE_BRE);
|
||||
|
||||
p->word_regexp = opt->word_regexp;
|
||||
p->ignore_case = opt->ignore_case;
|
||||
p->fixed = opt->fixed;
|
||||
p->fixed = opt->pattern_type_option == GREP_PATTERN_TYPE_FIXED;
|
||||
|
||||
if (memchr(p->pattern, 0, p->patternlen) && !opt->pcre2)
|
||||
if (opt->pattern_type_option != GREP_PATTERN_TYPE_PCRE &&
|
||||
memchr(p->pattern, 0, p->patternlen))
|
||||
die(_("given pattern contains NULL byte (via -f <file>). This is only supported with -P under PCRE v2"));
|
||||
|
||||
p->is_fixed = is_fixed(p->pattern, p->patternlen);
|
||||
@ -578,14 +493,14 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
|
||||
return;
|
||||
}
|
||||
|
||||
if (opt->pcre2) {
|
||||
if (opt->pattern_type_option == GREP_PATTERN_TYPE_PCRE) {
|
||||
compile_pcre2_pattern(p, opt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->ignore_case)
|
||||
regflags |= REG_ICASE;
|
||||
if (opt->extended_regexp_option)
|
||||
if (opt->pattern_type_option == GREP_PATTERN_TYPE_ERE)
|
||||
regflags |= REG_EXTENDED;
|
||||
err = regcomp(&p->regexp, p->pattern, regflags);
|
||||
if (err) {
|
||||
|
||||
Reference in New Issue
Block a user