]> git.ozlabs.org Git - ccan/blobdiff - ccan/opt/usage.c
opt: don't wordwrap when description line starts with whitespace.
[ccan] / ccan / opt / usage.c
index ef33f9188dd304f41b12f19c6bbd29b3f8a69849..3edc4cf87ade8c8158eed5f01f9500944ae7c264 100644 (file)
@@ -1,6 +1,6 @@
 /* Licensed under GPLv3+ - see LICENSE file for details */
 #include <ccan/opt/opt.h>
-#ifdef HAVE_SYS_TERMIOS_H
+#if HAVE_SYS_TERMIOS_H
 #include <sys/ioctl.h>
 #include <sys/termios.h> /* Required on Solaris for struct winsize */
 #endif
@@ -24,7 +24,8 @@ static unsigned int get_columns(void)
 
        if (env)
                ws_col = atoi(env);
-#ifdef HAVE_SYS_TERMIOS_H
+
+#ifdef TIOCGWINSZ
        if (!ws_col)
        {
                struct winsize w;
@@ -40,25 +41,35 @@ static unsigned int get_columns(void)
 
 /* Return number of chars of words to put on this line.
  * Prefix is set to number to skip at start, maxlen is max width, returns
- * length (after prefix) to put on this line. */
-static size_t consume_words(const char *words, size_t maxlen, size_t *prefix)
+ * length (after prefix) to put on this line.
+ * start is set if we start a new line in the source description. */
+static size_t consume_words(const char *words, size_t maxlen, size_t *prefix,
+                           bool *start)
 {
        size_t oldlen, len;
 
-       /* Swallow leading whitespace. */
-       *prefix = strspn(words, " ");
+       /* Always swollow leading whitespace. */
+       *prefix = strspn(words, " \n");
        words += *prefix;
 
-       /* Use at least one word, even if it takes us over maxlen. */
-       oldlen = len = strcspn(words, " ");
-       while (len <= maxlen) {
-               oldlen = len;
-               len += strspn(words+len, " ");
-               len += strcspn(words+len, " ");
-               if (len == oldlen)
-                       break;
+       /* Leading whitespace at start of line means literal. */
+       if (*start && *prefix) {
+               oldlen = strcspn(words, "\n");
+       } else {
+               /* Use at least one word, even if it takes us over maxlen. */
+               oldlen = len = strcspn(words, " ");
+               while (len <= maxlen) {
+                       oldlen = len;
+                       len += strspn(words+len, " ");
+                       if (words[len] == '\n')
+                               break;
+                       len += strcspn(words+len, " \n");
+                       if (len == oldlen)
+                               break;
+               }
        }
 
+       *start = (words[oldlen - 1] == '\n');
        return oldlen;
 }
 
@@ -92,7 +103,7 @@ static char *add_desc(char *base, size_t *len, size_t *max,
 {
        size_t off, prefix, l;
        const char *p;
-       bool same_line = false;
+       bool same_line = false, start = true;
 
        base = add_str(base, len, max, opt->names);
        off = strlen(opt->names);
@@ -115,7 +126,7 @@ static char *add_desc(char *base, size_t *len, size_t *max,
 
        /* Indent description. */
        p = opt->desc;
-       while ((l = consume_words(p, width - indent, &prefix)) != 0) {
+       while ((l = consume_words(p, width - indent, &prefix, &start)) != 0) {
                if (!same_line)
                        base = add_indent(base, len, max, indent);
                p += prefix;