aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-10-13 21:04:01 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-10-13 21:04:01 +0000
commit42ec8ad6286be046d86fc9f09bb4cdeefc395bfe (patch)
treebc2de6234cbc40060ba81d71222d593b0c680efe
parentb14071164366e7efee9dc3a017eb7cb4cfac3428 (diff)
downloadpostgresql-42ec8ad6286be046d86fc9f09bb4cdeefc395bfe.tar.gz
postgresql-42ec8ad6286be046d86fc9f09bb4cdeefc395bfe.zip
Add "\pset linestyle ascii/unicode" option to psql, allowing our traditional
ASCII-art style of table output to be upgraded to use Unicode box drawing characters if desired. By default, psql will use the Unicode characters whenever client_encoding is UTF8. The patch forces linestyle=ascii in pg_regress usage, ensuring we don't break the regression tests in Unicode locales. Roger Leigh
-rw-r--r--doc/src/sgml/ref/psql-ref.sgml35
-rw-r--r--src/bin/psql/command.c22
-rw-r--r--src/bin/psql/mbprint.c8
-rw-r--r--src/bin/psql/mbprint.h4
-rw-r--r--src/bin/psql/print.c250
-rw-r--r--src/bin/psql/print.h37
-rw-r--r--src/bin/psql/tab-complete.c6
-rw-r--r--src/test/regress/pg_regress_main.c4
8 files changed, 276 insertions, 90 deletions
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 88fd8b0b292..bbccb3b87b9 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -1,5 +1,5 @@
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.231 2009/10/08 16:34:00 alvherre Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.232 2009/10/13 21:04:01 tgl Exp $
PostgreSQL documentation
-->
@@ -1761,6 +1761,39 @@ lo_import 152801
</varlistentry>
<varlistentry>
+ <term><literal>linestyle</literal></term>
+ <listitem>
+ <para>
+ Sets the border line drawing style to one
+ of <literal>ascii</literal> or <literal>unicode</literal>.
+ Unique abbreviations are allowed. (That would mean one
+ letter is enough.)
+ </para>
+
+ <para>
+ <quote>ASCII</quote> uses plain <acronym>ASCII</acronym> characters.
+ </para>
+
+ <para>
+ <quote>Unicode</quote> uses Unicode box-drawing characters.
+ </para>
+
+ <para>
+ When the selected output format is one that draws lines or boxes
+ around the data, this setting controls how the lines are drawn.
+ Plain <acronym>ASCII</acronym> characters work everywhere, but
+ Unicode characters look nicer on displays that recognize them.
+ </para>
+
+ <para>
+ If this option has not been set, the default behavior is to
+ use Unicode characters if the client character set encoding
+ is UTF-8, otherwise <acronym>ASCII</acronym> characters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><literal>expanded</literal> (or <literal>x</literal>)</term>
<listitem>
<para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index cea3942f013..6ce10caa2b8 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.209 2009/10/07 22:14:24 alvherre Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.210 2009/10/13 21:04:01 tgl Exp $
*/
#include "postgres_fe.h"
#include "command.h"
@@ -1788,6 +1788,26 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
printf(_("Output format is %s.\n"), _align2string(popt->topt.format));
}
+ /* set table line style */
+ else if (strcmp(param, "linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (pg_strncasecmp("ascii", value, vallen) == 0)
+ popt->topt.line_style = &pg_asciiformat;
+ else if (pg_strncasecmp("unicode", value, vallen) == 0)
+ popt->topt.line_style = &pg_utf8format;
+ else
+ {
+ psql_error("\\pset: allowed line styles are ascii, unicode\n");
+ return false;
+ }
+
+ if (!quiet)
+ printf(_("Line style is %s.\n"),
+ get_line_style(&popt->topt)->name);
+ }
+
/* set border style/width */
else if (strcmp(param, "border") == 0)
{
diff --git a/src/bin/psql/mbprint.c b/src/bin/psql/mbprint.c
index 4c33688e09a..2999d56ef6f 100644
--- a/src/bin/psql/mbprint.c
+++ b/src/bin/psql/mbprint.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/mbprint.c,v 1.35 2009/06/11 14:49:08 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/mbprint.c,v 1.36 2009/10/13 21:04:01 tgl Exp $
*
* XXX this file does not really belong in psql/. Perhaps move to libpq?
* It also seems that the mbvalidate function is redundant with existing
@@ -30,8 +30,8 @@
typedef unsigned int pg_wchar;
-static int
-get_utf8_id(void)
+int
+pg_get_utf8_id(void)
{
static int utf8_id = -1;
@@ -40,7 +40,7 @@ get_utf8_id(void)
return utf8_id;
}
-#define PG_UTF8 get_utf8_id()
+#define PG_UTF8 pg_get_utf8_id()
static pg_wchar
diff --git a/src/bin/psql/mbprint.h b/src/bin/psql/mbprint.h
index 5ab1cbf0453..4d5376c7cd6 100644
--- a/src/bin/psql/mbprint.h
+++ b/src/bin/psql/mbprint.h
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/bin/psql/mbprint.h,v 1.13 2009/06/11 14:49:08 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/bin/psql/mbprint.h,v 1.14 2009/10/13 21:04:01 tgl Exp $ */
#ifndef MBPRINT_H
#define MBPRINT_H
@@ -9,8 +9,8 @@ struct lineptr
int width;
};
+extern int pg_get_utf8_id(void);
extern unsigned char *mbvalidate(unsigned char *pwcs, int encoding);
-
extern int pg_wcswidth(const unsigned char *pwcs, size_t len, int encoding);
extern void pg_wcsformat(unsigned char *pwcs, size_t len, int encoding, struct lineptr * lines, int count);
extern void pg_wcssize(unsigned char *pwcs, size_t len, int encoding,
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 4260143c447..80dd304f1eb 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.116 2009/06/12 16:17:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.117 2009/10/13 21:04:01 tgl Exp $
*/
#include "postgres_fe.h"
@@ -44,6 +44,43 @@ static char *decimal_point;
static char *grouping;
static char *thousands_sep;
+/* Line style control structures */
+const printTextFormat pg_asciiformat =
+{
+ "ascii",
+ {
+ { "-", "+", "+", "+" },
+ { "-", "+", "+", "+" },
+ { "-", "+", "+", "+" },
+ { "", "|", "|", "|" }
+ },
+ ":",
+ ";",
+ " "
+};
+
+const printTextFormat pg_utf8format =
+{
+ "unicode",
+ {
+ /* ─, ┌, ┬, ┐ */
+ { "\342\224\200", "\342\224\214", "\342\224\254", "\342\224\220" },
+ /* ─, ├, ┼, ┤ */
+ { "\342\224\200", "\342\224\234", "\342\224\274", "\342\224\244" },
+ /* ─, └, ┴, ┘ */
+ { "\342\224\200", "\342\224\224", "\342\224\264", "\342\224\230" },
+ /* N/A, │, │, │ */
+ { "", "\342\224\202", "\342\224\202", "\342\224\202" }
+ },
+ /* ╎ */
+ "\342\225\216",
+ /* ┊ */
+ "\342\224\212",
+ /* ╷ */
+ "\342\225\267"
+};
+
+
/* Local functions */
static int strlen_max_width(unsigned char *str, int *target_width, int encoding);
static void IsPagerNeeded(const printTableContent *cont, const int extra_lines,
@@ -116,7 +153,10 @@ strlen_with_numeric_locale(const char *my_str)
return strlen(my_str) + additional_numeric_locale_len(my_str);
}
-/* Returns the appropriately formatted string in a new allocated block, caller must free */
+/*
+ * Returns the appropriately formatted string in a new allocated block,
+ * caller must free
+ */
static char *
format_numeric_locale(const char *my_str)
{
@@ -172,6 +212,7 @@ format_numeric_locale(const char *my_str)
return new_str;
}
+
/*************************/
/* Unaligned text */
/*************************/
@@ -360,34 +401,38 @@ print_unaligned_vertical(const printTableContent *cont, FILE *fout)
/* draw "line" */
static void
_print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths,
- unsigned short border, FILE *fout)
+ unsigned short border, printTextRule pos,
+ const printTextFormat *format,
+ FILE *fout)
{
+ const printTextLineFormat *lformat = &format->lrule[pos];
unsigned int i,
j;
if (border == 1)
- fputc('-', fout);
+ fputs(lformat->hrule, fout);
else if (border == 2)
- fputs("+-", fout);
+ fprintf(fout, "%s%s", lformat->leftvrule, lformat->hrule);
for (i = 0; i < ncolumns; i++)
{
for (j = 0; j < widths[i]; j++)
- fputc('-', fout);
+ fputs(lformat->hrule, fout);
if (i < ncolumns - 1)
{
if (border == 0)
fputc(' ', fout);
else
- fputs("-+-", fout);
+ fprintf(fout, "%s%s%s", lformat->hrule,
+ lformat->midvrule, lformat->hrule);
}
}
if (border == 2)
- fputs("-+", fout);
+ fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
else if (border == 1)
- fputc('-', fout);
+ fputs(lformat->hrule, fout);
fputc('\n', fout);
}
@@ -403,6 +448,8 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
bool opt_numeric_locale = cont->opt->numericLocale;
int encoding = cont->opt->encoding;
unsigned short opt_border = cont->opt->border;
+ const printTextFormat *format = get_line_style(cont->opt);
+ const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
unsigned int col_count = 0,
cell_count = 0;
@@ -709,7 +756,8 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
int curr_nl_line;
if (opt_border == 2)
- _print_horizontal_line(col_count, width_wrap, opt_border, fout);
+ _print_horizontal_line(col_count, width_wrap, opt_border,
+ PRINT_RULE_TOP, format, fout);
for (i = 0; i < col_count; i++)
pg_wcsformat((unsigned char *) cont->headers[i],
@@ -722,15 +770,15 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
while (more_col_wrapping)
{
if (opt_border == 2)
- fprintf(fout, "|%c", curr_nl_line ? '+' : ' ');
+ fprintf(fout, "%s%c", dformat->leftvrule,
+ curr_nl_line ? '+' : ' ');
else if (opt_border == 1)
fputc(curr_nl_line ? '+' : ' ', fout);
for (i = 0; i < cont->ncolumns; i++)
{
- unsigned int nbspace;
-
struct lineptr *this_line = col_lineptrs[i] + curr_nl_line;
+ unsigned int nbspace;
if (!header_done[i])
{
@@ -753,19 +801,21 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
if (opt_border == 0)
fputc(curr_nl_line ? '+' : ' ', fout);
else
- fprintf(fout, " |%c", curr_nl_line ? '+' : ' ');
+ fprintf(fout, " %s%c", dformat->midvrule,
+ curr_nl_line ? '+' : ' ');
}
}
curr_nl_line++;
if (opt_border == 2)
- fputs(" |", fout);
+ fprintf(fout, " %s", dformat->rightvrule);
else if (opt_border == 1)
fputc(' ', fout);
fputc('\n', fout);
}
- _print_horizontal_line(col_count, width_wrap, opt_border, fout);
+ _print_horizontal_line(col_count, width_wrap, opt_border,
+ PRINT_RULE_MIDDLE, format, fout);
}
}
@@ -811,7 +861,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
/* left border */
if (opt_border == 2)
- fputs("| ", fout);
+ fprintf(fout, "%s ", dformat->leftvrule);
else if (opt_border == 1)
fputc(' ', fout);
@@ -884,22 +934,22 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
fputc(' ', fout);
/* Next value is beyond past newlines? */
else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL)
- fputs(" ", fout);
+ fprintf(fout, " %s ", format->midvrule_blank);
/* In wrapping of value? */
else if (bytes_output[j + 1] != 0)
- fputs(" ; ", fout);
+ fprintf(fout, " %s ", format->midvrule_wrap);
/* After first newline value */
else if (curr_nl_line[j + 1] != 0)
- fputs(" : ", fout);
+ fprintf(fout, " %s ", format->midvrule_cont);
+ /* Ordinary line */
else
- /* Ordinary line */
- fputs(" | ", fout);
+ fprintf(fout, " %s ", dformat->midvrule);
}
}
/* end-of-row border */
if (opt_border == 2)
- fputs(" |", fout);
+ fprintf(fout, " %s", dformat->rightvrule);
fputc('\n', fout);
} while (more_lines);
@@ -908,7 +958,8 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
if (cont->opt->stop_table)
{
if (opt_border == 2 && !cancel_pressed)
- _print_horizontal_line(col_count, width_wrap, opt_border, fout);
+ _print_horizontal_line(col_count, width_wrap, opt_border,
+ PRINT_RULE_BOTTOM, format, fout);
/* print footers */
if (cont->footers && !opt_tuples_only && !cancel_pressed)
@@ -943,11 +994,70 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
static void
+print_aligned_vertical_line(const printTableContent *cont,
+ unsigned long record,
+ unsigned int hwidth,
+ unsigned int dwidth,
+ printTextRule pos,
+ FILE *fout)
+{
+ const printTextFormat *format = get_line_style(cont->opt);
+ const printTextLineFormat *lformat = &format->lrule[pos];
+ unsigned short opt_border = cont->opt->border;
+ unsigned int i;
+ int reclen = 0;
+
+ if (opt_border == 2)
+ fprintf(fout, "%s%s", lformat->leftvrule, lformat->hrule);
+ else if (opt_border == 1)
+ fputs(lformat->hrule, fout);
+
+ if (record)
+ {
+ if (opt_border == 0)
+ reclen = fprintf(fout, "* Record %lu", record);
+ else
+ reclen = fprintf(fout, "[ RECORD %lu ]", record);
+ }
+ if (opt_border != 2)
+ reclen++;
+ if (reclen < 0)
+ reclen = 0;
+ for (i = reclen; i < hwidth; i++)
+ fputs(opt_border > 0 ? lformat->hrule : " ", fout);
+ reclen -= hwidth;
+
+ if (opt_border > 0)
+ {
+ if (reclen-- <= 0)
+ fputs(lformat->hrule, fout);
+ if (reclen-- <= 0)
+ fputs(lformat->midvrule, fout);
+ if (reclen-- <= 0)
+ fputs(lformat->hrule, fout);
+ }
+ else
+ {
+ if (reclen-- <= 0)
+ fputc(' ', fout);
+ }
+ if (reclen < 0)
+ reclen = 0;
+ for (i = reclen; i < dwidth; i++)
+ fputs(opt_border > 0 ? lformat->hrule : " ", fout);
+ if (opt_border == 2)
+ fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
+ fputc('\n', fout);
+}
+
+static void
print_aligned_vertical(const printTableContent *cont, FILE *fout)
{
bool opt_tuples_only = cont->opt->tuples_only;
bool opt_numeric_locale = cont->opt->numericLocale;
unsigned short opt_border = cont->opt->border;
+ const printTextFormat *format = get_line_style(cont->opt);
+ const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
int encoding = cont->opt->encoding;
unsigned long record = cont->opt->prior_records + 1;
const char *const * ptr;
@@ -958,7 +1068,6 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
dheight = 1,
hformatsize = 0,
dformatsize = 0;
- char *divider;
struct lineptr *hlineptr,
*dlineptr;
@@ -1026,22 +1135,6 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
dlineptr->ptr = pg_local_malloc(dformatsize);
hlineptr->ptr = pg_local_malloc(hformatsize);
- /* make horizontal border */
- divider = pg_local_malloc(hwidth + dwidth + 10);
- divider[0] = '\0';
- if (opt_border == 2)
- strcat(divider, "+-");
- for (i = 0; i < hwidth; i++)
- strcat(divider, opt_border > 0 ? "-" : " ");
- if (opt_border > 0)
- strcat(divider, "-+-");
- else
- strcat(divider, " ");
- for (i = 0; i < dwidth; i++)
- strcat(divider, opt_border > 0 ? "-" : " ");
- if (opt_border == 2)
- strcat(divider, "-+");
-
if (cont->opt->start_table)
{
/* print title */
@@ -1052,38 +1145,29 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
/* print records */
for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
{
+ printTextRule pos;
int line_count,
dcomplete,
hcomplete;
+ if (cancel_pressed)
+ break;
+
+ if (i == 0)
+ pos = PRINT_RULE_TOP;
+ else if (!(*(ptr+1)))
+ pos = PRINT_RULE_BOTTOM;
+ else
+ pos = PRINT_RULE_MIDDLE;
+
if (i % cont->ncolumns == 0)
{
- if (cancel_pressed)
- break;
if (!opt_tuples_only)
- {
- char record_str[64];
- size_t record_str_len;
-
- if (opt_border == 0)
- snprintf(record_str, 64, "* Record %lu", record++);
- else
- snprintf(record_str, 64, "[ RECORD %lu ]", record++);
- record_str_len = strlen(record_str);
-
- if (record_str_len + opt_border > strlen(divider))
- fprintf(fout, "%.*s%s\n", opt_border, divider, record_str);
- else
- {
- char *div_copy = pg_strdup(divider);
-
- strncpy(div_copy + opt_border, record_str, record_str_len);
- fprintf(fout, "%s\n", div_copy);
- free(div_copy);
- }
- }
+ print_aligned_vertical_line(cont, record++, hwidth, dwidth,
+ pos, fout);
else if (i != 0 || !cont->opt->start_table || opt_border == 2)
- fprintf(fout, "%s\n", divider);
+ print_aligned_vertical_line(cont, 0, hwidth, dwidth,
+ pos, fout);
}
/* Format the header */
@@ -1099,7 +1183,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
while (!dcomplete || !hcomplete)
{
if (opt_border == 2)
- fputs("| ", fout);
+ fprintf(fout, "%s ", dformat->leftvrule);
if (!hcomplete)
{
fprintf(fout, "%-s%*s", hlineptr[line_count].ptr,
@@ -1112,9 +1196,11 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
fprintf(fout, "%*s", hwidth, "");
if (opt_border > 0)
- fprintf(fout, " %c ", (line_count == 0) ? '|' : ':');
+ fprintf(fout, " %s ",
+ (line_count == 0) ?
+ format->midvrule_cont : dformat->midvrule);
else
- fputs(" ", fout);
+ fputc(' ', fout);
if (!dcomplete)
{
@@ -1125,8 +1211,9 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (opt_border < 2)
fprintf(fout, "%s\n", my_cell);
else
- fprintf(fout, "%-s%*s |\n", my_cell,
- (int) (dwidth - strlen(my_cell)), "");
+ fprintf(fout, "%-s%*s %s\n", my_cell,
+ (int) (dwidth - strlen(my_cell)), "",
+ dformat->rightvrule);
free(my_cell);
}
else
@@ -1134,8 +1221,9 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (opt_border < 2)
fprintf(fout, "%s\n", dlineptr[line_count].ptr);
else
- fprintf(fout, "%-s%*s |\n", dlineptr[line_count].ptr,
- dwidth - dlineptr[line_count].width, "");
+ fprintf(fout, "%-s%*s %s\n", dlineptr[line_count].ptr,
+ dwidth - dlineptr[line_count].width, "",
+ dformat->rightvrule);
}
if (!dlineptr[line_count + 1].ptr)
@@ -1146,7 +1234,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (opt_border < 2)
fputc('\n', fout);
else
- fprintf(fout, "%*s |\n", dwidth, "");
+ fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule);
}
line_count++;
}
@@ -1155,7 +1243,8 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (cont->opt->stop_table)
{
if (opt_border == 2 && !cancel_pressed)
- fprintf(fout, "%s\n", divider);
+ print_aligned_vertical_line(cont, 0, hwidth, dwidth,
+ PRINT_RULE_BOTTOM, fout);
/* print footers */
if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
@@ -1171,7 +1260,6 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
fputc('\n', fout);
}
- free(divider);
free(hlineptr->ptr);
free(dlineptr->ptr);
free(hlineptr);
@@ -2387,6 +2475,18 @@ setDecimalLocale(void)
thousands_sep = ".";
}
+/* get selected or default line style */
+const printTextFormat *
+get_line_style(const printTableOpt *opt)
+{
+ if (opt->line_style != NULL)
+ return opt->line_style;
+ else if (opt->encoding == pg_get_utf8_id())
+ return &pg_utf8format;
+ else
+ return &pg_asciiformat;
+}
+
/*
* Compute the byte distance to the end of the string or *target_width
* display character positions, whichever comes first. Update *target_width
diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h
index 13e53e0dad0..b09aac90f77 100644
--- a/src/bin/psql/print.h
+++ b/src/bin/psql/print.h
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/print.h,v 1.40 2009/06/11 14:49:08 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/print.h,v 1.41 2009/10/13 21:04:01 tgl Exp $
*/
#ifndef PRINT_H
#define PRINT_H
@@ -23,10 +23,37 @@ enum printFormat
/* add your favourite output format here ... */
};
+typedef struct printTextLineFormat
+{
+ /* Line drawing characters to be used in various contexts */
+ const char *hrule; /* horizontal line character */
+ const char *leftvrule; /* left vertical line (+horizontal) */
+ const char *midvrule; /* intra-column vertical line (+horizontal) */
+ const char *rightvrule; /* right vertical line (+horizontal) */
+} printTextLineFormat;
+
+typedef enum printTextRule
+{
+ /* Additional context for selecting line drawing characters */
+ PRINT_RULE_TOP, /* top horizontal line */
+ PRINT_RULE_MIDDLE, /* intra-data horizontal line */
+ PRINT_RULE_BOTTOM, /* bottom horizontal line */
+ PRINT_RULE_DATA /* data line (hrule is unused here) */
+} printTextRule;
+
+typedef struct printTextFormat
+{
+ /* A complete line style */
+ const char *name; /* for display purposes */
+ printTextLineFormat lrule[4]; /* indexed by enum printTextRule */
+ const char *midvrule_cont; /* vertical line for continue after newline */
+ const char *midvrule_wrap; /* vertical line for wrapped data */
+ const char *midvrule_blank; /* vertical line for blank data */
+} printTextFormat;
typedef struct printTableOpt
{
- enum printFormat format; /* one of the above */
+ enum printFormat format; /* see enum above */
bool expanded; /* expanded/vertical output (if supported by
* output format) */
unsigned short int border; /* Print a border around the table. 0=none,
@@ -37,6 +64,7 @@ typedef struct printTableOpt
bool start_table; /* print start decoration, eg <table> */
bool stop_table; /* print stop decoration, eg </table> */
unsigned long prior_records; /* start offset for record counters */
+ const printTextFormat *line_style; /* line style (NULL for default) */
char *fieldSep; /* field separator for unaligned text mode */
char *recordSep; /* record separator for unaligned text mode */
bool numericLocale; /* locale-aware numeric units separator and
@@ -96,6 +124,10 @@ typedef struct printQueryOpt
} printQueryOpt;
+extern const printTextFormat pg_asciiformat;
+extern const printTextFormat pg_utf8format;
+
+
extern FILE *PageOutput(int lines, unsigned short int pager);
extern void ClosePager(FILE *pagerpipe);
@@ -118,6 +150,7 @@ extern void printQuery(const PGresult *result, const printQueryOpt *opt,
FILE *fout, FILE *flog);
extern void setDecimalLocale(void);
+extern const printTextFormat *get_line_style(const printTableOpt *opt);
#ifndef __CYGWIN__
#define DEFAULT_PAGER "more"
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 2996eb78099..7cd07574151 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.186 2009/10/08 16:34:01 alvherre Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.187 2009/10/13 21:04:01 tgl Exp $
*/
/*----------------------------------------------------------------------
@@ -2264,8 +2264,8 @@ psql_completion(char *text, int start, int end)
{
static const char *const my_list[] =
{"format", "border", "expanded",
- "null", "fieldsep", "tuples_only", "title", "tableattr", "pager",
- "recordsep", NULL};
+ "null", "fieldsep", "tuples_only", "title", "tableattr",
+ "linestyle", "pager", "recordsep", NULL};
COMPLETE_WITH_LIST(my_list);
}
diff --git a/src/test/regress/pg_regress_main.c b/src/test/regress/pg_regress_main.c
index e068792eb3b..9dd99bc6b90 100644
--- a/src/test/regress/pg_regress_main.c
+++ b/src/test/regress/pg_regress_main.c
@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/test/regress/pg_regress_main.c,v 1.6 2009/06/11 14:49:15 momjian Exp $
+ * $PostgreSQL: pgsql/src/test/regress/pg_regress_main.c,v 1.7 2009/10/13 21:04:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -59,7 +59,7 @@ psql_start_test(const char *testname,
add_stringlist_item(expectfiles, expectfile);
snprintf(psql_cmd, sizeof(psql_cmd),
- SYSTEMQUOTE "\"%s%spsql\" -X -a -q -d \"%s\" < \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE,
+ SYSTEMQUOTE "\"%s%spsql\" -X -a -q -P linestyle=ascii -d \"%s\" < \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE,
psqldir ? psqldir : "",
psqldir ? "/" : "",
dblist->str,