convert: refactor capabilities negotiation
The code to negotiate long running filter capabilities was very repetitive for new capabilities. Replace the repetitive conditional statements with a table-driven approach. This is useful for the subsequent patch 'convert: add "status=delayed" to filter process protocol'. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Lars Schneider <larsxschneider@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Lars Schneider committed
Jun 30, 2017 at 22:41 UTC
1514c8edd62d96006cd1de31e906ed5798dd4681
1 file changed
+27
-12
convert.c
+27
-12
@@ -507,7 +507,7 @@ static struct hashmap subprocess_map;
507
508
static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
509
{
510
- int err;
510
+ int err, i;
511
struct cmd2process *entry = (struct cmd2process *)subprocess;
512
struct string_list cap_list = STRING_LIST_INIT_NODUP;
513
char *cap_buf;
@@ -515,6 +515,14 @@ static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
515
struct child_process *process = &subprocess->process;
516
const char *cmd = subprocess->cmd;
517
518
+ static const struct {
519
+ const char *name;
520
+ unsigned int cap;
521
+ } known_caps[] = {
522
+ { "clean", CAP_CLEAN },
523
+ { "smudge", CAP_SMUDGE },
524
+ };
525
+
526
sigchain_push(SIGPIPE, SIG_IGN);
527
528
err = packet_writel(process->in, "git-filter-client", "version=2", NULL);
@@ -533,7 +541,15 @@ static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
541
if (err)
542
goto done;
543
536
- err = packet_writel(process->in, "capability=clean", "capability=smudge", NULL);
544
+ for (i = 0; i < ARRAY_SIZE(known_caps); ++i) {
545
+ err = packet_write_fmt_gently(
546
+ process->in, "capability=%s\n", known_caps[i].name);
547
+ if (err)
548
+ goto done;
549
+ }
550
+ err = packet_flush_gently(process->in);
551
+ if (err)
552
+ goto done;
553
554
for (;;) {
555
cap_buf = packet_read_line(process->out, NULL);
@@ -545,16 +561,15 @@ static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
561
continue;
562
563
cap_name = cap_list.items[1].string;
548
- if (!strcmp(cap_name, "clean")) {
549
- entry->supported_capabilities |= CAP_CLEAN;
550
- } else if (!strcmp(cap_name, "smudge")) {
551
- entry->supported_capabilities |= CAP_SMUDGE;
552
- } else {
553
- warning(
554
- "external filter '%s' requested unsupported filter capability '%s'",
555
- cmd, cap_name
556
- );
557
- }
564
+ i = ARRAY_SIZE(known_caps) - 1;
565
+ while (i >= 0 && strcmp(cap_name, known_caps[i].name))
566
+ i--;
567
+
568
+ if (i >= 0)
569
+ entry->supported_capabilities |= known_caps[i].cap;
570
+ else
571
+ warning("external filter '%s' requested unsupported filter capability '%s'",
572
+ cmd, cap_name);
573
574
string_list_clear(&cap_list, 0);
575
}