]> granicus.if.org Git - postgresql/commitdiff
Add "\pset linestyle ascii/unicode" option to psql, allowing our traditional
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 13 Oct 2009 21:04:01 +0000 (21:04 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 13 Oct 2009 21:04:01 +0000 (21:04 +0000)
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

doc/src/sgml/ref/psql-ref.sgml
src/bin/psql/command.c
src/bin/psql/mbprint.c
src/bin/psql/mbprint.h
src/bin/psql/print.c
src/bin/psql/print.h
src/bin/psql/tab-complete.c
src/test/regress/pg_regress_main.c

index 88fd8b0b2923e67253570119d368c89bb4c07013..bbccb3b87b9581004a8d018ff8d9b45302521368 100644 (file)
@@ -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
 -->
 
@@ -1760,6 +1760,39 @@ lo_import 152801
           </listitem>
           </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>
index cea3942f013be4637cc5d8c946da4e15f6829233..6ce10caa2b8e476ef50cafce17634eae8aa80511 100644 (file)
@@ -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)
        {
index 4c33688e09acdf71e3197dceee61f9f867121a3b..2999d56ef6f725b44119c8f08832882ab324a992 100644 (file)
@@ -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
index 5ab1cbf045320ce1dc88dbdff7390821d4fc6f9e..4d5376c7cd60a2dd559d0acb3d6a253d1da67811 100644 (file)
@@ -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,
index 4260143c4474e6e936549f78ec58d8126a5372a4..80dd304f1ebabbcbb2ea19042b4cc26fb4fdd796 100644 (file)
@@ -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)
@@ -942,12 +993,71 @@ 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
index 13e53e0dad0ce2f0bc1b14f52af0b8c4cdf4b6a9..b09aac90f77714d4fdabc239f3402ee2299beb49 100644 (file)
@@ -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"
index 2996eb780999b60a2c30f4c429439c7f25fdb47c..7cd07574151f6841d0ce60c37698dee1f54b462e 100644 (file)
@@ -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);
        }
index e068792eb3bdbfb433a850dfb7ab03a044a7ae23..9dd99bc6b90d8c252c68a34831077237df9ad98c 100644 (file)
@@ -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,