@ -19,27 +19,6 @@ static void std_output(struct grep_opt *opt, const void *buf, size_t size)
fwrite(buf, size, 1, stdout);
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[] = {
static const char *color_grep_slots[] = {
[GREP_COLOR_CONTEXT] = "context",
[GREP_COLOR_CONTEXT] = "context",
[GREP_COLOR_FILENAME] = "filename",
[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)
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;
const char *slot;
if (userdiff_config(var, value) < 0)
if (userdiff_config(var, value) < 0)
return -1;
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")) {
if (!strcmp(var, "grep.extendedregexp")) {
opt->extended_regexp_option = git_config_bool(var, value);
opt->extended_regexp_option = git_config_bool(var, value);
return 0;
return 0;
@ -134,78 +105,16 @@ int grep_config(const char *var, const char *value, void *cb)
return 0;
return 0;
}
}
/*
void grep_init(struct grep_opt *opt, struct repository *repo)
* 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)
{
{
*opt = grep_defaults;
struct grep_opt blank = GREP_OPT_INIT;
memcpy(opt, &blank, sizeof(*opt));
opt->repo = repo;
opt->repo = repo;
opt->prefix = prefix;
opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
opt->pattern_tail = &opt->pattern_list;
opt->pattern_tail = &opt->pattern_list;
opt->header_tail = &opt->header_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,
static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
const char *origin, int no,
const char *origin, int no,
enum grep_pat_token t,
enum grep_pat_token t,
@ -523,11 +432,17 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
int err;
int err;
int regflags = REG_NEWLINE;
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->word_regexp = opt->word_regexp;
p->ignore_case = opt->ignore_case;
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"));
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);
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;
return;
}
}
if (opt->pcre2) {
if (opt->pattern_type_option == GREP_PATTERN_TYPE_PCRE) {
compile_pcre2_pattern(p, opt);
compile_pcre2_pattern(p, opt);
return;
return;
}
}
if (p->ignore_case)
if (p->ignore_case)
regflags |= REG_ICASE;
regflags |= REG_ICASE;
if (opt->extended_regexp_option)
if (opt->pattern_type_option == GREP_PATTERN_TYPE_ERE)
regflags |= REG_EXTENDED;
regflags |= REG_EXTENDED;
err = regcomp(&p->regexp, p->pattern, regflags);
err = regcomp(&p->regexp, p->pattern, regflags);
if (err) {
if (err) {