]> git.draconx.ca Git - dxcommon.git/commitdiff
help_print_desc: Simplify implementation.
authorNick Bowler <nbowler@draconx.ca>
Tue, 5 Dec 2023 01:55:43 +0000 (20:55 -0500)
committerNick Bowler <nbowler@draconx.ca>
Tue, 5 Dec 2023 01:57:06 +0000 (20:57 -0500)
Simplify the way this function works by basing the loop around strcspn.

There is a slight change of behaviour when called with i==0 and an empty
description.   Previously, no newline was printed.  Now, a newline is
printed.  I think the original behaviour was a mistake as it does not
make much sense (and this function serves no real purpose unless i is
nonzero).  The tests are updated to expect this behaviour change.

As a bonus, we no longer tickle a problem with some ancient systems
(e.g., ULTRIX 4.5) which have a printf that doesn't support a negative
precision argument to mean "default precision".  This problem actually
has no coverage in the test suite, so fix that up too.

src/help.c
src/help.h
tests/functions.at

index 4b77b2ce2e78587df19e0548ee2dea49bb4b9d1b..3aa083003a03710560976034a209cc44b2f5cb3a 100644 (file)
@@ -202,17 +202,11 @@ void help_print_desc(const struct option *opt, const char *s, int i, int w)
        if (opt)
                s = pgettext_expr(opt->name, s);
 
-       if (i && s[0] == '\0')
-               putchar('\n');
-
-       for (; *s; w = 0) {
-               const char *nl = strchr(s, '\n');
-               int n = (nl ? nl-s : -1);
+       do {
+               size_t n = strcspn(s, "\n");
 
-               printf("%*s%.*s\n", i-w, "", n, s);
-               if (!nl)
-                       break;
-
-               s = nl+1;
-       }
+               printf("%*s%.*s\n", n ? i-w : 0, "", (int)n, s);
+               s += n + (s[n] != '\0');
+               w = 0;
+       } while (*s);
 }
index a78bc59c0b6fc48953d8e556a12d0b8ef34bc3c1..7dbb65de4efb7998bd0ea2b9b357aab3c8738b4c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2021 Nick Bowler
+ * Copyright © 2021, 2023 Nick Bowler
  *
  * Helper functions for formatting --help program output.
  *
@@ -28,6 +28,9 @@ int help_print_optstring(const struct option *opt, const char *argname, int l);
  * with the context set to opt->name.  The first line will be indented by
  * i-w spaces (to account for the cursor being in some other column), all
  * other lines are indented by i spaces.
+ *
+ * The output always ends with a newline, regardless of whether or not the
+ * input string ends with a newline.
  */
 void help_print_desc(const struct option *opt, const char *desc, int i, int w);
 
index e1d556b0a71d59e697f14c3701f23b9fb33faa0a..71a282d7d4c67c0c9a62cd2662fb3d7a5841ef5c 100644 (file)
@@ -33,6 +33,11 @@ sed -e '5,$s/^/     /' -e '6,$s/^/     /' \
 AT_CHECK(["$builddir/t/helpdesc" 0 0 10 5 30 20 40 40 <test.txt],
   [0], [expout])
 
+AT_CHECK([AS_ECHO_N(["no trailing newline"]) |
+  "$builddir/t/helpdesc" 0 0], [0],
+[no trailing newline
+])
+
 AT_CLEANUP
 
 AT_SETUP([help_print_desc (empty description)])
@@ -40,7 +45,9 @@ AT_KEYWORDS([help])
 
 AT_SKIP_IF([test ! -x "$builddir/t/helpdesc"])
 
-AT_CHECK(["$builddir/t/helpdesc" 0 0 0 20 </dev/null])
+AT_CHECK(["$builddir/t/helpdesc" 0 0 0 20 </dev/null], [0], [
+
+])
 AT_CHECK(["$builddir/t/helpdesc" 1 20 </dev/null], [0], [
 ])