Skip to content

Commit 15fabd1

Browse files
committed
builtin/grep.c: make configuration callback more reusable
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>
1 parent f84667d commit 15fabd1

File tree

1 file changed

+79
-25
lines changed

1 file changed

+79
-25
lines changed

builtin/grep.c

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,41 @@ static void grep_pattern_type_options(const int pattern_type, struct grep_opt *o
308308
}
309309
}
310310

311+
static struct grep_opt grep_defaults;
312+
313+
/*
314+
* Initialize the grep_defaults template with hardcoded defaults.
315+
* We could let the compiler do this, but without C99 initializers
316+
* the code gets unwieldy and unreadable, so...
317+
*/
318+
static void init_grep_defaults(void)
319+
{
320+
struct grep_opt *opt = &grep_defaults;
321+
322+
memset(opt, 0, sizeof(*opt));
323+
opt->relative = 1;
324+
opt->pathname = 1;
325+
opt->regflags = REG_NEWLINE;
326+
opt->max_depth = -1;
327+
opt->pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
328+
opt->extended_regexp_option = 0;
329+
strcpy(opt->color_context, "");
330+
strcpy(opt->color_filename, "");
331+
strcpy(opt->color_function, "");
332+
strcpy(opt->color_lineno, "");
333+
strcpy(opt->color_match, GIT_COLOR_BOLD_RED);
334+
strcpy(opt->color_selected, "");
335+
strcpy(opt->color_sep, GIT_COLOR_CYAN);
336+
opt->color = -1;
337+
}
338+
339+
/*
340+
* Read the configuration file once and store it in
341+
* the grep_defaults template.
342+
*/
311343
static int grep_config(const char *var, const char *value, void *cb)
312344
{
313-
struct grep_opt *opt = cb;
345+
struct grep_opt *opt = &grep_defaults;
314346
char *color = NULL;
315347

316348
if (userdiff_config(var, value) < 0)
@@ -327,7 +359,7 @@ static int grep_config(const char *var, const char *value, void *cb)
327359
if (!strcmp(var, "grep.patterntype")) {
328360
opt->pattern_type_option = parse_pattern_type_arg(var, value);
329361
return 0;
330-
}
362+
}
331363

332364
if (!strcmp(var, "grep.linenumber")) {
333365
opt->linenum = git_config_bool(var, value);
@@ -350,8 +382,7 @@ static int grep_config(const char *var, const char *value, void *cb)
350382
color = opt->color_selected;
351383
else if (!strcmp(var, "color.grep.separator"))
352384
color = opt->color_sep;
353-
else
354-
return git_color_default_config(var, value, cb);
385+
355386
if (color) {
356387
if (!value)
357388
return config_error_nonbool(var);
@@ -360,6 +391,47 @@ static int grep_config(const char *var, const char *value, void *cb)
360391
return 0;
361392
}
362393

394+
/*
395+
* Initialize one instance of grep_opt and copy the
396+
* default values from the template we read the configuration
397+
* information in an earlier call to git_config(grep_config).
398+
*/
399+
static void grep_init(struct grep_opt *opt, const char *prefix)
400+
{
401+
struct grep_opt *def = &grep_defaults;
402+
403+
memset(opt, 0, sizeof(*opt));
404+
opt->prefix = prefix;
405+
opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
406+
opt->pattern_tail = &opt->pattern_list;
407+
opt->header_tail = &opt->header_list;
408+
409+
opt->color = def->color;
410+
opt->extended_regexp_option = def->extended_regexp_option;
411+
opt->pattern_type_option = def->pattern_type_option;
412+
opt->linenum = def->linenum;
413+
opt->max_depth = def->max_depth;
414+
opt->pathname = def->pathname;
415+
opt->regflags = def->regflags;
416+
opt->relative = def->relative;
417+
418+
strcpy(opt->color_context, def->color_context);
419+
strcpy(opt->color_filename, def->color_filename);
420+
strcpy(opt->color_function, def->color_function);
421+
strcpy(opt->color_lineno, def->color_lineno);
422+
strcpy(opt->color_match, def->color_match);
423+
strcpy(opt->color_selected, def->color_selected);
424+
strcpy(opt->color_sep, def->color_sep);
425+
}
426+
427+
static int grep_cmd_config(const char *var, const char *value, void *cb)
428+
{
429+
int st = grep_config(var, value, cb);
430+
if (git_color_default_config(var, value, cb) < 0)
431+
st = -1;
432+
return st;
433+
}
434+
363435
static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
364436
{
365437
void *data;
@@ -839,27 +911,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
839911
if (argc == 2 && !strcmp(argv[1], "-h"))
840912
usage_with_options(grep_usage, options);
841913

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);
914+
init_grep_defaults();
915+
git_config(grep_cmd_config, NULL);
916+
grep_init(&opt, prefix);
863917

864918
/*
865919
* If there is no -- then the paths must exist in the working

0 commit comments

Comments
 (0)