]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
include/optutils: improve err_exclusive_options() output
authorKarel Zak <kzak@redhat.com>
Mon, 3 Nov 2025 12:41:31 +0000 (13:41 +0100)
committerKarel Zak <kzak@redhat.com>
Fri, 7 Nov 2025 10:10:34 +0000 (11:10 +0100)
OLD:
$ losetup --remove --detach loop0
losetup: mutually exclusive arguments: --detach-all --all --set-capacity --detach --find --associated --remove
NEW:
$ losetup --remove --detach loop0
losetup: options --detach and --remove cannot be combined.

Suggested-by: Benno Schulenberg <bensberg@telfort.nl>
Signed-off-by: Karel Zak <kzak@redhat.com>
include/optutils.h

index 6fe4aeb7a51dad96d415d04cc73b7fa24cef5e16..87d20d0d5334f51fc3a61127fcccbf1847a91998 100644 (file)
 #include "nls.h"
 #include "cctype.h"
 
-static inline const char *option_to_longopt(int c, const struct option *opts)
+/*
+ * Converts the short option @c to the corresponding long option from @opts, or
+ * returns NULL.
+ */
+static inline const char *ul_get_longopt(const struct option *opts, int c)
 {
        const struct option *o;
 
@@ -22,6 +26,19 @@ static inline const char *option_to_longopt(int c, const struct option *opts)
        return NULL;
 }
 
+/*
+ * Converts the short options @c to "%c" or "0x<hex>" if not printable.
+ */
+static inline const char *ul_get_shortopt(char *buf, size_t bufsz, int c)
+{
+       if (c_isgraph(c))
+               snprintf(buf, bufsz, "%c", c);
+       else
+               snprintf(buf, bufsz, "<0x%02x>", c);    /* should not happen */
+
+       return buf;
+}
+
 #ifndef OPTUTILS_EXIT_CODE
 # define OPTUTILS_EXIT_CODE EXIT_FAILURE
 #endif
@@ -84,23 +101,16 @@ static inline void err_exclusive_options(
                        if (status[e] == 0)
                                status[e] = c;
                        else if (status[e] != c) {
-                               size_t ct = 0;
+                               const char *a = ul_get_longopt(opts, status[e]);
+                               const char *b = ul_get_longopt(opts, c);
+                               char buf[16];   /* short option in hex */
 
-                               fprintf(stderr, _("%s: mutually exclusive "
-                                                 "arguments:"),
-                                               program_invocation_short_name);
-
-                               for (op = excl[e];
-                                    ct + 1 < ARRAY_SIZE(excl[0]) && *op;
-                                    op++, ct++) {
-                                       const char *n = option_to_longopt(*op, opts);
-                                       if (n)
-                                               fprintf(stderr, " --%s", n);
-                                       else if (c_isgraph(*op))
-                                               fprintf(stderr, " -%c", *op);
-                               }
-                               fputc('\n', stderr);
-                               exit(OPTUTILS_EXIT_CODE);
+                               errx(OPTUTILS_EXIT_CODE,
+                                       _("options %s%s and %s%s cannot be combined"),
+                                       a ? "--" : "-",
+                                       a ? a : ul_get_shortopt(buf, sizeof(buf), status[e]),
+                                       b ? "--" : "-",
+                                       b ? b : ul_get_shortopt(buf, sizeof(buf), c));
                        }
                        break;
                }
@@ -108,4 +118,3 @@ static inline void err_exclusive_options(
 }
 
 #endif
-