userdiff: add and use struct external_diff

Wrap the string specifying the external diff command in a new struct to simplify adding attributes, which the next patch will do. Make sure external_diff() still returns NULL if neither the environment variable GIT_EXTERNAL_DIFF nor the configuration option diff.external is set, to continue allowing its use in a boolean context. Use a designated initializer for the default builtin userdiff driver to adjust to the type change of the second struct member. Spelling out only the non-zero members improves readability as a nice side-effect. No functional change intended. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Jun 9, 2024 at 09:39 UTC 54443bbfc38d0252b31c821fea77320fcf0fe277
3 files changed +24 -18
diff.c
+17 -15
@@ -57,7 +57,7 @@ static int diff_color_moved_ws_default;
57 static int diff_context_default = 3;
58 static int diff_interhunk_context_default;
59 static char *diff_word_regex_cfg;
60 -static char *external_diff_cmd_cfg;
60 +static struct external_diff external_diff_cfg;
61 static char *diff_order_file_cfg;
62 int diff_auto_refresh_index = 1;
63 static int diff_mnemonic_prefix;
@@ -431,7 +431,7 @@ int git_diff_ui_config(const char *var, const char *value,
431 return 0;
432 }
433 if (!strcmp(var, "diff.external"))
434 - return git_config_string(&external_diff_cmd_cfg, var, value);
434 + return git_config_string(&external_diff_cfg.cmd, var, value);
435 if (!strcmp(var, "diff.wordregex"))
436 return git_config_string(&diff_word_regex_cfg, var, value);
437 if (!strcmp(var, "diff.orderfile"))
@@ -548,18 +548,20 @@ static char *quote_two(const char *one, const char *two)
548 return strbuf_detach(&res, NULL);
549 }
550
551 -static const char *external_diff(void)
551 +static const struct external_diff *external_diff(void)
552 {
553 - static const char *external_diff_cmd = NULL;
553 + static struct external_diff external_diff_env, *external_diff_ptr;
554 static int done_preparing = 0;
555
556 if (done_preparing)
557 - return external_diff_cmd;
558 - external_diff_cmd = xstrdup_or_null(getenv("GIT_EXTERNAL_DIFF"));
559 - if (!external_diff_cmd)
560 - external_diff_cmd = external_diff_cmd_cfg;
557 + return external_diff_ptr;
558 + external_diff_env.cmd = xstrdup_or_null(getenv("GIT_EXTERNAL_DIFF"));
559 + if (external_diff_env.cmd)
560 + external_diff_ptr = &external_diff_env;
561 + else if (external_diff_cfg.cmd)
562 + external_diff_ptr = &external_diff_cfg;
563 done_preparing = 1;
562 - return external_diff_cmd;
564 + return external_diff_ptr;
565 }
566
567 /*
@@ -4375,7 +4377,7 @@ static void add_external_diff_name(struct repository *r,
4377 * infile2 infile2-sha1 infile2-mode [ rename-to ]
4378 *
4379 */
4378 -static void run_external_diff(const char *pgm,
4380 +static void run_external_diff(const struct external_diff *pgm,
4381 const char *name,
4382 const char *other,
4383 struct diff_filespec *one,
@@ -4386,7 +4388,7 @@ static void run_external_diff(const char *pgm,
4388 struct child_process cmd = CHILD_PROCESS_INIT;
4389 struct diff_queue_struct *q = &diff_queued_diff;
4390
4389 - strvec_push(&cmd.args, pgm);
4391 + strvec_push(&cmd.args, pgm->cmd);
4392 strvec_push(&cmd.args, name);
4393
4394 if (one && two) {
@@ -4512,7 +4514,7 @@ static void fill_metainfo(struct strbuf *msg,
4514 }
4515 }
4516
4515 -static void run_diff_cmd(const char *pgm,
4517 +static void run_diff_cmd(const struct external_diff *pgm,
4518 const char *name,
4519 const char *other,
4520 const char *attr_path,
@@ -4530,8 +4532,8 @@ static void run_diff_cmd(const char *pgm,
4532 if (o->flags.allow_external || !o->ignore_driver_algorithm)
4533 drv = userdiff_find_by_path(o->repo->index, attr_path);
4534
4533 - if (o->flags.allow_external && drv && drv->external)
4534 - pgm = drv->external;
4535 + if (o->flags.allow_external && drv && drv->external.cmd)
4536 + pgm = &drv->external;
4537
4538 if (msg) {
4539 /*
@@ -4597,7 +4599,7 @@ static void strip_prefix(int prefix_length, const char **namep, const char **oth
4599
4600 static void run_diff(struct diff_filepair *p, struct diff_options *o)
4601 {
4600 - const char *pgm = external_diff();
4602 + const struct external_diff *pgm = external_diff();
4603 struct strbuf msg;
4604 struct diff_filespec *one = p->one;
4605 struct diff_filespec *two = p->two;
userdiff.c
+2 -2
@@ -333,7 +333,7 @@ PATTERNS("scheme",
333 "|([^][)(}{[ \t])+"),
334 PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$",
335 "\\\\[a-zA-Z@]+|\\\\.|([a-zA-Z0-9]|[^\x01-\x7f])+"),
336 -{ "default", NULL, NULL, -1, { NULL, 0 } },
336 +{ .name = "default", .binary = -1 },
337 };
338 #undef PATTERNS
339 #undef IPATTERN
@@ -445,7 +445,7 @@ int userdiff_config(const char *k, const char *v)
445 if (!strcmp(type, "binary"))
446 return parse_tristate(&drv->binary, k, v);
447 if (!strcmp(type, "command"))
448 - return git_config_string(&drv->external, k, v);
448 + return git_config_string(&drv->external.cmd, k, v);
449 if (!strcmp(type, "textconv"))
450 return git_config_string(&drv->textconv, k, v);
451 if (!strcmp(type, "cachetextconv"))
userdiff.h
+5 -1
@@ -11,9 +11,13 @@ struct userdiff_funcname {
11 int cflags;
12 };
13
14 +struct external_diff {
15 + char *cmd;
16 +};
17 +
18 struct userdiff_driver {
19 const char *name;
16 - char *external;
20 + struct external_diff external;
21 char *algorithm;
22 int binary;
23 struct userdiff_funcname funcname;