+dispcolumn (i, buf, bufsize, width, height)
+ int i;
+ char *buf;
+ size_t bufsize;
+ int width, height;
+{
+ int j;
+ int displen;
+ char *helpdoc;
+
+ /* first column */
+ helpdoc = _(shell_builtins[i].short_doc);
+
+ buf[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
+ strncpy (buf + 1, helpdoc, width - 2);
+ buf[width - 2] = '>'; /* indicate truncation */
+ buf[width - 1] = '\0';
+ printf ("%s", buf);
+ if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
+ {
+ printf ("\n");
+ return;
+ }
+
+ displen = strlen (buf);
+ /* two spaces */
+ for (j = displen; j < width; j++)
+ putc (' ', stdout);
+
+ /* second column */
+ helpdoc = _(shell_builtins[i+height].short_doc);
+
+ buf[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*';
+ strncpy (buf + 1, helpdoc, width - 3);
+ buf[width - 3] = '>'; /* indicate truncation */
+ buf[width - 2] = '\0';
+
+ printf ("%s\n", buf);
+}
+
+#if defined (HANDLE_MULTIBYTE)
+static void
+wdispcolumn (i, buf, bufsize, width, height)
+ int i;
+ char *buf;
+ size_t bufsize;
+ int width, height;
+{
+ int j;
+ int displen;
+ char *helpdoc;
+ wchar_t *wcstr;
+ size_t slen, n;
+ int wclen;
+
+ /* first column */
+ helpdoc = _(shell_builtins[i].short_doc);
+
+ wcstr = 0;
+ slen = mbstowcs ((wchar_t *)0, helpdoc, 0);
+ if (slen == -1)
+ {
+ dispcolumn (i, buf, bufsize, width, height);
+ return;
+ }
+
+ /* No bigger than the passed max width */
+ if (slen >= width)
+ slen = width - 2;
+ wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (width + 2));
+ n = mbstowcs (wcstr+1, helpdoc, slen + 1);
+ wcstr[n+1] = L'\0';
+
+ /* Turn tabs and newlines into spaces for column display, since wcwidth
+ returns -1 for them */
+ for (j = 1; j < n; j++)
+ if (wcstr[j] == L'\n' || wcstr[j] == L'\t')
+ wcstr[j] = L' ';
+
+ displen = wcsnwidth (wcstr+1, slen, width - 2) + 1; /* +1 for ' ' or '*' */
+
+ wcstr[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? L' ' : L'*';
+
+ /* This assumes each wide char takes up one column position when displayed */
+ wcstr[width - 2] = L'>'; /* indicate truncation */
+ wcstr[width - 1] = L'\0';
+
+ printf ("%ls", wcstr);
+ if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
+ {
+ printf ("\n");
+ return;
+ }
+
+ /* at least one space */
+ for (j = displen; j < width; j++)
+ putc (' ', stdout);
+
+ /* second column */
+ helpdoc = _(shell_builtins[i+height].short_doc);
+ slen = mbstowcs ((wchar_t *)0, helpdoc, 0);
+ if (slen == -1)
+ {
+ /* for now */
+ printf ("%c%s\n", (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*', helpdoc);
+ return;
+ }
+
+ /* Reuse wcstr since it is already width wide chars long */
+ if (slen >= width)
+ slen = width - 2;
+ n = mbstowcs (wcstr+1, helpdoc, slen + 1);
+ wcstr[n+1] = L'\0'; /* make sure null-terminated */
+
+ /* Turn tabs and newlines into spaces for column display */
+ for (j = 1; j < n; j++)
+ if (wcstr[j] == L'\n' || wcstr[j] == L'\t')
+ wcstr[j] = L' ';
+
+ displen = wcsnwidth (wcstr+1, slen, width - 2);
+
+ wcstr[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? L' ' : L'*';
+
+ /* This assumes each wide char takes up one column position when displayed */
+ wcstr[width - 3] = L'>'; /* indicate truncation */
+ wcstr[width - 2] = L'\0';
+
+ printf ("%ls\n", wcstr);
+
+ free (wcstr);
+}
+#endif /* HANDLE_MULTIBYTE */
+
+static void