summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-01-20 21:13:55 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-01-20 21:13:55 +0000
commitf7108ce06bb526ba336c194956b4ed924b317b7a (patch)
treea3c8a95121ae089a9fc86446d0342ec058574ff4
parent000666bbfea4694212d104202d21875ce6f160c7 (diff)
Fix psql \h output for case of no parameters (ie, list all the known commands)
to format properly for the actually needed column width, instead of having a hard-wired assumption about the longest command name length. Also make it respond to the current screen width. In passing, const-ify the constant table.
-rw-r--r--src/bin/psql/create_help.pl20
-rw-r--r--src/bin/psql/help.c63
2 files changed, 54 insertions, 29 deletions
diff --git a/src/bin/psql/create_help.pl b/src/bin/psql/create_help.pl
index f969f930861..0fc0f487ce2 100644
--- a/src/bin/psql/create_help.pl
+++ b/src/bin/psql/create_help.pl
@@ -5,7 +5,7 @@
#
# Copyright (c) 2000-2008, PostgreSQL Global Development Group
#
-# $PostgreSQL: pgsql/src/bin/psql/create_help.pl,v 1.16 2008/01/01 19:45:55 momjian Exp $
+# $PostgreSQL: pgsql/src/bin/psql/create_help.pl,v 1.17 2008/01/20 21:13:55 tgl Exp $
#################################################################
#
@@ -51,20 +51,21 @@ print OUT
#ifndef $define
#define $define
-#define N_(x) (x) /* gettext noop */
+#define N_(x) (x) /* gettext noop */
struct _helpStruct
{
- char *cmd; /* the command name */
- char *help; /* the help associated with it */
- char *syntax; /* the syntax associated with it */
+ const char *cmd; /* the command name */
+ const char *help; /* the help associated with it */
+ const char *syntax; /* the syntax associated with it */
};
-static struct _helpStruct QL_HELP[] = {
+static const struct _helpStruct QL_HELP[] = {
";
$count = 0;
+$maxlen = 0;
foreach $file (sort readdir DIR) {
local ($cmdname, $cmddesc, $cmdsynopsis);
@@ -113,7 +114,9 @@ foreach $file (sort readdir DIR) {
$cmdsynopsis =~ s/\"/\\"/g;
print OUT " { \"$cmdname\",\n N_(\"$cmddesc\"),\n N_(\"$cmdsynopsis\") },\n\n";
- $count++;
+
+ $count++;
+ $maxlen = ($maxlen >= length $cmdname) ? $maxlen : length $cmdname;
}
else {
print STDERR "$0: parsing file '$file' failed (N='$cmdname' D='$cmddesc')\n";
@@ -125,7 +128,8 @@ print OUT "
};
-#define QL_HELP_COUNT $count
+#define QL_HELP_COUNT $count /* number of help items */
+#define QL_MAX_CMD_LEN $maxlen /* largest strlen(cmd) */
#endif /* $define */
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index e9f2e0db086..9d0eb40a24a 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.121 2008/01/01 19:45:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.122 2008/01/20 21:13:55 tgl Exp $
*/
#include "postgres_fe.h"
@@ -19,6 +19,14 @@
#include <win32.h>
#endif
+#ifndef WIN32
+#include <sys/ioctl.h> /* for ioctl() */
+#endif
+
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
#include "pqsignal.h"
#include "common.h"
@@ -147,15 +155,6 @@ usage(void)
*
* print out help for the backslash commands
*/
-
-#ifndef TIOCGWINSZ
-struct winsize
-{
- int ws_row;
- int ws_col;
-};
-#endif
-
void
slashUsage(unsigned short int pager)
{
@@ -280,24 +279,46 @@ helpSQL(const char *topic, unsigned short int pager)
if (!topic || strlen(topic) == 0)
{
- int i;
- int items_per_column = (QL_HELP_COUNT + 2) / 3;
+ /* Print all the available command names */
+ int screen_width;
+ int ncolumns;
+ int nrows;
FILE *output;
+ int i;
+ int j;
- output = PageOutput(items_per_column + 1, pager);
+#ifdef TIOCGWINSZ
+ struct winsize screen_size;
+
+ if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1)
+ screen_width = 80; /* ioctl failed, assume 80 */
+ else
+ screen_width = screen_size.ws_col;
+#else
+ screen_width = 80; /* default assumption */
+#endif
+
+ ncolumns = (screen_width - 3) / (QL_MAX_CMD_LEN + 1);
+ ncolumns = Max(ncolumns, 1);
+ nrows = (QL_HELP_COUNT + (ncolumns - 1)) / ncolumns;
+
+ output = PageOutput(nrows + 1, pager);
fputs(_("Available help:\n"), output);
- for (i = 0; i < items_per_column; i++)
+ for (i = 0; i < nrows; i++)
{
- fprintf(output, " %-26s%-26s",
- VALUE_OR_NULL(QL_HELP[i].cmd),
- VALUE_OR_NULL(QL_HELP[i + items_per_column].cmd));
- if (i + 2 * items_per_column < QL_HELP_COUNT)
- fprintf(output, "%-26s",
- VALUE_OR_NULL(QL_HELP[i + 2 * items_per_column].cmd));
+ fprintf(output, " ");
+ for (j = 0; j < ncolumns-1; j++)
+ fprintf(output, "%-*s",
+ QL_MAX_CMD_LEN + 1,
+ VALUE_OR_NULL(QL_HELP[i + j * nrows].cmd));
+ if (i + j * nrows < QL_HELP_COUNT)
+ fprintf(output, "%s",
+ VALUE_OR_NULL(QL_HELP[i + j * nrows].cmd));
fputc('\n', output);
}
+
/* Only close if we used the pager */
if (output != stdout)
{
@@ -317,7 +338,7 @@ helpSQL(const char *topic, unsigned short int pager)
size_t len,
wordlen;
int nl_count = 0;
- char *ch;
+ const char *ch;
/* User gets two chances: exact match, then the first word */