]> git.draconx.ca Git - dxcommon.git/commitdiff
help_print_optstring: Fix handling of 'flag' options.
authorNick Bowler <nbowler@draconx.ca>
Thu, 24 Feb 2022 01:47:55 +0000 (20:47 -0500)
committerNick Bowler <nbowler@draconx.ca>
Thu, 24 Feb 2022 01:47:55 +0000 (20:47 -0500)
When getopt_long options use the 'flag' feature, the 'val' member is
not meaningful as a short option.  So we shouldn't try to format it
as if there is a short option, as this leads to printing garbage.

src/help.c
t/helpopt.c
tests/functions.at

index ea817e84ae47e485bfd9425d50510782a5da5294..43bb266d4df4dc8c5dc17ed7519abd49d1bdb088 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2021 Nick Bowler
+ * Copyright © 2021-2022 Nick Bowler
  *
  * Helper functions for formatting --help program output.
  *
  */
 static int option_type(const struct option *opt)
 {
-       return ((opt->val <= CHAR_MAX) << 2) | (opt->has_arg & 3);
+       int ret = opt->has_arg & 3;
+
+       if (!opt->flag)
+               ret |= (opt->val <= CHAR_MAX) << 2;
+
+       return ret;
 }
 
 enum {
index 303e13ab8f8ed1f485d597905ff9a53c31480deb..51b08a7f1f8346eacaa59e613dee0e7b5f9006e7 100644 (file)
@@ -1,7 +1,33 @@
 /*
- * Read some text from standard input and format it with help_print_desc,
- * for testing.  Each pair of program arguments is converted to an int and
- * passed as the two integer arguments to help_print_desc.
+ * Copyright © 2021-2022 Nick Bowler
+ *
+ * Test helper application to verify help_print_optstring operation.
+ *
+ * Command-line arguments are collected to create the options to be formatted.
+ * There are six basic forms:
+ *
+ *   --long-option-only
+ *   --long-option-with-argument arg
+ *   --long-option-with-optional-argument [arg]
+ *   --short-option -s arg
+ *   --short-option-with-argument -s arg
+ *   --short-option-with-optional-argument -s [arg]
+ *
+ * Adding an argument of '&' to any form will set the "flag" member of
+ * the option structure to a non-null value.
+ *
+ * Based on these arguments, a suitable 'struct option' is constructed and
+ * passed to help_print_optstring.  Then a tab character is printed, followed
+ * by the return value of help_print_optsring (via printf %d).  Then further
+ * arguments are considered to output more options.
+ *
+ * Initially, the "l" value passed to help_print_optstring is 20.  This can be
+ * changed at any point by a numeric command-line argument, which will set a
+ * new value that applies to all subsequent calls until it is changed again.
+ *
+ * License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+ * This is free software: you are free to do what the fuck you want to.
+ * There is NO WARRANTY, to the extent permitted by law.
  */
 #include "help.h"
 #include "tap.h"
@@ -14,8 +40,6 @@
 
 #include <getopt.h>
 
-static char buf[1000];
-
 int arg_to_int(const char *s)
 {
        char *end;
@@ -52,6 +76,7 @@ int main(int argc, char **argv)
                        opt.val = UCHAR_MAX+1;
                        opt.has_arg = 0;
                        opt.name = argv[i]+2;
+                       opt.flag = NULL;
                } else if (argv[i][0] == '-') {
                        opt.val = argv[i][1];
                } else if (argv[i][0] == '[') {
@@ -61,6 +86,9 @@ int main(int argc, char **argv)
                        if ((c = strchr(argname, ']')))
                                *c = 0;
                        opt.has_arg = 2;
+               } else if (argv[i][0] == '&') {
+                       static int dummy;
+                       opt.flag = &dummy;
                } else if (argv[i][0] >= '0' && argv[i][0] <= '9') {
                        w = arg_to_int(argv[i]);
                } else {
index dbbcf6db2527c6ff7bbee0ab8718ceda1a8edbf6..cfd5408ee604775f35a593f3e9362bdbd4b1adf8 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright © 2015, 2021 Nick Bowler
+dnl Copyright © 2015, 2021-2022 Nick Bowler
 dnl
 dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
 dnl This is free software: you are free to do what the fuck you want to.
@@ -66,7 +66,8 @@ AT_CHECK([m4_join([ ],
   [--quux -q '@<:@ARG@:>@'],
   [--hello-this-is-a-very-long-option 20],
   [--hello-this-is-a-very-long-option 50],
-  [--not-long 12])], [0],
+  [--not-long 12],
+  [--flagged -f \&])], [0],
 [[  --foo      7
   -b, --bar    11
   --baz=ARG    11
@@ -77,6 +78,7 @@ AT_CHECK([m4_join([ ],
        0
   --hello-this-is-a-very-long-option   36
   --not-long   12
+  --flagged    11
 ]])
 
 AT_CLEANUP
@@ -95,7 +97,8 @@ AT_CHECK([m4_join([ ],
   [--quux -q '@<:@ARG@:>@'],
   [--hello-this-is-a-very-long-option 20],
   [--hello-this-is-a-very-long-option 50],
-  [--not-long 12])], [0],
+  [--not-long 12],
+  [--flagged -f \&])], [0],
 [[  -foo       6
   -bar 6
   -baz ARG     10
@@ -106,6 +109,7 @@ AT_CHECK([m4_join([ ],
        0
   -hello-this-is-a-very-long-option    35
   -not-long    11
+  -flagged     10
 ]])
 
 AT_CLEANUP