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.
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);
}
/*
- * Copyright © 2021 Nick Bowler
+ * Copyright © 2021, 2023 Nick Bowler
*
* Helper functions for formatting --help program output.
*
* 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);
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)])
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], [
])