From: Junio C Hamano Date: Wed, 26 Aug 2026 23:31:52 GMT Subject: [PATCH 2/2] die_for_incompatible_opts(): accept more than four options Message-ID: <20260826233152.1703497-3-gitster@pobox.com> In-Reply-To: <20260826233152.1703497-1-gitster@pobox.com> Introduce die_for_incompatible_opts(), which takes an arbitrary and unbounded number of pairs and complains when two or more of these options are set at the same time. Reimplement die_for_incompatible_opt4() and others in terms of this function. To avoid allocation costs, the implementation reports only the first four mutually incompatible options used. This behavior is deliberate. If a set of ten options were mutually exclusive and a user specified seven of them at once, they would be told that the first four cannot be used together. If the user then tries the remaining three, the same error for the remaining three would be reported. It is dubious that there is any practical downside to not reporting all seven incompatible options at once, especially given that there are other three mutually incompatible options that the user will not be told about with this message anyway. Signed-off-by: Junio C Hamano --- parse-options.c | 26 ++++++++++++++------------ parse-options.h | 15 +++++++++++---- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/parse-options.c b/parse-options.c index b56bc7e419..163842837c 100644 --- a/parse-options.c +++ b/parse-options.c @@ -1535,26 +1535,28 @@ void NORETURN usage_msg_optf(const char * const fmt, usage_msg_opt(msg.buf, usagestr, options); } -void die_for_incompatible_opt4(const char *opt1_name, int opt1, - const char *opt2_name, int opt2, - const char *opt3_name, int opt3, - const char *opt4_name, int opt4) +void die_for_incompatible_opts(const char *opt1_name, int opt1, ...) { - int count = 0; + unsigned count = 0; const char *options[4]; + va_list ap; + + va_start(ap, opt1); if (opt1) options[count++] = opt1_name; - if (opt2) - options[count++] = opt2_name; - if (opt3) - options[count++] = opt3_name; - if (opt4) - options[count++] = opt4_name; + while (count < ARRAY_SIZE(options)) { + const char *name = va_arg(ap, const char *); + if (!name) + break; + if (va_arg(ap, int)) + options[count++] = name; + } + switch (count) { case 4: die(_("options '%s', '%s', '%s', and '%s' cannot be used together"), - opt1_name, opt2_name, opt3_name, opt4_name); + options[0], options[1], options[2], options[3]); break; case 3: die(_("options '%s', '%s', and '%s' cannot be used together"), diff --git a/parse-options.h b/parse-options.h index 888949ab61..79e4de9b32 100644 --- a/parse-options.h +++ b/parse-options.h @@ -441,11 +441,18 @@ void NORETURN usage_msg_optf(const char *fmt, const char * const *usagestr, const struct option *options, ...); -void die_for_incompatible_opt4(const char *opt1_name, int opt1, - const char *opt2_name, int opt2, - const char *opt3_name, int opt3, - const char *opt4_name, int opt4); +void die_for_incompatible_opts(const char *opt1_name, int opt1, ...); +static inline void die_for_incompatible_opt4(const char *opt1_name, int opt1, + const char *opt2_name, int opt2, + const char *opt3_name, int opt3, + const char *opt4_name, int opt4) +{ + die_for_incompatible_opts(opt1_name, opt1, + opt2_name, opt2, + opt3_name, opt3, + opt4_name, opt4, NULL); +} static inline void die_for_incompatible_opt3(const char *opt1_name, int opt1, const char *opt2_name, int opt2, -- 2.55.0-862-g3c6f97f7b9