Skip to content

Commit 4607a8c

Browse files
committed
Merge branch 'jc/grep-pcre-loose-ends' (early part) into maint
"git log -F -E --grep='<ere>'" failed to use the given <ere> pattern as extended regular expression, and instead looked for the string literally. * 'jc/grep-pcre-loose-ends' (early part): 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
2 parents 6c95f53 + 34a4ae5 commit 4607a8c

File tree

5 files changed

+204
-128
lines changed

5 files changed

+204
-128
lines changed

builtin/grep.c

Lines changed: 9 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -261,103 +261,12 @@ static int wait_all(void)
261261
}
262262
#endif
263263

264-
static int parse_pattern_type_arg(const char *opt, const char *arg)
264+
static int grep_cmd_config(const char *var, const char *value, void *cb)
265265
{
266-
if (!strcmp(arg, "default"))
267-
return GREP_PATTERN_TYPE_UNSPECIFIED;
268-
else if (!strcmp(arg, "basic"))
269-
return GREP_PATTERN_TYPE_BRE;
270-
else if (!strcmp(arg, "extended"))
271-
return GREP_PATTERN_TYPE_ERE;
272-
else if (!strcmp(arg, "fixed"))
273-
return GREP_PATTERN_TYPE_FIXED;
274-
else if (!strcmp(arg, "perl"))
275-
return GREP_PATTERN_TYPE_PCRE;
276-
die("bad %s argument: %s", opt, arg);
277-
}
278-
279-
static void grep_pattern_type_options(const int pattern_type, struct grep_opt *opt)
280-
{
281-
switch (pattern_type) {
282-
case GREP_PATTERN_TYPE_UNSPECIFIED:
283-
/* fall through */
284-
285-
case GREP_PATTERN_TYPE_BRE:
286-
opt->fixed = 0;
287-
opt->pcre = 0;
288-
opt->regflags &= ~REG_EXTENDED;
289-
break;
290-
291-
case GREP_PATTERN_TYPE_ERE:
292-
opt->fixed = 0;
293-
opt->pcre = 0;
294-
opt->regflags |= REG_EXTENDED;
295-
break;
296-
297-
case GREP_PATTERN_TYPE_FIXED:
298-
opt->fixed = 1;
299-
opt->pcre = 0;
300-
opt->regflags &= ~REG_EXTENDED;
301-
break;
302-
303-
case GREP_PATTERN_TYPE_PCRE:
304-
opt->fixed = 0;
305-
opt->pcre = 1;
306-
opt->regflags &= ~REG_EXTENDED;
307-
break;
308-
}
309-
}
310-
311-
static int grep_config(const char *var, const char *value, void *cb)
312-
{
313-
struct grep_opt *opt = cb;
314-
char *color = NULL;
315-
316-
if (userdiff_config(var, value) < 0)
317-
return -1;
318-
319-
if (!strcmp(var, "grep.extendedregexp")) {
320-
if (git_config_bool(var, value))
321-
opt->extended_regexp_option = 1;
322-
else
323-
opt->extended_regexp_option = 0;
324-
return 0;
325-
}
326-
327-
if (!strcmp(var, "grep.patterntype")) {
328-
opt->pattern_type_option = parse_pattern_type_arg(var, value);
329-
return 0;
330-
}
331-
332-
if (!strcmp(var, "grep.linenumber")) {
333-
opt->linenum = git_config_bool(var, value);
334-
return 0;
335-
}
336-
337-
if (!strcmp(var, "color.grep"))
338-
opt->color = git_config_colorbool(var, value);
339-
else if (!strcmp(var, "color.grep.context"))
340-
color = opt->color_context;
341-
else if (!strcmp(var, "color.grep.filename"))
342-
color = opt->color_filename;
343-
else if (!strcmp(var, "color.grep.function"))
344-
color = opt->color_function;
345-
else if (!strcmp(var, "color.grep.linenumber"))
346-
color = opt->color_lineno;
347-
else if (!strcmp(var, "color.grep.match"))
348-
color = opt->color_match;
349-
else if (!strcmp(var, "color.grep.selected"))
350-
color = opt->color_selected;
351-
else if (!strcmp(var, "color.grep.separator"))
352-
color = opt->color_sep;
353-
else
354-
return git_color_default_config(var, value, cb);
355-
if (color) {
356-
if (!value)
357-
return config_error_nonbool(var);
358-
color_parse(value, var, color);
359-
}
360-
return 0;
266+
int st = grep_config(var, value, cb);
267+
if (git_color_default_config(var, value, cb) < 0)
268+
st = -1;
269+
return st;
361270
}
362271

363272
static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
@@ -839,27 +748,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
839748
if (argc == 2 && !strcmp(argv[1], "-h"))
840749
usage_with_options(grep_usage, options);
841750

842-
memset(&opt, 0, sizeof(opt));
843-
opt.prefix = prefix;
844-
opt.prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
845-
opt.relative = 1;
846-
opt.pathname = 1;
847-
opt.pattern_tail = &opt.pattern_list;
848-
opt.header_tail = &opt.header_list;
849-
opt.regflags = REG_NEWLINE;
850-
opt.max_depth = -1;
851-
opt.pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
852-
opt.extended_regexp_option = 0;
853-
854-
strcpy(opt.color_context, "");
855-
strcpy(opt.color_filename, "");
856-
strcpy(opt.color_function, "");
857-
strcpy(opt.color_lineno, "");
858-
strcpy(opt.color_match, GIT_COLOR_BOLD_RED);
859-
strcpy(opt.color_selected, "");
860-
strcpy(opt.color_sep, GIT_COLOR_CYAN);
861-
opt.color = -1;
862-
git_config(grep_config, &opt);
751+
init_grep_defaults();
752+
git_config(grep_cmd_config, NULL);
753+
grep_init(&opt, prefix);
863754

864755
/*
865756
* If there is no -- then the paths must exist in the working
@@ -875,13 +766,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
875766
PARSE_OPT_KEEP_DASHDASH |
876767
PARSE_OPT_STOP_AT_NON_OPTION |
877768
PARSE_OPT_NO_INTERNAL_HELP);
878-
879-
if (pattern_type_arg != GREP_PATTERN_TYPE_UNSPECIFIED)
880-
grep_pattern_type_options(pattern_type_arg, &opt);
881-
else if (opt.pattern_type_option != GREP_PATTERN_TYPE_UNSPECIFIED)
882-
grep_pattern_type_options(opt.pattern_type_option, &opt);
883-
else if (opt.extended_regexp_option)
884-
grep_pattern_type_options(GREP_PATTERN_TYPE_ERE, &opt);
769+
grep_commit_pattern_type(pattern_type_arg, &opt);
885770

886771
if (use_index && !startup_info->have_repository)
887772
/* die the same way as if we did it at the beginning */

grep.c

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,183 @@
66
static int grep_source_load(struct grep_source *gs);
77
static int grep_source_is_binary(struct grep_source *gs);
88

9+
static struct grep_opt grep_defaults;
10+
11+
/*
12+
* Initialize the grep_defaults template with hardcoded defaults.
13+
* We could let the compiler do this, but without C99 initializers
14+
* the code gets unwieldy and unreadable, so...
15+
*/
16+
void init_grep_defaults(void)
17+
{
18+
struct grep_opt *opt = &grep_defaults;
19+
static int run_once;
20+
21+
if (run_once)
22+
return;
23+
run_once++;
24+
25+
memset(opt, 0, sizeof(*opt));
26+
opt->relative = 1;
27+
opt->pathname = 1;
28+
opt->regflags = REG_NEWLINE;
29+
opt->max_depth = -1;
30+
opt->pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
31+
opt->extended_regexp_option = 0;
32+
strcpy(opt->color_context, "");
33+
strcpy(opt->color_filename, "");
34+
strcpy(opt->color_function, "");
35+
strcpy(opt->color_lineno, "");
36+
strcpy(opt->color_match, GIT_COLOR_BOLD_RED);
37+
strcpy(opt->color_selected, "");
38+
strcpy(opt->color_sep, GIT_COLOR_CYAN);
39+
opt->color = -1;
40+
}
41+
42+
static int parse_pattern_type_arg(const char *opt, const char *arg)
43+
{
44+
if (!strcmp(arg, "default"))
45+
return GREP_PATTERN_TYPE_UNSPECIFIED;
46+
else if (!strcmp(arg, "basic"))
47+
return GREP_PATTERN_TYPE_BRE;
48+
else if (!strcmp(arg, "extended"))
49+
return GREP_PATTERN_TYPE_ERE;
50+
else if (!strcmp(arg, "fixed"))
51+
return GREP_PATTERN_TYPE_FIXED;
52+
else if (!strcmp(arg, "perl"))
53+
return GREP_PATTERN_TYPE_PCRE;
54+
die("bad %s argument: %s", opt, arg);
55+
}
56+
57+
/*
58+
* Read the configuration file once and store it in
59+
* the grep_defaults template.
60+
*/
61+
int grep_config(const char *var, const char *value, void *cb)
62+
{
63+
struct grep_opt *opt = &grep_defaults;
64+
char *color = NULL;
65+
66+
if (userdiff_config(var, value) < 0)
67+
return -1;
68+
69+
if (!strcmp(var, "grep.extendedregexp")) {
70+
if (git_config_bool(var, value))
71+
opt->extended_regexp_option = 1;
72+
else
73+
opt->extended_regexp_option = 0;
74+
return 0;
75+
}
76+
77+
if (!strcmp(var, "grep.patterntype")) {
78+
opt->pattern_type_option = parse_pattern_type_arg(var, value);
79+
return 0;
80+
}
81+
82+
if (!strcmp(var, "grep.linenumber")) {
83+
opt->linenum = git_config_bool(var, value);
84+
return 0;
85+
}
86+
87+
if (!strcmp(var, "color.grep"))
88+
opt->color = git_config_colorbool(var, value);
89+
else if (!strcmp(var, "color.grep.context"))
90+
color = opt->color_context;
91+
else if (!strcmp(var, "color.grep.filename"))
92+
color = opt->color_filename;
93+
else if (!strcmp(var, "color.grep.function"))
94+
color = opt->color_function;
95+
else if (!strcmp(var, "color.grep.linenumber"))
96+
color = opt->color_lineno;
97+
else if (!strcmp(var, "color.grep.match"))
98+
color = opt->color_match;
99+
else if (!strcmp(var, "color.grep.selected"))
100+
color = opt->color_selected;
101+
else if (!strcmp(var, "color.grep.separator"))
102+
color = opt->color_sep;
103+
104+
if (color) {
105+
if (!value)
106+
return config_error_nonbool(var);
107+
color_parse(value, var, color);
108+
}
109+
return 0;
110+
}
111+
112+
/*
113+
* Initialize one instance of grep_opt and copy the
114+
* default values from the template we read the configuration
115+
* information in an earlier call to git_config(grep_config).
116+
*/
117+
void grep_init(struct grep_opt *opt, const char *prefix)
118+
{
119+
struct grep_opt *def = &grep_defaults;
120+
121+
memset(opt, 0, sizeof(*opt));
122+
opt->prefix = prefix;
123+
opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
124+
opt->pattern_tail = &opt->pattern_list;
125+
opt->header_tail = &opt->header_list;
126+
127+
opt->color = def->color;
128+
opt->extended_regexp_option = def->extended_regexp_option;
129+
opt->pattern_type_option = def->pattern_type_option;
130+
opt->linenum = def->linenum;
131+
opt->max_depth = def->max_depth;
132+
opt->pathname = def->pathname;
133+
opt->regflags = def->regflags;
134+
opt->relative = def->relative;
135+
136+
strcpy(opt->color_context, def->color_context);
137+
strcpy(opt->color_filename, def->color_filename);
138+
strcpy(opt->color_function, def->color_function);
139+
strcpy(opt->color_lineno, def->color_lineno);
140+
strcpy(opt->color_match, def->color_match);
141+
strcpy(opt->color_selected, def->color_selected);
142+
strcpy(opt->color_sep, def->color_sep);
143+
}
144+
145+
void grep_commit_pattern_type(enum grep_pattern_type pattern_type, struct grep_opt *opt)
146+
{
147+
if (pattern_type != GREP_PATTERN_TYPE_UNSPECIFIED)
148+
grep_set_pattern_type_option(pattern_type, opt);
149+
else if (opt->pattern_type_option != GREP_PATTERN_TYPE_UNSPECIFIED)
150+
grep_set_pattern_type_option(opt->pattern_type_option, opt);
151+
else if (opt->extended_regexp_option)
152+
grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, opt);
153+
}
154+
155+
void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt)
156+
{
157+
switch (pattern_type) {
158+
case GREP_PATTERN_TYPE_UNSPECIFIED:
159+
/* fall through */
160+
161+
case GREP_PATTERN_TYPE_BRE:
162+
opt->fixed = 0;
163+
opt->pcre = 0;
164+
opt->regflags &= ~REG_EXTENDED;
165+
break;
166+
167+
case GREP_PATTERN_TYPE_ERE:
168+
opt->fixed = 0;
169+
opt->pcre = 0;
170+
opt->regflags |= REG_EXTENDED;
171+
break;
172+
173+
case GREP_PATTERN_TYPE_FIXED:
174+
opt->fixed = 1;
175+
opt->pcre = 0;
176+
opt->regflags &= ~REG_EXTENDED;
177+
break;
178+
179+
case GREP_PATTERN_TYPE_PCRE:
180+
opt->fixed = 0;
181+
opt->pcre = 1;
182+
opt->regflags &= ~REG_EXTENDED;
183+
break;
184+
}
185+
}
9186

10187
static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
11188
const char *origin, int no,

grep.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ struct grep_opt {
138138
void *output_priv;
139139
};
140140

141+
extern void init_grep_defaults(void);
142+
extern int grep_config(const char *var, const char *value, void *);
143+
extern void grep_init(struct grep_opt *, const char *prefix);
144+
void grep_set_pattern_type_option(enum grep_pattern_type, struct grep_opt *opt);
145+
void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt);
146+
141147
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);
142148
extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
143149
extern void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *);

revision.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,9 +1048,9 @@ void init_revisions(struct rev_info *revs, const char *prefix)
10481048

10491049
revs->commit_format = CMIT_FMT_DEFAULT;
10501050

1051+
init_grep_defaults();
1052+
grep_init(&revs->grep_filter, prefix);
10511053
revs->grep_filter.status_only = 1;
1052-
revs->grep_filter.pattern_tail = &(revs->grep_filter.pattern_list);
1053-
revs->grep_filter.header_tail = &(revs->grep_filter.header_list);
10541054
revs->grep_filter.regflags = REG_NEWLINE;
10551055

10561056
diff_setup(&revs->diffopt);
@@ -1604,12 +1604,12 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
16041604
} else if (!strcmp(arg, "--grep-debug")) {
16051605
revs->grep_filter.debug = 1;
16061606
} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
1607-
revs->grep_filter.regflags |= REG_EXTENDED;
1607+
grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, &revs->grep_filter);
16081608
} else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
16091609
revs->grep_filter.regflags |= REG_ICASE;
16101610
DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE);
16111611
} else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
1612-
revs->grep_filter.fixed = 1;
1612+
grep_set_pattern_type_option(GREP_PATTERN_TYPE_FIXED, &revs->grep_filter);
16131613
} else if (!strcmp(arg, "--all-match")) {
16141614
revs->grep_filter.all_match = 1;
16151615
} else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
@@ -1893,6 +1893,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
18931893
revs->diffopt.abbrev = revs->abbrev;
18941894
diff_setup_done(&revs->diffopt);
18951895

1896+
grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED,
1897+
&revs->grep_filter);
18961898
compile_grep_patterns(&revs->grep_filter);
18971899

18981900
if (revs->reverse && revs->reflog_info)

0 commit comments

Comments
 (0)