]> git.draconx.ca Git - dxcommon.git/commitdiff
help_print_optstring: Better output on some old systems.
authorNick Bowler <nbowler@draconx.ca>
Wed, 6 Dec 2023 01:10:08 +0000 (20:10 -0500)
committerNick Bowler <nbowler@draconx.ca>
Wed, 6 Dec 2023 01:17:54 +0000 (20:17 -0500)
Some very old printf implementations return 0 on success instead of the
number of bytes written.  We should never see a return of 0 normally,
so we can improve the output to be less of a garbled mess by printing a
newline if that happens (same as the error case).  This is a simple
tweak that should have virtually no impact on modern systems.

The tests are adapted to verify the new behaviour, although we'll mark
the result as "skipped" (assuming it is correct) instead of "passed"
since it's only sortof working.

Makefile.am
src/help.c
t/.gitignore
t/printfchk.c [new file with mode: 0644]
tests/functions.at

index f811cde03e642632738d928f9d4725fe58b0aa92..0e5e20a45e2dd207b0b166a55864b401576e107d 100644 (file)
@@ -24,7 +24,7 @@ t_packtests_SOURCES = t/packtests.c src/pack.c src/tap.c
 t_packtestu64_SOURCES = t/packtestu64.c src/pack.c src/tap.c
 t_packtests64_SOURCES = t/packtests64.c src/pack.c src/tap.c
 
-check_PROGRAMS += t/helpdesc t/helpopt t/helpopt2
+check_PROGRAMS += t/printfchk t/helpdesc t/helpopt t/helpopt2
 if HAVE_WCWIDTH
 check_PROGRAMS += t/helpopt3
 endif
index 3886c272ac6e4cd5145b4f17462f66a28ccee9f0..a635a15c879785ff1d7b931a99de3199ac38eca7 100644 (file)
@@ -183,7 +183,7 @@ no_translate:
                w = printf(fmt, opt->name, argname);
        }
 out:
-       if (w < 0 || w > l) {
+       if (w <= 0 || w > l) {
                putchar('\n');
                return 0;
        }
index 8b12d4a65f600aeaf4259f938eefa43a0b3f95c4..39c659aef698cb426880fcf719dd2b0cd1b69b95 100644 (file)
@@ -5,3 +5,4 @@
 /helpopt3
 /packtest[su]
 /packtest[su]64
+/printfchk
diff --git a/t/printfchk.c b/t/printfchk.c
new file mode 100644 (file)
index 0000000..8d63f3b
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright © 2023 Nick Bowler
+ *
+ * Runtime check of printf behaviour for the test suite.  Some very old printf
+ * implementations return 0 on success instead of the number of bytes written.
+ *
+ * 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 <stdio.h>
+
+int main(void)
+{
+       return printf("hello\n") == 0;
+}
index 6b092a0e17fe70a0fc11659365b29dba9b261a3f..4a9aeb5b16b9b9dde59b6ba61502dc4f07b54810 100644 (file)
@@ -56,20 +56,7 @@ AT_CLEANUP
 AT_SETUP([help_print_optstring])
 AT_KEYWORDS([help])
 
-AT_SKIP_IF([test ! -x "$builddir/t/helpopt"])
-
-AT_CHECK([m4_join([ ],
-  ["$builddir/t/helpopt"],
-  [--foo],
-  [--bar -b],
-  [--baz ARG],
-  [--baz -B ARG],
-  [--quux '@<:@ARG@:>@'],
-  [--quux -q '@<:@ARG@:>@'],
-  [--hello-this-is-a-very-long-option 20],
-  [--hello-this-is-a-very-long-option 50],
-  [--not-long 12],
-  [--flagged -f \&])], [0],
+AT_DATA([expout],
 [[ --foo       6
  -b, --bar     10
  --baz=ARG     10
@@ -83,15 +70,20 @@ AT_CHECK([m4_join([ ],
  --flagged     10
 ]])
 
-AT_CLEANUP
-
-AT_SETUP([help_print_optstring (getopt_long_only)])
-AT_KEYWORDS([help])
-
-AT_SKIP_IF([test ! -x "$builddir/t/helpopt2"])
+# Some very old printf implementations return 0 on success instead of the
+# number of bytes written.  The help_print_optstring function is not fully
+# functional in this case.  It should fallback to printing a newline and
+# returning 0 so the overall --help output should be mostly acceptable.
+#
+# We verify that this indeed works properly by adjusting the expected
+# output accordingly, but ...
+AS_IF(["$builddir/t/printfchk" >/dev/null], [ancient_printf=false],
+[[sed -n -e 's/        [0-9]*$//' -e '/^ *-/p' -e 's/^ *-.*/   0/p' expout >expout.tmp
+mv -f expout.tmp expout
+ancient_printf=:]])
 
 AT_CHECK([m4_join([ ],
-  ["$builddir/t/helpopt2"],
+  ["$builddir/t/helpopt"],
   [--foo],
   [--bar -b],
   [--baz ARG],
@@ -101,7 +93,18 @@ AT_CHECK([m4_join([ ],
   [--hello-this-is-a-very-long-option 20],
   [--hello-this-is-a-very-long-option 50],
   [--not-long 12],
-  [--flagged -f \&])], [0],
+  [--flagged -f \&])], [0], [expout])
+
+# ... we ultimately skip the test so there's an indication (other than an
+# outright failure) that the function is not working completely.
+AT_SKIP_IF([$ancient_printf])
+
+AT_CLEANUP
+
+AT_SETUP([help_print_optstring (getopt_long_only)])
+AT_KEYWORDS([help])
+
+AT_DATA([expout],
 [[ -foo        5
  -bar  5
  -baz ARG      9
@@ -115,6 +118,35 @@ AT_CHECK([m4_join([ ],
  -flagged      9
 ]])
 
+# Some very old printf implementations return 0 on success instead of the
+# number of bytes written.  The help_print_optstring function is not fully
+# functional in this case.  It should fallback to printing a newline and
+# returning 0 so the overall --help output should be mostly acceptable.
+#
+# We verify that this indeed works properly by adjusting the expected
+# output accordingly, but ...
+AS_IF(["$builddir/t/printfchk" >/dev/null], [ancient_printf=false],
+[[sed -n -e 's/        [0-9]*$//' -e '/^ *-/p' -e 's/^ *-.*/   0/p' expout >expout.tmp
+mv -f expout.tmp expout
+ancient_printf=:]])
+
+AT_CHECK([m4_join([ ],
+  ["$builddir/t/helpopt2"],
+  [--foo],
+  [--bar -b],
+  [--baz ARG],
+  [--baz -B ARG],
+  [--quux '@<:@ARG@:>@'],
+  [--quux -q '@<:@ARG@:>@'],
+  [--hello-this-is-a-very-long-option 20],
+  [--hello-this-is-a-very-long-option 50],
+  [--not-long 12],
+  [--flagged -f \&])], [0], [expout])
+
+# ... we ultimately skip the test so there's an indication (other than an
+# outright failure) that the function is not working completely.
+AT_SKIP_IF([$ancient_printf])
+
 AT_CLEANUP
 
 AT_SETUP([help_print_optstring (NLS fullwidth/halfwidth)])