proposal (9.5) : psql unicode border line styles
Hello
I am returning back to this topic. Last time I proposed styles:
/messages/by-id/CAFj8pRCLgoKtrYjPbToncpgyfTRcZ-ZgfOwdc1jquLB+eDe0Tw@mail.gmail.com
http://postgres.cz/wiki/Pretty_borders_in_psql
This experiment fails, but there are some interesting tips in discuss.
So I propose little bit different proposal - choose one predefined style
for any table lines elements. These styles are active only when "linestyle"
is unicode.
So possible line elements are:
* border,
* header_separator,
* row_separator,
* column_separator,
Possible styles (for each element)
* none,
* single,
* double,
* thick,
It should to have enough variability to define all styles proposed early. I
hope, so this proposal is secure and simple for usage. Styles should be
persistently saved in .psqlrc file - and some examples can be in
documentation.
Usage:
\pset linestyle_border double
\pset linestyle_header_separator single
\pset linestyle_row_separator single
\pset linestyle_column_separator single
\pset linestyle unicode
╔═══╤════════════╤═══════╗
║ a │ b │ c ║
╟───┼────────────┼───────╢
║ 1 │ 2012-05-24 │ Hello ║
╟───┼────────────┼───────╢
║ 2 │ 2012-05-25 │ Hello ║
║ │ │ World ║
╚═══╧════════════╧═══════╝
(2 rows)
Comments, ideas ?
Regards
Pavel
Hello
I had to reduce allowed line style to single or double, because unicode
allows only combination single,double or single,thick
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access
privileges
-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
=c/postgres +
| | | | |
postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
=c/postgres +
| | | | |
postgres=CTc/postgres
(3 rows)
postgres=# \pset border 2
Border style (border) is 2.
postgres=# \pset linestyle unicode
Line style (linestyle) is unicode.
postgres=# \l
List of databases
┌───────────┬──────────┬──────────┬─────────────┬─────────────┬───────────────────────┐
│ Name │ Owner │ Encoding │ Collate │ Ctype │ Access
privileges │
├───────────┼──────────┼──────────┼─────────────┼─────────────┼───────────────────────┤
│ postgres │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8
│ │
│ template0 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │
=c/postgres ↵│
│ │ │ │ │ │
postgres=CTc/postgres │
│ template1 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │
=c/postgres ↵│
│ │ │ │ │ │
postgres=CTc/postgres │
└───────────┴──────────┴──────────┴─────────────┴─────────────┴───────────────────────┘
(3 rows)
postgres=# \pset unicode_header_linestyle double
Unicode border linestyle is "double".
postgres=# \l
List of databases
┌───────────┬──────────┬──────────┬─────────────┬─────────────┬───────────────────────┐
│ Name │ Owner │ Encoding │ Collate │ Ctype │ Access
privileges │
╞═══════════╪══════════╪══════════╪═════════════╪═════════════╪═══════════════════════╡
│ postgres │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8
│ │
│ template0 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │
=c/postgres ↵│
│ │ │ │ │ │
postgres=CTc/postgres │
│ template1 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │
=c/postgres ↵│
│ │ │ │ │ │
postgres=CTc/postgres │
└───────────┴──────────┴──────────┴─────────────┴─────────────┴───────────────────────┘
(3 rows)
postgres=#
Regards
Pavel
2014-03-07 19:24 GMT+01:00 Pavel Stehule <pavel.stehule@gmail.com>:
Show quoted text
Hello
I am returning back to this topic. Last time I proposed styles:
/messages/by-id/CAFj8pRCLgoKtrYjPbToncpgyfTRcZ-ZgfOwdc1jquLB+eDe0Tw@mail.gmail.com
http://postgres.cz/wiki/Pretty_borders_in_psql
This experiment fails, but there are some interesting tips in discuss.
So I propose little bit different proposal - choose one predefined style
for any table lines elements. These styles are active only when "linestyle"
is unicode.So possible line elements are:
* border,
* header_separator,
* row_separator,
* column_separator,Possible styles (for each element)
* none,
* single,
* double,
* thick,It should to have enough variability to define all styles proposed early.
I hope, so this proposal is secure and simple for usage. Styles should be
persistently saved in .psqlrc file - and some examples can be in
documentation.Usage:
\pset linestyle_border double
\pset linestyle_header_separator single
\pset linestyle_row_separator single
\pset linestyle_column_separator single\pset linestyle unicode
╔═══╤════════════╤═══════╗
║ a │ b │ c ║
╟───┼────────────┼───────╢
║ 1 │ 2012-05-24 │ Hello ║
╟───┼────────────┼───────╢
║ 2 │ 2012-05-25 │ Hello ║
║ │ │ World ║
╚═══╧════════════╧═══════╝
(2 rows)Comments, ideas ?
Regards
Pavel
Attachments:
unicode_linestyle.patchtext/x-patch; charset=UTF-8; name=unicode_linestyle.patchDownload
From ea7a046afbd6f517b37606f3e52bd2e401d1fad2 Mon Sep 17 00:00:00 2001
From: Pavel Stehule <pavel.stehule@gooddata.com>
Date: Tue, 11 Mar 2014 20:57:08 +0100
Subject: [PATCH] initial
---
doc/src/sgml/ref/psql-ref.sgml | 36 ++++++++
src/bin/psql/command.c | 118 +++++++++++++++++++++++-
src/bin/psql/print.c | 199 ++++++++++++++++++++++++++++++++---------
src/bin/psql/print.h | 22 ++++-
src/bin/psql/startup.c | 5 ++
src/bin/psql/tab-complete.c | 13 ++-
6 files changed, 345 insertions(+), 48 deletions(-)
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 8813be8..3e7e748 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2273,6 +2273,42 @@ lo_import 152801
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_border_style</literal></term>
+ <listitem>
+ <para>
+ Sets the border line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_column_style</literal></term>
+ <listitem>
+ <para>
+ Sets the column line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_header_style</literal></term>
+ <listitem>
+ <para>
+ Sets the header line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index fd64ba8..0adccba 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1054,6 +1054,9 @@ exec_command(const char *cmd,
"footer", "format", "linestyle", "null",
"numericlocale", "pager", "recordsep",
"tableattr", "title", "tuples_only",
+ "unicode_border_linestyle",
+ "unicode_column_linestyle",
+ "unicode_header_linestyle",
NULL
};
@@ -2247,6 +2250,55 @@ _align2string(enum printFormat in)
return "unknown";
}
+/*
+ * Parse entered unicode linestyle. Returns true, when entered string is
+ * known linestyle: single, double else returns false.
+ */
+static bool
+set_unicode_line_style(const char *value, size_t vallen, unicode_linestyle *linestyle)
+{
+ if (pg_strncasecmp("single", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_SINGLE;
+ else if (pg_strncasecmp("double", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_DOUBLE;
+ else
+ return false;
+
+ return true;
+}
+
+static const char *
+_unicode_linestyle2string(int linestyle)
+{
+ switch (linestyle)
+ {
+ case UNICODE_LINESTYLE_SINGLE:
+ return "single";
+ break;
+ case UNICODE_LINESTYLE_DOUBLE:
+ return "double";
+ break;
+ }
+ return "unknown";
+}
+
+static const char *
+_linestyle2string(linestyle_type line_style)
+{
+ switch (line_style)
+ {
+ case LINESTYLE_ASCII:
+ return "ascii";
+ break;
+ case LINESTYLE_OLD_ASCII:
+ return "old-ascii";
+ break;
+ case LINESTYLE_UNICODE:
+ return "unicode";
+ break;
+ }
+ return "unknown";
+}
bool
do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
@@ -2291,11 +2343,11 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
if (!value)
;
else if (pg_strncasecmp("ascii", value, vallen) == 0)
- popt->topt.line_style = &pg_asciiformat;
+ popt->topt.line_style = LINESTYLE_ASCII;
else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
- popt->topt.line_style = &pg_asciiformat_old;
+ popt->topt.line_style = LINESTYLE_OLD_ASCII;
else if (pg_strncasecmp("unicode", value, vallen) == 0)
- popt->topt.line_style = &pg_utf8format;
+ popt->topt.line_style = LINESTYLE_UNICODE;
else
{
psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n");
@@ -2304,6 +2356,45 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
}
+ /* set unicode border line style */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(value, vallen, &popt->topt.unicode_border_linestyle))
+ {
+ psql_error("\\pset: allowed unicode border linestyle are single, double\n");
+ return false;
+ }
+
+ }
+
+ /* set unicode column line style */
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(value, vallen, &popt->topt.unicode_column_linestyle))
+ {
+ psql_error("\\pset: allowed unicode column linestyle are single, double\n");
+ return false;
+ }
+
+ }
+
+ /* set unicode header line style */
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(value, vallen, &popt->topt.unicode_header_linestyle))
+ {
+ psql_error("\\pset: allowed unicode header linestyle are single, double\n");
+ return false;
+ }
+
+ }
+
/* set border style/width */
else if (strcmp(param, "border") == 0)
{
@@ -2525,7 +2616,7 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
else if (strcmp(param, "linestyle") == 0)
{
printf(_("Line style (%s) is %s.\n"), param,
- get_line_style(&popt->topt)->name);
+ _linestyle2string(popt->topt.line_style));
}
/* show null display */
@@ -2600,6 +2691,25 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
printf(_("Tuples only (%s) is off.\n"), param);
}
+ /* unicode style formatting */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_border_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ printf(_("Unicode column linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_column_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_header_linestyle));
+ }
+
else
{
psql_error("\\pset: unknown option: %s\n", param);
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 79fc43e..a6f77c13 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -49,7 +49,6 @@ static printTableFooter default_footer_cell = {default_footer, NULL};
/* Line style control structures */
const printTextFormat pg_asciiformat =
{
- "ascii",
{
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
@@ -65,12 +64,12 @@ const printTextFormat pg_asciiformat =
"+",
".",
".",
- true
+ true,
+ false
};
const printTextFormat pg_asciiformat_old =
{
- "old-ascii",
{
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
@@ -86,39 +85,85 @@ const printTextFormat pg_asciiformat_old =
" ",
" ",
" ",
+ false,
false
};
-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"}
+typedef struct unicodeStyleRowFormat {
+ const char *horizontal;
+ const char *vertical_and_right[2];
+ const char *vertical_and_left[2];
+} unicodeStyleRowFormat;
+
+typedef struct unicodeStyleColumnFormat {
+ const char *vertical;
+ const char *vertical_and_horizontal[2];
+ const char *up_and_horizontal[2];
+ const char *down_and_horizontal[2];
+} unicodeStyleColumnFormat;
+
+typedef struct unicodeStyleBorderFormat {
+ const char *up_and_right;
+ const char *vertical;
+ const char *down_and_right;
+ const char *horizontal;
+ const char *down_and_left;
+ const char *left_and_right;
+} unicodeStyleBorderFormat;
+
+typedef struct unicodeStyleFormat {
+ unicodeStyleRowFormat row_style[2];
+ unicodeStyleColumnFormat column_style[2];
+ unicodeStyleBorderFormat border_style[2];
+} unicodeStyleFormat;
+
+const unicodeStyleFormat unicode_style = {
+ {
+ {
+ /* ─ */
+ "\342\224\200",
+ /* ├╟ */
+ {"\342\224\234", "\342\225\237"},
+ /* ┤╢ */
+ {"\342\224\244", "\342\225\242"},
+ },
+ {
+ /* ═ */
+ "\342\225\220",
+ /* ╞╠ */
+ {"\342\225\236", "\342\225\240"},
+ /* ╡╣ */
+ {"\342\225\241", "\342\225\243"},
+ },
+ },
+ {
+ {
+ /* │ */
+ "\342\224\202",
+ /* ┼╪ */
+ {"\342\224\274", "\342\225\252"},
+ /* ┴╧ */
+ {"\342\224\264", "\342\225\247"},
+ /* ┬╤ */
+ {"\342\224\254", "\342\225\244"},
+ },
+ {
+ /* ║ */
+ "\342\225\221",
+ /* ╫╬ */
+ {"\342\225\253", "\342\225\254"},
+ /* ╨╩ */
+ {"\342\225\250", "\342\225\251"},
+ /* ╥╦ */
+ {"\342\225\245", "\342\225\246"},
+ },
+ },
+ {
+ /* └│┌─┐┘ */
+ {"\342\224\224", "\342\224\202", "\342\224\214", "\342\224\200", "\342\224\220", "\342\224\230"},
+ /* ╚║╔═╗╝ */
+ {"\342\225\232", "\342\225\221", "\342\225\224", "\342\225\220", "\342\225\227", "\342\225\235"},
},
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- " ",
- /* ↵ */
- "\342\206\265",
- " ",
- /* ↵ */
- "\342\206\265",
- /* … */
- "\342\200\246",
- /* … */
- "\342\200\246",
- true
};
@@ -128,6 +173,7 @@ static void IsPagerNeeded(const printTableContent *cont, const int extra_lines,
FILE **fout, bool *is_pager);
static void print_aligned_vertical(const printTableContent *cont, FILE *fout);
+static printTextFormat * prepare_unicode_format(const printTableOpt *opt);
static int
@@ -503,7 +549,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
bool opt_tuples_only = cont->opt->tuples_only;
int encoding = cont->opt->encoding;
unsigned short opt_border = cont->opt->border;
- const printTextFormat *format = get_line_style(cont->opt);
+ printTextFormat *format = get_line_style(cont->opt);
const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
unsigned int col_count = 0,
@@ -1081,6 +1127,9 @@ cleanup:
if (is_pager)
ClosePager(fout);
+
+ if (format->free_format)
+ free(format);
}
@@ -1092,7 +1141,7 @@ print_aligned_vertical_line(const printTableContent *cont,
printTextRule pos,
FILE *fout)
{
- const printTextFormat *format = get_line_style(cont->opt);
+ printTextFormat *format = get_line_style(cont->opt);
const printTextLineFormat *lformat = &format->lrule[pos];
unsigned short opt_border = cont->opt->border;
unsigned int i;
@@ -1139,6 +1188,9 @@ print_aligned_vertical_line(const printTableContent *cont,
if (opt_border == 2)
fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
fputc('\n', fout);
+
+ if (format->free_format)
+ free(format);
}
static void
@@ -1146,7 +1198,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
{
bool opt_tuples_only = cont->opt->tuples_only;
unsigned short opt_border = cont->opt->border;
- const printTextFormat *format = get_line_style(cont->opt);
+ 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;
@@ -1342,6 +1394,9 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (is_pager)
ClosePager(fout);
+
+ if (format->free_format)
+ free(format);
}
@@ -2695,7 +2750,7 @@ setDecimalLocale(void)
}
/* get selected or default line style */
-const printTextFormat *
+printTextFormat *
get_line_style(const printTableOpt *opt)
{
/*
@@ -2703,10 +2758,74 @@ get_line_style(const printTableOpt *opt)
* printTableOpt struct can be initialized to zeroes to get default
* behavior.
*/
- if (opt->line_style != NULL)
- return opt->line_style;
- else
- return &pg_asciiformat;
+ switch (opt->line_style)
+ {
+ case LINESTYLE_ASCII:
+ return &pg_asciiformat;
+ case LINESTYLE_OLD_ASCII:
+ return &pg_asciiformat_old;
+ case LINESTYLE_UNICODE:
+ return prepare_unicode_format(opt);
+ }
+}
+
+static printTextFormat *
+prepare_unicode_format(const printTableOpt *opt)
+{
+ printTextFormat *popt;
+
+ unicodeStyleBorderFormat *border;
+ unicodeStyleRowFormat *header;
+ unicodeStyleColumnFormat *column;
+
+ border = &unicode_style.border_style[opt->unicode_border_linestyle];
+ header = &unicode_style.row_style[opt->unicode_header_linestyle];
+ column = &unicode_style.column_style[opt->unicode_column_linestyle];
+
+ popt = pg_malloc(sizeof(printTextFormat));
+
+ popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_TOP].leftvrule = border->down_and_right;
+ popt->lrule[PRINT_RULE_TOP].midvrule = column->down_and_horizontal[opt->unicode_border_linestyle];;
+ popt->lrule[PRINT_RULE_TOP].rightvrule = border->down_and_left;
+
+ popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
+ popt->lrule[PRINT_RULE_MIDDLE].leftvrule = header->vertical_and_right[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].midvrule = column->vertical_and_horizontal[opt->unicode_header_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].rightvrule = header->vertical_and_left[opt->unicode_border_linestyle];
+
+ popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_BOTTOM].leftvrule = border->up_and_right;
+ popt->lrule[PRINT_RULE_BOTTOM].midvrule = column->up_and_horizontal[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_BOTTOM].rightvrule = border->left_and_right;
+
+ /* N/A */
+ popt->lrule[PRINT_RULE_DATA].hrule = "";
+ popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
+ popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
+ popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
+
+ popt->midvrule_nl = column->vertical;
+ popt->midvrule_wrap = column->vertical;
+ popt->midvrule_blank = column->vertical;
+ popt->header_nl_left = " ";
+
+ /* ↵ */
+ popt->header_nl_right = "\342\206\265";
+
+ popt->nl_left = " ";
+
+ /* ↵ */
+ popt->nl_right = "\342\206\265";
+
+ /* … */
+ popt->wrap_left = "\342\200\246";
+ popt->wrap_right = "\342\200\246";
+
+ popt->wrap_right_border = true;
+ popt->free_format = true;
+
+ return popt;
}
/*
diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h
index 87b2856..7e1f2f7 100644
--- a/src/bin/psql/print.h
+++ b/src/bin/psql/print.h
@@ -53,7 +53,6 @@ typedef enum printTextLineWrap
typedef struct printTextFormat
{
/* A complete line style */
- const char *name; /* for display purposes */
printTextLineFormat lrule[4]; /* indexed by enum printTextRule */
const char *midvrule_nl; /* vertical line for continue after newline */
const char *midvrule_wrap; /* vertical line for wrapped data */
@@ -66,8 +65,22 @@ typedef struct printTextFormat
const char *wrap_right; /* right mark for wrapped data */
bool wrap_right_border; /* use right-hand border for wrap
* marks when border=0? */
+ bool free_format; /* true, when format should be released after usage */
} printTextFormat;
+typedef enum unicode_linestyle
+{
+ UNICODE_LINESTYLE_SINGLE = 0, /* to make sure someone initializes this */
+ UNICODE_LINESTYLE_DOUBLE = 1
+} unicode_linestyle;
+
+typedef enum linestyle_type
+{
+ LINESTYLE_ASCII = 0,
+ LINESTYLE_OLD_ASCII,
+ LINESTYLE_UNICODE
+} linestyle_type;
+
struct separator
{
char *separator;
@@ -88,7 +101,7 @@ typedef struct printTableOpt
bool stop_table; /* print stop decoration, eg </table> */
bool default_footer; /* allow "(xx rows)" default footer */
unsigned long prior_records; /* start offset for record counters */
- const printTextFormat *line_style; /* line style (NULL for default) */
+ linestyle_type line_style; /* line style */
struct separator fieldSep; /* field separator for unaligned text mode */
struct separator recordSep; /* record separator for unaligned text mode */
bool numericLocale; /* locale-aware numeric units separator and
@@ -97,6 +110,9 @@ typedef struct printTableOpt
int encoding; /* character encoding */
int env_columns; /* $COLUMNS on psql start, 0 is unset */
int columns; /* target width for wrapped format */
+ unicode_linestyle unicode_border_linestyle;
+ unicode_linestyle unicode_column_linestyle;
+ unicode_linestyle unicode_header_linestyle;
} printTableOpt;
/*
@@ -177,7 +193,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);
+extern printTextFormat *get_line_style(const printTableOpt *opt);
#ifndef __CYGWIN__
#define DEFAULT_PAGER "more"
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index d5f1c0d..960bc9c 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -128,6 +128,11 @@ main(int argc, char *argv[])
pset.popt.topt.start_table = true;
pset.popt.topt.stop_table = true;
pset.popt.topt.default_footer = true;
+
+ pset.popt.topt.unicode_border_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_column_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_header_linestyle = UNICODE_LINESTYLE_SINGLE;
+
/* We must get COLUMNS here before readline() sets it */
pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 1d69b95..430a327 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3371,7 +3371,8 @@ psql_completion(char *text, int start, int end)
{"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
"footer", "format", "linestyle", "null", "numericlocale",
"pager", "recordsep", "recordsep_zero", "tableattr", "title",
- "tuples_only", NULL};
+ "tuples_only", "unicode_border_linestyle", "unicode_column_linestyle",
+ "unicode_header_linestyle", NULL};
COMPLETE_WITH_LIST_CS(my_list);
}
@@ -3392,6 +3393,16 @@ psql_completion(char *text, int start, int end)
COMPLETE_WITH_LIST_CS(my_list);
}
+ else if (strcmp(prev_wd, "unicode_border_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_column_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_header_linestyle") == 0)
+ {
+ static const char *const my_list[] =
+ {"single", "double", NULL};
+
+ COMPLETE_WITH_LIST_CS(my_list);
+
+ }
}
else if (strcmp(prev_wd, "\\set") == 0)
{
--
1.8.5.3
Hello
rebase for 9.5
test:
\pset linestyle unicode \pset border 2
\pset unicode_header_linestyle double
\l
Regards
Pavel
2014-03-11 21:17 GMT+01:00 Pavel Stehule <pavel.stehule@gmail.com>:
Show quoted text
Hello
I had to reduce allowed line style to single or double, because unicode
allows only combination single,double or single,thickpostgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access
privileges-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
=c/postgres +
| | | | |
postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
=c/postgres +
| | | | |
postgres=CTc/postgres
(3 rows)postgres=# \pset border 2
Border style (border) is 2.
postgres=# \pset linestyle unicode
Line style (linestyle) is unicode.
postgres=# \l
List of databases┌───────────┬──────────┬──────────┬─────────────┬─────────────┬───────────────────────┐
│ Name │ Owner │ Encoding │ Collate │ Ctype │ Access
privileges │├───────────┼──────────┼──────────┼─────────────┼─────────────┼───────────────────────┤
│ postgres │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8
│ │
│ template0 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │
=c/postgres ↵│
│ │ │ │ │ │
postgres=CTc/postgres │
│ template1 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │
=c/postgres ↵│
│ │ │ │ │ │
postgres=CTc/postgres │└───────────┴──────────┴──────────┴─────────────┴─────────────┴───────────────────────┘
(3 rows)postgres=# \pset unicode_header_linestyle double
Unicode border linestyle is "double".
postgres=# \l
List of databases┌───────────┬──────────┬──────────┬─────────────┬─────────────┬───────────────────────┐
│ Name │ Owner │ Encoding │ Collate │ Ctype │ Access
privileges │╞═══════════╪══════════╪══════════╪═════════════╪═════════════╪═══════════════════════╡
│ postgres │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8
│ │
│ template0 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │
=c/postgres ↵│
│ │ │ │ │ │
postgres=CTc/postgres │
│ template1 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │
=c/postgres ↵│
│ │ │ │ │ │
postgres=CTc/postgres │└───────────┴──────────┴──────────┴─────────────┴─────────────┴───────────────────────┘
(3 rows)postgres=#
Regards
Pavel
2014-03-07 19:24 GMT+01:00 Pavel Stehule <pavel.stehule@gmail.com>:
Hello
I am returning back to this topic. Last time I proposed styles:
/messages/by-id/CAFj8pRCLgoKtrYjPbToncpgyfTRcZ-ZgfOwdc1jquLB+eDe0Tw@mail.gmail.com
http://postgres.cz/wiki/Pretty_borders_in_psql
This experiment fails, but there are some interesting tips in discuss.
So I propose little bit different proposal - choose one predefined style
for any table lines elements. These styles are active only when "linestyle"
is unicode.So possible line elements are:
* border,
* header_separator,
* row_separator,
* column_separator,Possible styles (for each element)
* none,
* single,
* double,
* thick,It should to have enough variability to define all styles proposed early.
I hope, so this proposal is secure and simple for usage. Styles should be
persistently saved in .psqlrc file - and some examples can be in
documentation.Usage:
\pset linestyle_border double
\pset linestyle_header_separator single
\pset linestyle_row_separator single
\pset linestyle_column_separator single\pset linestyle unicode
╔═══╤════════════╤═══════╗
║ a │ b │ c ║
╟───┼────────────┼───────╢
║ 1 │ 2012-05-24 │ Hello ║
╟───┼────────────┼───────╢
║ 2 │ 2012-05-25 │ Hello ║
║ │ │ World ║
╚═══╧════════════╧═══════╝
(2 rows)Comments, ideas ?
Regards
Pavel
Attachments:
unicode_linestyle-01.patchtext/x-patch; charset=UTF-8; name=unicode_linestyle-01.patchDownload
commit 8f0918a42b095df6a8e5fc981a2947cc54b14404
Author: Pavel Stehule <pavel.stehule@gooddata.com>
Date: Sat Jun 28 21:25:45 2014 +0200
rebase for 9.5 and clean warnings
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index ee6ec3a..671259f 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2281,6 +2281,42 @@ lo_import 152801
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_border_style</literal></term>
+ <listitem>
+ <para>
+ Sets the border line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_column_style</literal></term>
+ <listitem>
+ <para>
+ Sets the column line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_header_style</literal></term>
+ <listitem>
+ <para>
+ Sets the header line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index cede72a..8cbf10b 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1054,6 +1054,9 @@ exec_command(const char *cmd,
"footer", "format", "linestyle", "null",
"numericlocale", "pager", "recordsep",
"tableattr", "title", "tuples_only",
+ "unicode_border_linestyle",
+ "unicode_column_linestyle",
+ "unicode_header_linestyle",
NULL
};
@@ -2247,6 +2250,55 @@ _align2string(enum printFormat in)
return "unknown";
}
+/*
+ * Parse entered unicode linestyle. Returns true, when entered string is
+ * known linestyle: single, double else returns false.
+ */
+static bool
+set_unicode_line_style(const char *value, size_t vallen, unicode_linestyle *linestyle)
+{
+ if (pg_strncasecmp("single", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_SINGLE;
+ else if (pg_strncasecmp("double", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_DOUBLE;
+ else
+ return false;
+
+ return true;
+}
+
+static const char *
+_unicode_linestyle2string(int linestyle)
+{
+ switch (linestyle)
+ {
+ case UNICODE_LINESTYLE_SINGLE:
+ return "single";
+ break;
+ case UNICODE_LINESTYLE_DOUBLE:
+ return "double";
+ break;
+ }
+ return "unknown";
+}
+
+static const char *
+_linestyle2string(linestyle_type line_style)
+{
+ switch (line_style)
+ {
+ case LINESTYLE_ASCII:
+ return "ascii";
+ break;
+ case LINESTYLE_OLD_ASCII:
+ return "old-ascii";
+ break;
+ case LINESTYLE_UNICODE:
+ return "unicode";
+ break;
+ }
+ return "unknown";
+}
bool
do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
@@ -2291,11 +2343,11 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
if (!value)
;
else if (pg_strncasecmp("ascii", value, vallen) == 0)
- popt->topt.line_style = &pg_asciiformat;
+ popt->topt.line_style = LINESTYLE_ASCII;
else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
- popt->topt.line_style = &pg_asciiformat_old;
+ popt->topt.line_style = LINESTYLE_OLD_ASCII;
else if (pg_strncasecmp("unicode", value, vallen) == 0)
- popt->topt.line_style = &pg_utf8format;
+ popt->topt.line_style = LINESTYLE_UNICODE;
else
{
psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n");
@@ -2304,6 +2356,45 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
}
+ /* set unicode border line style */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(value, vallen, &popt->topt.unicode_border_linestyle))
+ {
+ psql_error("\\pset: allowed unicode border linestyle are single, double\n");
+ return false;
+ }
+
+ }
+
+ /* set unicode column line style */
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(value, vallen, &popt->topt.unicode_column_linestyle))
+ {
+ psql_error("\\pset: allowed unicode column linestyle are single, double\n");
+ return false;
+ }
+
+ }
+
+ /* set unicode header line style */
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(value, vallen, &popt->topt.unicode_header_linestyle))
+ {
+ psql_error("\\pset: allowed unicode header linestyle are single, double\n");
+ return false;
+ }
+
+ }
+
/* set border style/width */
else if (strcmp(param, "border") == 0)
{
@@ -2525,7 +2616,7 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
else if (strcmp(param, "linestyle") == 0)
{
printf(_("Line style (%s) is %s.\n"), param,
- get_line_style(&popt->topt)->name);
+ _linestyle2string(popt->topt.line_style));
}
/* show null display */
@@ -2600,6 +2691,25 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
printf(_("Tuples only (%s) is off.\n"), param);
}
+ /* unicode style formatting */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_border_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ printf(_("Unicode column linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_column_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_header_linestyle));
+ }
+
else
{
psql_error("\\pset: unknown option: %s\n", param);
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 62850d8..6b2f349 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -49,7 +49,6 @@ static printTableFooter default_footer_cell = {default_footer, NULL};
/* Line style control structures */
const printTextFormat pg_asciiformat =
{
- "ascii",
{
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
@@ -65,12 +64,12 @@ const printTextFormat pg_asciiformat =
"+",
".",
".",
- true
+ true,
+ false
};
const printTextFormat pg_asciiformat_old =
{
- "old-ascii",
{
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
@@ -86,39 +85,85 @@ const printTextFormat pg_asciiformat_old =
" ",
" ",
" ",
+ false,
false
};
-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"}
+typedef struct unicodeStyleRowFormat {
+ const char *horizontal;
+ const char *vertical_and_right[2];
+ const char *vertical_and_left[2];
+} unicodeStyleRowFormat;
+
+typedef struct unicodeStyleColumnFormat {
+ const char *vertical;
+ const char *vertical_and_horizontal[2];
+ const char *up_and_horizontal[2];
+ const char *down_and_horizontal[2];
+} unicodeStyleColumnFormat;
+
+typedef struct unicodeStyleBorderFormat {
+ const char *up_and_right;
+ const char *vertical;
+ const char *down_and_right;
+ const char *horizontal;
+ const char *down_and_left;
+ const char *left_and_right;
+} unicodeStyleBorderFormat;
+
+typedef struct unicodeStyleFormat {
+ unicodeStyleRowFormat row_style[2];
+ unicodeStyleColumnFormat column_style[2];
+ unicodeStyleBorderFormat border_style[2];
+} unicodeStyleFormat;
+
+const unicodeStyleFormat unicode_style = {
+ {
+ {
+ /* ─ */
+ "\342\224\200",
+ /* ├╟ */
+ {"\342\224\234", "\342\225\237"},
+ /* ┤╢ */
+ {"\342\224\244", "\342\225\242"},
+ },
+ {
+ /* ═ */
+ "\342\225\220",
+ /* ╞╠ */
+ {"\342\225\236", "\342\225\240"},
+ /* ╡╣ */
+ {"\342\225\241", "\342\225\243"},
+ },
+ },
+ {
+ {
+ /* │ */
+ "\342\224\202",
+ /* ┼╪ */
+ {"\342\224\274", "\342\225\252"},
+ /* ┴╧ */
+ {"\342\224\264", "\342\225\247"},
+ /* ┬╤ */
+ {"\342\224\254", "\342\225\244"},
+ },
+ {
+ /* ║ */
+ "\342\225\221",
+ /* ╫╬ */
+ {"\342\225\253", "\342\225\254"},
+ /* ╨╩ */
+ {"\342\225\250", "\342\225\251"},
+ /* ╥╦ */
+ {"\342\225\245", "\342\225\246"},
+ },
+ },
+ {
+ /* └│┌─┐┘ */
+ {"\342\224\224", "\342\224\202", "\342\224\214", "\342\224\200", "\342\224\220", "\342\224\230"},
+ /* ╚║╔═╗╝ */
+ {"\342\225\232", "\342\225\221", "\342\225\224", "\342\225\220", "\342\225\227", "\342\225\235"},
},
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- " ",
- /* ↵ */
- "\342\206\265",
- " ",
- /* ↵ */
- "\342\206\265",
- /* … */
- "\342\200\246",
- /* … */
- "\342\200\246",
- true
};
@@ -128,6 +173,7 @@ static void IsPagerNeeded(const printTableContent *cont, const int extra_lines,
FILE **fout, bool *is_pager);
static void print_aligned_vertical(const printTableContent *cont, FILE *fout);
+static printTextFormat * prepare_unicode_format(const printTableOpt *opt);
static int
@@ -503,7 +549,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
bool opt_tuples_only = cont->opt->tuples_only;
int encoding = cont->opt->encoding;
unsigned short opt_border = cont->opt->border;
- const printTextFormat *format = get_line_style(cont->opt);
+ printTextFormat *format = get_line_style(cont->opt);
const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
unsigned int col_count = 0,
@@ -1081,6 +1127,9 @@ cleanup:
if (is_pager)
ClosePager(fout);
+
+ if (format->free_format)
+ free(format);
}
@@ -1092,7 +1141,7 @@ print_aligned_vertical_line(const printTableContent *cont,
printTextRule pos,
FILE *fout)
{
- const printTextFormat *format = get_line_style(cont->opt);
+ printTextFormat *format = get_line_style(cont->opt);
const printTextLineFormat *lformat = &format->lrule[pos];
unsigned short opt_border = cont->opt->border;
unsigned int i;
@@ -1139,6 +1188,9 @@ print_aligned_vertical_line(const printTableContent *cont,
if (opt_border == 2)
fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
fputc('\n', fout);
+
+ if (format->free_format)
+ free(format);
}
static void
@@ -1146,7 +1198,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
{
bool opt_tuples_only = cont->opt->tuples_only;
unsigned short opt_border = cont->opt->border;
- const printTextFormat *format = get_line_style(cont->opt);
+ 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;
@@ -1487,6 +1539,9 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (is_pager)
ClosePager(fout);
+
+ if (format->free_format)
+ free(format);
}
@@ -2840,7 +2895,7 @@ setDecimalLocale(void)
}
/* get selected or default line style */
-const printTextFormat *
+printTextFormat *
get_line_style(const printTableOpt *opt)
{
/*
@@ -2848,10 +2903,78 @@ get_line_style(const printTableOpt *opt)
* printTableOpt struct can be initialized to zeroes to get default
* behavior.
*/
- if (opt->line_style != NULL)
- return opt->line_style;
- else
- return &pg_asciiformat;
+ switch (opt->line_style)
+ {
+ case LINESTYLE_ASCII:
+ return (printTextFormat *) &pg_asciiformat;
+ case LINESTYLE_OLD_ASCII:
+ return (printTextFormat *) &pg_asciiformat_old;
+ case LINESTYLE_UNICODE:
+ return prepare_unicode_format(opt);
+ default:
+ /* can't get here */
+ fprintf(stderr, "invalid line style\n");
+ exit(1);
+ }
+}
+
+static printTextFormat *
+prepare_unicode_format(const printTableOpt *opt)
+{
+ printTextFormat *popt;
+
+ const unicodeStyleBorderFormat *border;
+ const unicodeStyleRowFormat *header;
+ const unicodeStyleColumnFormat *column;
+
+ border = &unicode_style.border_style[opt->unicode_border_linestyle];
+ header = &unicode_style.row_style[opt->unicode_header_linestyle];
+ column = &unicode_style.column_style[opt->unicode_column_linestyle];
+
+ popt = pg_malloc(sizeof(printTextFormat));
+
+ popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_TOP].leftvrule = border->down_and_right;
+ popt->lrule[PRINT_RULE_TOP].midvrule = column->down_and_horizontal[opt->unicode_border_linestyle];;
+ popt->lrule[PRINT_RULE_TOP].rightvrule = border->down_and_left;
+
+ popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
+ popt->lrule[PRINT_RULE_MIDDLE].leftvrule = header->vertical_and_right[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].midvrule = column->vertical_and_horizontal[opt->unicode_header_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].rightvrule = header->vertical_and_left[opt->unicode_border_linestyle];
+
+ popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_BOTTOM].leftvrule = border->up_and_right;
+ popt->lrule[PRINT_RULE_BOTTOM].midvrule = column->up_and_horizontal[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_BOTTOM].rightvrule = border->left_and_right;
+
+ /* N/A */
+ popt->lrule[PRINT_RULE_DATA].hrule = "";
+ popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
+ popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
+ popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
+
+ popt->midvrule_nl = column->vertical;
+ popt->midvrule_wrap = column->vertical;
+ popt->midvrule_blank = column->vertical;
+ popt->header_nl_left = " ";
+
+ /* ↵ */
+ popt->header_nl_right = "\342\206\265";
+
+ popt->nl_left = " ";
+
+ /* ↵ */
+ popt->nl_right = "\342\206\265";
+
+ /* … */
+ popt->wrap_left = "\342\200\246";
+ popt->wrap_right = "\342\200\246";
+
+ popt->wrap_right_border = true;
+ popt->free_format = true;
+
+ return popt;
}
/*
diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h
index 87b2856..7e1f2f7 100644
--- a/src/bin/psql/print.h
+++ b/src/bin/psql/print.h
@@ -53,7 +53,6 @@ typedef enum printTextLineWrap
typedef struct printTextFormat
{
/* A complete line style */
- const char *name; /* for display purposes */
printTextLineFormat lrule[4]; /* indexed by enum printTextRule */
const char *midvrule_nl; /* vertical line for continue after newline */
const char *midvrule_wrap; /* vertical line for wrapped data */
@@ -66,8 +65,22 @@ typedef struct printTextFormat
const char *wrap_right; /* right mark for wrapped data */
bool wrap_right_border; /* use right-hand border for wrap
* marks when border=0? */
+ bool free_format; /* true, when format should be released after usage */
} printTextFormat;
+typedef enum unicode_linestyle
+{
+ UNICODE_LINESTYLE_SINGLE = 0, /* to make sure someone initializes this */
+ UNICODE_LINESTYLE_DOUBLE = 1
+} unicode_linestyle;
+
+typedef enum linestyle_type
+{
+ LINESTYLE_ASCII = 0,
+ LINESTYLE_OLD_ASCII,
+ LINESTYLE_UNICODE
+} linestyle_type;
+
struct separator
{
char *separator;
@@ -88,7 +101,7 @@ typedef struct printTableOpt
bool stop_table; /* print stop decoration, eg </table> */
bool default_footer; /* allow "(xx rows)" default footer */
unsigned long prior_records; /* start offset for record counters */
- const printTextFormat *line_style; /* line style (NULL for default) */
+ linestyle_type line_style; /* line style */
struct separator fieldSep; /* field separator for unaligned text mode */
struct separator recordSep; /* record separator for unaligned text mode */
bool numericLocale; /* locale-aware numeric units separator and
@@ -97,6 +110,9 @@ typedef struct printTableOpt
int encoding; /* character encoding */
int env_columns; /* $COLUMNS on psql start, 0 is unset */
int columns; /* target width for wrapped format */
+ unicode_linestyle unicode_border_linestyle;
+ unicode_linestyle unicode_column_linestyle;
+ unicode_linestyle unicode_header_linestyle;
} printTableOpt;
/*
@@ -177,7 +193,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);
+extern printTextFormat *get_line_style(const printTableOpt *opt);
#ifndef __CYGWIN__
#define DEFAULT_PAGER "more"
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 45653a1..260d5fe 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -129,6 +129,11 @@ main(int argc, char *argv[])
pset.popt.topt.start_table = true;
pset.popt.topt.stop_table = true;
pset.popt.topt.default_footer = true;
+
+ pset.popt.topt.unicode_border_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_column_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_header_linestyle = UNICODE_LINESTYLE_SINGLE;
+
/* We must get COLUMNS here before readline() sets it */
pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index be5c3c5..51ab73e 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3565,7 +3565,8 @@ psql_completion(const char *text, int start, int end)
{"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
"footer", "format", "linestyle", "null", "numericlocale",
"pager", "recordsep", "recordsep_zero", "tableattr", "title",
- "tuples_only", NULL};
+ "tuples_only", "unicode_border_linestyle",
+ "unicode_column_linestyle", "unicode_header_linestyle", NULL};
COMPLETE_WITH_LIST_CS(my_list);
}
@@ -3586,6 +3587,16 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH_LIST_CS(my_list);
}
+ else if (strcmp(prev_wd, "unicode_border_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_column_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_header_linestyle") == 0)
+ {
+ static const char *const my_list[] =
+ {"single", "double", NULL};
+
+ COMPLETE_WITH_LIST_CS(my_list);
+
+ }
}
else if (strcmp(prev_wd, "\\set") == 0)
{
On 28.6.2014 21:29, Pavel Stehule wrote:
Hello
rebase for 9.5
test:
\pset linestyle unicode \pset border 2
\pset unicode_header_linestyle double\l
Regards
Pavel
I did a quick review of the patch today:
* it applies cleanly to current HEAD (no failures, small offsets)
* compiles and generally seems to work just fine
Two questions:
(1) Shouldn't the new options be listed in '\?' (as possible names for
"pset")? I mean, here:
\pset [NAME [VALUE]] set table output option
(NAME :=
{format|border|expanded|fieldsep|fieldsep_zero|footer|null|
numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager})
(2) I noticed this piece of code:
+typedef enum unicode_linestyle
+{
+ UNICODE_LINESTYLE_SINGLE = 0, /* to make sure someone initializes this */
+ UNICODE_LINESTYLE_DOUBLE = 1
+} unicode_linestyle;
Why are the values defined explicitly? These values are set by the
compiled automatically, so why set them manually? Only a few of the
other enums are defined explicitly, and most of them have to do that to
define different values (e.g. 0x01, 0x02, 0x04, ...).
I don't understand how the comment "to make sure someone initializes
this" explains the purpose?
regards
Tomas
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hi Tomas
2014-07-22 23:20 GMT+02:00 Tomas Vondra <tv@fuzzy.cz>:
On 28.6.2014 21:29, Pavel Stehule wrote:
Hello
rebase for 9.5
test:
\pset linestyle unicode \pset border 2
\pset unicode_header_linestyle double\l
Regards
Pavel
I did a quick review of the patch today:
* it applies cleanly to current HEAD (no failures, small offsets)
* compiles and generally seems to work just fineTwo questions:
(1) Shouldn't the new options be listed in '\?' (as possible names for
"pset")? I mean, here:\pset [NAME [VALUE]] set table output option
(NAME :=
{format|border|expanded|fieldsep|fieldsep_zero|footer|null|
numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager})
fixed
(2) I noticed this piece of code:
+typedef enum unicode_linestyle +{ + UNICODE_LINESTYLE_SINGLE = 0, /* to make sure someone initializes this */ + UNICODE_LINESTYLE_DOUBLE = 1 +} unicode_linestyle;Why are the values defined explicitly? These values are set by the
compiled automatically, so why set them manually? Only a few of the
other enums are defined explicitly, and most of them have to do that to
define different values (e.g. 0x01, 0x02, 0x04, ...).
this is useless - I removed it.
I don't understand how the comment "to make sure someone initializes
this" explains the purpose?
copy/paste error :( - removed
updated version is in attachment
Regards
Pavel
Show quoted text
regards
Tomas--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Attachments:
unicode_linestyle-02.patchtext/x-patch; charset=UTF-8; name=unicode_linestyle-02.patchDownload
commit fb99f3b1e12d7dfb203b70187e63647e5d0a674d
Author: Pavel Stehule <pavel.stehule@gooddata.com>
Date: Wed Jul 23 07:30:46 2014 +0200
second version - minor changes: help, remove bogus comment and not necessary exact enum specification
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index fa0d6f2..fc8a503 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2294,6 +2294,42 @@ lo_import 152801
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_border_style</literal></term>
+ <listitem>
+ <para>
+ Sets the border line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_column_style</literal></term>
+ <listitem>
+ <para>
+ Sets the column line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_header_style</literal></term>
+ <listitem>
+ <para>
+ Sets the header line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 161de75..c0a09b1 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1054,6 +1054,9 @@ exec_command(const char *cmd,
"footer", "format", "linestyle", "null",
"numericlocale", "pager", "recordsep",
"tableattr", "title", "tuples_only",
+ "unicode_border_linestyle",
+ "unicode_column_linestyle",
+ "unicode_header_linestyle",
NULL
};
@@ -2248,6 +2251,55 @@ _align2string(enum printFormat in)
return "unknown";
}
+/*
+ * Parse entered unicode linestyle. Returns true, when entered string is
+ * known linestyle: single, double else returns false.
+ */
+static bool
+set_unicode_line_style(const char *value, size_t vallen, unicode_linestyle *linestyle)
+{
+ if (pg_strncasecmp("single", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_SINGLE;
+ else if (pg_strncasecmp("double", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_DOUBLE;
+ else
+ return false;
+
+ return true;
+}
+
+static const char *
+_unicode_linestyle2string(int linestyle)
+{
+ switch (linestyle)
+ {
+ case UNICODE_LINESTYLE_SINGLE:
+ return "single";
+ break;
+ case UNICODE_LINESTYLE_DOUBLE:
+ return "double";
+ break;
+ }
+ return "unknown";
+}
+
+static const char *
+_linestyle2string(linestyle_type line_style)
+{
+ switch (line_style)
+ {
+ case LINESTYLE_ASCII:
+ return "ascii";
+ break;
+ case LINESTYLE_OLD_ASCII:
+ return "old-ascii";
+ break;
+ case LINESTYLE_UNICODE:
+ return "unicode";
+ break;
+ }
+ return "unknown";
+}
bool
do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
@@ -2292,11 +2344,11 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
if (!value)
;
else if (pg_strncasecmp("ascii", value, vallen) == 0)
- popt->topt.line_style = &pg_asciiformat;
+ popt->topt.line_style = LINESTYLE_ASCII;
else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
- popt->topt.line_style = &pg_asciiformat_old;
+ popt->topt.line_style = LINESTYLE_OLD_ASCII;
else if (pg_strncasecmp("unicode", value, vallen) == 0)
- popt->topt.line_style = &pg_utf8format;
+ popt->topt.line_style = LINESTYLE_UNICODE;
else
{
psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n");
@@ -2305,6 +2357,45 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
}
+ /* set unicode border line style */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(value, vallen, &popt->topt.unicode_border_linestyle))
+ {
+ psql_error("\\pset: allowed unicode border linestyle are single, double\n");
+ return false;
+ }
+
+ }
+
+ /* set unicode column line style */
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(value, vallen, &popt->topt.unicode_column_linestyle))
+ {
+ psql_error("\\pset: allowed unicode column linestyle are single, double\n");
+ return false;
+ }
+
+ }
+
+ /* set unicode header line style */
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(value, vallen, &popt->topt.unicode_header_linestyle))
+ {
+ psql_error("\\pset: allowed unicode header linestyle are single, double\n");
+ return false;
+ }
+
+ }
+
/* set border style/width */
else if (strcmp(param, "border") == 0)
{
@@ -2526,7 +2617,7 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
else if (strcmp(param, "linestyle") == 0)
{
printf(_("Line style (%s) is %s.\n"), param,
- get_line_style(&popt->topt)->name);
+ _linestyle2string(popt->topt.line_style));
}
/* show null display */
@@ -2601,6 +2692,25 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
printf(_("Tuples only (%s) is off.\n"), param);
}
+ /* unicode style formatting */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_border_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ printf(_("Unicode column linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_column_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_header_linestyle));
+ }
+
else
{
psql_error("\\pset: unknown option: %s\n", param);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index f8f000f..4ca7887 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -235,7 +235,8 @@ slashUsage(unsigned short int pager)
ON(pset.popt.topt.format == PRINT_HTML));
fprintf(output, _(" \\pset [NAME [VALUE]] set table output option\n"
" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n"
- " numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager})\n"));
+ " numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n"
+ " unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n"));
fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"),
ON(pset.popt.topt.tuples_only));
fprintf(output, _(" \\T [STRING] set HTML <table> tag attributes, or unset if none\n"));
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 62850d8..6b2f349 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -49,7 +49,6 @@ static printTableFooter default_footer_cell = {default_footer, NULL};
/* Line style control structures */
const printTextFormat pg_asciiformat =
{
- "ascii",
{
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
@@ -65,12 +64,12 @@ const printTextFormat pg_asciiformat =
"+",
".",
".",
- true
+ true,
+ false
};
const printTextFormat pg_asciiformat_old =
{
- "old-ascii",
{
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
@@ -86,39 +85,85 @@ const printTextFormat pg_asciiformat_old =
" ",
" ",
" ",
+ false,
false
};
-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"}
+typedef struct unicodeStyleRowFormat {
+ const char *horizontal;
+ const char *vertical_and_right[2];
+ const char *vertical_and_left[2];
+} unicodeStyleRowFormat;
+
+typedef struct unicodeStyleColumnFormat {
+ const char *vertical;
+ const char *vertical_and_horizontal[2];
+ const char *up_and_horizontal[2];
+ const char *down_and_horizontal[2];
+} unicodeStyleColumnFormat;
+
+typedef struct unicodeStyleBorderFormat {
+ const char *up_and_right;
+ const char *vertical;
+ const char *down_and_right;
+ const char *horizontal;
+ const char *down_and_left;
+ const char *left_and_right;
+} unicodeStyleBorderFormat;
+
+typedef struct unicodeStyleFormat {
+ unicodeStyleRowFormat row_style[2];
+ unicodeStyleColumnFormat column_style[2];
+ unicodeStyleBorderFormat border_style[2];
+} unicodeStyleFormat;
+
+const unicodeStyleFormat unicode_style = {
+ {
+ {
+ /* ─ */
+ "\342\224\200",
+ /* ├╟ */
+ {"\342\224\234", "\342\225\237"},
+ /* ┤╢ */
+ {"\342\224\244", "\342\225\242"},
+ },
+ {
+ /* ═ */
+ "\342\225\220",
+ /* ╞╠ */
+ {"\342\225\236", "\342\225\240"},
+ /* ╡╣ */
+ {"\342\225\241", "\342\225\243"},
+ },
+ },
+ {
+ {
+ /* │ */
+ "\342\224\202",
+ /* ┼╪ */
+ {"\342\224\274", "\342\225\252"},
+ /* ┴╧ */
+ {"\342\224\264", "\342\225\247"},
+ /* ┬╤ */
+ {"\342\224\254", "\342\225\244"},
+ },
+ {
+ /* ║ */
+ "\342\225\221",
+ /* ╫╬ */
+ {"\342\225\253", "\342\225\254"},
+ /* ╨╩ */
+ {"\342\225\250", "\342\225\251"},
+ /* ╥╦ */
+ {"\342\225\245", "\342\225\246"},
+ },
+ },
+ {
+ /* └│┌─┐┘ */
+ {"\342\224\224", "\342\224\202", "\342\224\214", "\342\224\200", "\342\224\220", "\342\224\230"},
+ /* ╚║╔═╗╝ */
+ {"\342\225\232", "\342\225\221", "\342\225\224", "\342\225\220", "\342\225\227", "\342\225\235"},
},
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- " ",
- /* ↵ */
- "\342\206\265",
- " ",
- /* ↵ */
- "\342\206\265",
- /* … */
- "\342\200\246",
- /* … */
- "\342\200\246",
- true
};
@@ -128,6 +173,7 @@ static void IsPagerNeeded(const printTableContent *cont, const int extra_lines,
FILE **fout, bool *is_pager);
static void print_aligned_vertical(const printTableContent *cont, FILE *fout);
+static printTextFormat * prepare_unicode_format(const printTableOpt *opt);
static int
@@ -503,7 +549,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
bool opt_tuples_only = cont->opt->tuples_only;
int encoding = cont->opt->encoding;
unsigned short opt_border = cont->opt->border;
- const printTextFormat *format = get_line_style(cont->opt);
+ printTextFormat *format = get_line_style(cont->opt);
const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
unsigned int col_count = 0,
@@ -1081,6 +1127,9 @@ cleanup:
if (is_pager)
ClosePager(fout);
+
+ if (format->free_format)
+ free(format);
}
@@ -1092,7 +1141,7 @@ print_aligned_vertical_line(const printTableContent *cont,
printTextRule pos,
FILE *fout)
{
- const printTextFormat *format = get_line_style(cont->opt);
+ printTextFormat *format = get_line_style(cont->opt);
const printTextLineFormat *lformat = &format->lrule[pos];
unsigned short opt_border = cont->opt->border;
unsigned int i;
@@ -1139,6 +1188,9 @@ print_aligned_vertical_line(const printTableContent *cont,
if (opt_border == 2)
fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
fputc('\n', fout);
+
+ if (format->free_format)
+ free(format);
}
static void
@@ -1146,7 +1198,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
{
bool opt_tuples_only = cont->opt->tuples_only;
unsigned short opt_border = cont->opt->border;
- const printTextFormat *format = get_line_style(cont->opt);
+ 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;
@@ -1487,6 +1539,9 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (is_pager)
ClosePager(fout);
+
+ if (format->free_format)
+ free(format);
}
@@ -2840,7 +2895,7 @@ setDecimalLocale(void)
}
/* get selected or default line style */
-const printTextFormat *
+printTextFormat *
get_line_style(const printTableOpt *opt)
{
/*
@@ -2848,10 +2903,78 @@ get_line_style(const printTableOpt *opt)
* printTableOpt struct can be initialized to zeroes to get default
* behavior.
*/
- if (opt->line_style != NULL)
- return opt->line_style;
- else
- return &pg_asciiformat;
+ switch (opt->line_style)
+ {
+ case LINESTYLE_ASCII:
+ return (printTextFormat *) &pg_asciiformat;
+ case LINESTYLE_OLD_ASCII:
+ return (printTextFormat *) &pg_asciiformat_old;
+ case LINESTYLE_UNICODE:
+ return prepare_unicode_format(opt);
+ default:
+ /* can't get here */
+ fprintf(stderr, "invalid line style\n");
+ exit(1);
+ }
+}
+
+static printTextFormat *
+prepare_unicode_format(const printTableOpt *opt)
+{
+ printTextFormat *popt;
+
+ const unicodeStyleBorderFormat *border;
+ const unicodeStyleRowFormat *header;
+ const unicodeStyleColumnFormat *column;
+
+ border = &unicode_style.border_style[opt->unicode_border_linestyle];
+ header = &unicode_style.row_style[opt->unicode_header_linestyle];
+ column = &unicode_style.column_style[opt->unicode_column_linestyle];
+
+ popt = pg_malloc(sizeof(printTextFormat));
+
+ popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_TOP].leftvrule = border->down_and_right;
+ popt->lrule[PRINT_RULE_TOP].midvrule = column->down_and_horizontal[opt->unicode_border_linestyle];;
+ popt->lrule[PRINT_RULE_TOP].rightvrule = border->down_and_left;
+
+ popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
+ popt->lrule[PRINT_RULE_MIDDLE].leftvrule = header->vertical_and_right[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].midvrule = column->vertical_and_horizontal[opt->unicode_header_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].rightvrule = header->vertical_and_left[opt->unicode_border_linestyle];
+
+ popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_BOTTOM].leftvrule = border->up_and_right;
+ popt->lrule[PRINT_RULE_BOTTOM].midvrule = column->up_and_horizontal[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_BOTTOM].rightvrule = border->left_and_right;
+
+ /* N/A */
+ popt->lrule[PRINT_RULE_DATA].hrule = "";
+ popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
+ popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
+ popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
+
+ popt->midvrule_nl = column->vertical;
+ popt->midvrule_wrap = column->vertical;
+ popt->midvrule_blank = column->vertical;
+ popt->header_nl_left = " ";
+
+ /* ↵ */
+ popt->header_nl_right = "\342\206\265";
+
+ popt->nl_left = " ";
+
+ /* ↵ */
+ popt->nl_right = "\342\206\265";
+
+ /* … */
+ popt->wrap_left = "\342\200\246";
+ popt->wrap_right = "\342\200\246";
+
+ popt->wrap_right_border = true;
+ popt->free_format = true;
+
+ return popt;
}
/*
diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h
index 87b2856..3d388de 100644
--- a/src/bin/psql/print.h
+++ b/src/bin/psql/print.h
@@ -53,7 +53,6 @@ typedef enum printTextLineWrap
typedef struct printTextFormat
{
/* A complete line style */
- const char *name; /* for display purposes */
printTextLineFormat lrule[4]; /* indexed by enum printTextRule */
const char *midvrule_nl; /* vertical line for continue after newline */
const char *midvrule_wrap; /* vertical line for wrapped data */
@@ -66,8 +65,22 @@ typedef struct printTextFormat
const char *wrap_right; /* right mark for wrapped data */
bool wrap_right_border; /* use right-hand border for wrap
* marks when border=0? */
+ bool free_format; /* true, when format should be released after usage */
} printTextFormat;
+typedef enum unicode_linestyle
+{
+ UNICODE_LINESTYLE_SINGLE = 0,
+ UNICODE_LINESTYLE_DOUBLE
+} unicode_linestyle;
+
+typedef enum linestyle_type
+{
+ LINESTYLE_ASCII = 0,
+ LINESTYLE_OLD_ASCII,
+ LINESTYLE_UNICODE
+} linestyle_type;
+
struct separator
{
char *separator;
@@ -88,7 +101,7 @@ typedef struct printTableOpt
bool stop_table; /* print stop decoration, eg </table> */
bool default_footer; /* allow "(xx rows)" default footer */
unsigned long prior_records; /* start offset for record counters */
- const printTextFormat *line_style; /* line style (NULL for default) */
+ linestyle_type line_style; /* line style */
struct separator fieldSep; /* field separator for unaligned text mode */
struct separator recordSep; /* record separator for unaligned text mode */
bool numericLocale; /* locale-aware numeric units separator and
@@ -97,6 +110,9 @@ typedef struct printTableOpt
int encoding; /* character encoding */
int env_columns; /* $COLUMNS on psql start, 0 is unset */
int columns; /* target width for wrapped format */
+ unicode_linestyle unicode_border_linestyle;
+ unicode_linestyle unicode_column_linestyle;
+ unicode_linestyle unicode_header_linestyle;
} printTableOpt;
/*
@@ -177,7 +193,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);
+extern printTextFormat *get_line_style(const printTableOpt *opt);
#ifndef __CYGWIN__
#define DEFAULT_PAGER "more"
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 5a397e8..a6514fb 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -129,6 +129,11 @@ main(int argc, char *argv[])
pset.popt.topt.start_table = true;
pset.popt.topt.stop_table = true;
pset.popt.topt.default_footer = true;
+
+ pset.popt.topt.unicode_border_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_column_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_header_linestyle = UNICODE_LINESTYLE_SINGLE;
+
/* We must get COLUMNS here before readline() sets it */
pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 24e60b7..569c802 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3582,7 +3582,8 @@ psql_completion(const char *text, int start, int end)
{"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
"footer", "format", "linestyle", "null", "numericlocale",
"pager", "recordsep", "recordsep_zero", "tableattr", "title",
- "tuples_only", NULL};
+ "tuples_only", "unicode_border_linestyle",
+ "unicode_column_linestyle", "unicode_header_linestyle", NULL};
COMPLETE_WITH_LIST_CS(my_list);
}
@@ -3603,6 +3604,16 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH_LIST_CS(my_list);
}
+ else if (strcmp(prev_wd, "unicode_border_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_column_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_header_linestyle") == 0)
+ {
+ static const char *const my_list[] =
+ {"single", "double", NULL};
+
+ COMPLETE_WITH_LIST_CS(my_list);
+
+ }
}
else if (strcmp(prev_wd, "\\set") == 0)
{
On 23 Červenec 2014, 7:36, Pavel Stehule wrote:
updated version is in attachment
OK, thanks. The new version seems OK to me.
Tomas
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
2014-07-23 8:38 GMT+02:00 Tomas Vondra <tv@fuzzy.cz>:
On 23 Červenec 2014, 7:36, Pavel Stehule wrote:
updated version is in attachment
OK, thanks. The new version seems OK to me.
Thank you
Pavel
Show quoted text
Tomas
Pavel,
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
2014-07-23 8:38 GMT+02:00 Tomas Vondra <tv@fuzzy.cz>:
OK, thanks. The new version seems OK to me.
Thank you
I've started looking over the patch and went back through the previous
thread about it. For my part, I'm in favor of adding this capability,
but I'm not terribly happy about how it was done. In particular,
get_line_style() seems pretty badly hacked around, and I don't really
like having the prepare_unicode_format call underneath it allocating
memory and then passing back up the need to free that memory via a new
field in the structure. Also, on a quick glance, are you sure that the
new 'unicode' output matches the same as the old 'unicode' did (with
pg_utf8format)?
I would think we'd simply set up a structure which is updated when the
linestyle is changed, which is surely going to be much less frequently
than the request for which linestyle to use happens, and handle all of
the line styles in more-or-less the same way rather than doing something
completely different for unicode than for the others.
Thanks,
Stephen
Hi
I removed dynamic allocation and reduced patch size.
What I tested a old unicode style is same as new unicode style. There
nothing was changed .. some fields are specified in refresh_utf8format
function
Regards
Pavel
2014-09-08 4:44 GMT+02:00 Stephen Frost <sfrost@snowman.net>:
Show quoted text
Pavel,
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
2014-07-23 8:38 GMT+02:00 Tomas Vondra <tv@fuzzy.cz>:
OK, thanks. The new version seems OK to me.
Thank you
I've started looking over the patch and went back through the previous
thread about it. For my part, I'm in favor of adding this capability,
but I'm not terribly happy about how it was done. In particular,
get_line_style() seems pretty badly hacked around, and I don't really
like having the prepare_unicode_format call underneath it allocating
memory and then passing back up the need to free that memory via a new
field in the structure. Also, on a quick glance, are you sure that the
new 'unicode' output matches the same as the old 'unicode' did (with
pg_utf8format)?I would think we'd simply set up a structure which is updated when the
linestyle is changed, which is surely going to be much less frequently
than the request for which linestyle to use happens, and handle all of
the line styles in more-or-less the same way rather than doing something
completely different for unicode than for the others.Thanks,
Stephen
Attachments:
unicode-linestyle-03.patchtext/x-patch; charset=UTF-8; name=unicode-linestyle-03.patchDownload
commit 509f8a92525889651653a75356d3fa57b58f3141
Author: Pavel Stehule <pavel.stehule@gooddata.com>
Date: Mon Sep 8 17:18:43 2014 +0200
remove palloc
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index db314c3..84233d0 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2299,6 +2299,42 @@ lo_import 152801
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_border_style</literal></term>
+ <listitem>
+ <para>
+ Sets the border line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_column_style</literal></term>
+ <listitem>
+ <para>
+ Sets the column line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_header_style</literal></term>
+ <listitem>
+ <para>
+ Sets the header line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index a66093a..fd05aae 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1054,6 +1054,9 @@ exec_command(const char *cmd,
"footer", "format", "linestyle", "null",
"numericlocale", "pager", "recordsep",
"tableattr", "title", "tuples_only",
+ "unicode_border_linestyle",
+ "unicode_column_linestyle",
+ "unicode_header_linestyle",
NULL
};
@@ -2248,6 +2251,40 @@ _align2string(enum printFormat in)
return "unknown";
}
+/*
+ * Parse entered unicode linestyle. Returns true, when entered string is
+ * known linestyle: single, double else returns false.
+ */
+static bool
+set_unicode_line_style(printQueryOpt *popt, const char *value, size_t vallen, unicode_linestyle *linestyle)
+{
+ if (pg_strncasecmp("single", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_SINGLE;
+ else if (pg_strncasecmp("double", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_DOUBLE;
+ else
+ return false;
+
+ /* input is ok, generate new unicode style */
+ refresh_utf8format(&(popt->topt));
+
+ return true;
+}
+
+static const char *
+_unicode_linestyle2string(int linestyle)
+{
+ switch (linestyle)
+ {
+ case UNICODE_LINESTYLE_SINGLE:
+ return "single";
+ break;
+ case UNICODE_LINESTYLE_DOUBLE:
+ return "double";
+ break;
+ }
+ return "unknown";
+}
bool
do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
@@ -2305,6 +2342,42 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
}
+ /* set unicode border line style */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(popt, value, vallen, &popt->topt.unicode_border_linestyle))
+ {
+ psql_error("\\pset: allowed unicode border linestyle are single, double\n");
+ return false;
+ }
+ }
+
+ /* set unicode column line style */
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(popt, value, vallen, &popt->topt.unicode_column_linestyle))
+ {
+ psql_error("\\pset: allowed unicode column linestyle are single, double\n");
+ return false;
+ }
+ }
+
+ /* set unicode header line style */
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(popt, value, vallen, &popt->topt.unicode_header_linestyle))
+ {
+ psql_error("\\pset: allowed unicode header linestyle are single, double\n");
+ return false;
+ }
+ }
+
/* set border style/width */
else if (strcmp(param, "border") == 0)
{
@@ -2601,6 +2674,25 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
printf(_("Tuples only (%s) is off.\n"), param);
}
+ /* unicode style formatting */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_border_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ printf(_("Unicode column linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_column_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_header_linestyle));
+ }
+
else
{
psql_error("\\pset: unknown option: %s\n", param);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index f8f000f..4ca7887 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -235,7 +235,8 @@ slashUsage(unsigned short int pager)
ON(pset.popt.topt.format == PRINT_HTML));
fprintf(output, _(" \\pset [NAME [VALUE]] set table output option\n"
" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n"
- " numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager})\n"));
+ " numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n"
+ " unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n"));
fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"),
ON(pset.popt.topt.tuples_only));
fprintf(output, _(" \\T [STRING] set HTML <table> tag attributes, or unset if none\n"));
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 0b31bc1..75cafc2 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -89,36 +89,84 @@ const printTextFormat pg_asciiformat_old =
false
};
-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"}
+/* Default unicode linestyle format */
+printTextFormat pg_utf8format;
+
+typedef struct unicodeStyleRowFormat {
+ const char *horizontal;
+ const char *vertical_and_right[2];
+ const char *vertical_and_left[2];
+} unicodeStyleRowFormat;
+
+typedef struct unicodeStyleColumnFormat {
+ const char *vertical;
+ const char *vertical_and_horizontal[2];
+ const char *up_and_horizontal[2];
+ const char *down_and_horizontal[2];
+} unicodeStyleColumnFormat;
+
+typedef struct unicodeStyleBorderFormat {
+ const char *up_and_right;
+ const char *vertical;
+ const char *down_and_right;
+ const char *horizontal;
+ const char *down_and_left;
+ const char *left_and_right;
+} unicodeStyleBorderFormat;
+
+typedef struct unicodeStyleFormat {
+ unicodeStyleRowFormat row_style[2];
+ unicodeStyleColumnFormat column_style[2];
+ unicodeStyleBorderFormat border_style[2];
+} unicodeStyleFormat;
+
+const unicodeStyleFormat unicode_style = {
+ {
+ {
+ /* ─ */
+ "\342\224\200",
+ /* ├╟ */
+ {"\342\224\234", "\342\225\237"},
+ /* ┤╢ */
+ {"\342\224\244", "\342\225\242"},
+ },
+ {
+ /* ═ */
+ "\342\225\220",
+ /* ╞╠ */
+ {"\342\225\236", "\342\225\240"},
+ /* ╡╣ */
+ {"\342\225\241", "\342\225\243"},
+ },
+ },
+ {
+ {
+ /* │ */
+ "\342\224\202",
+ /* ┼╪ */
+ {"\342\224\274", "\342\225\252"},
+ /* ┴╧ */
+ {"\342\224\264", "\342\225\247"},
+ /* ┬╤ */
+ {"\342\224\254", "\342\225\244"},
+ },
+ {
+ /* ║ */
+ "\342\225\221",
+ /* ╫╬ */
+ {"\342\225\253", "\342\225\254"},
+ /* ╨╩ */
+ {"\342\225\250", "\342\225\251"},
+ /* ╥╦ */
+ {"\342\225\245", "\342\225\246"},
+ },
+ },
+ {
+ /* └│┌─┐┘ */
+ {"\342\224\224", "\342\224\202", "\342\224\214", "\342\224\200", "\342\224\220", "\342\224\230"},
+ /* ╚║╔═╗╝ */
+ {"\342\225\232", "\342\225\221", "\342\225\224", "\342\225\220", "\342\225\227", "\342\225\235"},
},
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- " ",
- /* ↵ */
- "\342\206\265",
- " ",
- /* ↵ */
- "\342\206\265",
- /* … */
- "\342\200\246",
- /* … */
- "\342\200\246",
- true
};
@@ -503,7 +551,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
bool opt_tuples_only = cont->opt->tuples_only;
int encoding = cont->opt->encoding;
unsigned short opt_border = cont->opt->border;
- const printTextFormat *format = get_line_style(cont->opt);
+ printTextFormat *format = get_line_style(cont->opt);
const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
unsigned int col_count = 0,
@@ -1092,7 +1140,7 @@ print_aligned_vertical_line(const printTableContent *cont,
printTextRule pos,
FILE *fout)
{
- const printTextFormat *format = get_line_style(cont->opt);
+ printTextFormat *format = get_line_style(cont->opt);
const printTextLineFormat *lformat = &format->lrule[pos];
unsigned short opt_border = cont->opt->border;
unsigned int i;
@@ -1146,7 +1194,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
{
bool opt_tuples_only = cont->opt->tuples_only;
unsigned short opt_border = cont->opt->border;
- const printTextFormat *format = get_line_style(cont->opt);
+ 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;
@@ -2939,7 +2987,7 @@ setDecimalLocale(void)
}
/* get selected or default line style */
-const printTextFormat *
+printTextFormat *
get_line_style(const printTableOpt *opt)
{
/*
@@ -2953,6 +3001,64 @@ get_line_style(const printTableOpt *opt)
return &pg_asciiformat;
}
+void
+refresh_utf8format(const printTableOpt *opt)
+{
+ printTextFormat *popt = (printTextFormat *) &pg_utf8format;
+
+ const unicodeStyleBorderFormat *border;
+ const unicodeStyleRowFormat *header;
+ const unicodeStyleColumnFormat *column;
+
+ popt->name = "unicode";
+
+ border = &unicode_style.border_style[opt->unicode_border_linestyle];
+ header = &unicode_style.row_style[opt->unicode_header_linestyle];
+ column = &unicode_style.column_style[opt->unicode_column_linestyle];
+
+ popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_TOP].leftvrule = border->down_and_right;
+ popt->lrule[PRINT_RULE_TOP].midvrule = column->down_and_horizontal[opt->unicode_border_linestyle];;
+ popt->lrule[PRINT_RULE_TOP].rightvrule = border->down_and_left;
+
+ popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
+ popt->lrule[PRINT_RULE_MIDDLE].leftvrule = header->vertical_and_right[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].midvrule = column->vertical_and_horizontal[opt->unicode_header_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].rightvrule = header->vertical_and_left[opt->unicode_border_linestyle];
+
+ popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_BOTTOM].leftvrule = border->up_and_right;
+ popt->lrule[PRINT_RULE_BOTTOM].midvrule = column->up_and_horizontal[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_BOTTOM].rightvrule = border->left_and_right;
+
+ /* N/A */
+ popt->lrule[PRINT_RULE_DATA].hrule = "";
+ popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
+ popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
+ popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
+
+ popt->midvrule_nl = column->vertical;
+ popt->midvrule_wrap = column->vertical;
+ popt->midvrule_blank = column->vertical;
+ popt->header_nl_left = " ";
+
+ /* ↵ */
+ popt->header_nl_right = "\342\206\265";
+
+ popt->nl_left = " ";
+
+ /* ↵ */
+ popt->nl_right = "\342\206\265";
+
+ /* … */
+ popt->wrap_left = "\342\200\246";
+ popt->wrap_right = "\342\200\246";
+
+ popt->wrap_right_border = true;
+
+ return popt;
+}
+
/*
* 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 87b2856..bb8c1fc 100644
--- a/src/bin/psql/print.h
+++ b/src/bin/psql/print.h
@@ -68,6 +68,12 @@ typedef struct printTextFormat
* marks when border=0? */
} printTextFormat;
+typedef enum unicode_linestyle
+{
+ UNICODE_LINESTYLE_SINGLE = 0,
+ UNICODE_LINESTYLE_DOUBLE
+} unicode_linestyle;
+
struct separator
{
char *separator;
@@ -97,6 +103,9 @@ typedef struct printTableOpt
int encoding; /* character encoding */
int env_columns; /* $COLUMNS on psql start, 0 is unset */
int columns; /* target width for wrapped format */
+ unicode_linestyle unicode_border_linestyle;
+ unicode_linestyle unicode_column_linestyle;
+ unicode_linestyle unicode_header_linestyle;
} printTableOpt;
/*
@@ -152,7 +161,7 @@ typedef struct printQueryOpt
extern const printTextFormat pg_asciiformat;
extern const printTextFormat pg_asciiformat_old;
-extern const printTextFormat pg_utf8format;
+extern printTextFormat pg_utf8format;
extern FILE *PageOutput(int lines, unsigned short int pager);
@@ -177,7 +186,9 @@ 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);
+extern printTextFormat *get_line_style(const printTableOpt *opt);
+extern void refresh_utf8format(const printTableOpt *opt);
+
#ifndef __CYGWIN__
#define DEFAULT_PAGER "more"
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 5a397e8..8eecade 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -26,6 +26,7 @@
#include "help.h"
#include "input.h"
#include "mainloop.h"
+#include "print.h"
#include "settings.h"
@@ -129,6 +130,13 @@ main(int argc, char *argv[])
pset.popt.topt.start_table = true;
pset.popt.topt.stop_table = true;
pset.popt.topt.default_footer = true;
+
+ pset.popt.topt.unicode_border_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_column_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_header_linestyle = UNICODE_LINESTYLE_SINGLE;
+
+ refresh_utf8format(&(pset.popt.topt));
+
/* We must get COLUMNS here before readline() sets it */
pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 7577c4b..8b227f1 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3615,7 +3615,8 @@ psql_completion(const char *text, int start, int end)
{"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
"footer", "format", "linestyle", "null", "numericlocale",
"pager", "recordsep", "recordsep_zero", "tableattr", "title",
- "tuples_only", NULL};
+ "tuples_only", "unicode_border_linestyle",
+ "unicode_column_linestyle", "unicode_header_linestyle", NULL};
COMPLETE_WITH_LIST_CS(my_list);
}
@@ -3636,6 +3637,16 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH_LIST_CS(my_list);
}
+ else if (strcmp(prev_wd, "unicode_border_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_column_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_header_linestyle") == 0)
+ {
+ static const char *const my_list[] =
+ {"single", "double", NULL};
+
+ COMPLETE_WITH_LIST_CS(my_list);
+
+ }
}
else if (strcmp(prev_wd, "\\unset") == 0)
{
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 199036d..3764127 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -68,6 +68,9 @@ Record separator (recordsep) is <newline>.
Table attributes (tableattr) unset.
Title (title) unset.
Tuples only (tuples_only) is off.
+Unicode border linestyle is "single".
+Unicode column linestyle is "single".
+Unicode border linestyle is "single".
-- test multi-line headers, wrapping, and newline indicators
prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab
Pavel,
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
I removed dynamic allocation and reduced patch size.
This is certainly better, imv, though there are a couple of minor
issues (extra semi-colons, extraneous whitespace, get_line_style was
still changed to non-const, even though it doesn't need to be now).
What I tested a old unicode style is same as new unicode style. There
nothing was changed .. some fields are specified in refresh_utf8format
function
I don't particularly like this (having these fields set in
refresh_utf8format to hard-coded strings in the function), why not have
those handled the same as the rest, where the strings themselves are in
the unicode_style structure?
The rest looks pretty good. Need to step out for a bit but I'll look at
making the above changes when I get back if I don't hear anything.
Thanks,
Stephen
Hi
2014-09-11 16:42 GMT+02:00 Stephen Frost <sfrost@snowman.net>:
Pavel,
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
I removed dynamic allocation and reduced patch size.
This is certainly better, imv, though there are a couple of minor
issues (extra semi-colons, extraneous whitespace, get_line_style was
still changed to non-const, even though it doesn't need to be now).
fixed non-const -- other, I am sorry, I am blind
What I tested a old unicode style is same as new unicode style. There
nothing was changed .. some fields are specified in refresh_utf8format
functionI don't particularly like this (having these fields set in
refresh_utf8format to hard-coded strings in the function), why not have
those handled the same as the rest, where the strings themselves are in
the unicode_style structure?
I am not sure if I understand well.
With refresh_utf8format I can do shortly 6 possible combinations - or more
(when it will be requested)
I have no idea how to write as rest without repeating all 6 combinations -
what was one noticed issue of some older variant, where I designed
unicode1, unicode2, ...
Any idea, tip how to it?
Regards
Pavel
Show quoted text
The rest looks pretty good. Need to step out for a bit but I'll look at
making the above changes when I get back if I don't hear anything.Thanks,
Stephen
Attachments:
unicode-linestyle-04.patchtext/x-patch; charset=UTF-8; name=unicode-linestyle-04.patchDownload
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
new file mode 100644
index aa71674..1d59dce
*** a/doc/src/sgml/ref/psql-ref.sgml
--- b/doc/src/sgml/ref/psql-ref.sgml
*************** lo_import 152801
*** 2306,2311 ****
--- 2306,2347 ----
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_border_style</literal></term>
+ <listitem>
+ <para>
+ Sets the border line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_column_style</literal></term>
+ <listitem>
+ <para>
+ Sets the column line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_header_style</literal></term>
+ <listitem>
+ <para>
+ Sets the header line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
new file mode 100644
index 5d90ca2..94d8f45
*** a/src/bin/psql/command.c
--- b/src/bin/psql/command.c
*************** exec_command(const char *cmd,
*** 1054,1059 ****
--- 1054,1062 ----
"footer", "format", "linestyle", "null",
"numericlocale", "pager", "recordsep",
"tableattr", "title", "tuples_only",
+ "unicode_border_linestyle",
+ "unicode_column_linestyle",
+ "unicode_header_linestyle",
NULL
};
*************** _align2string(enum printFormat in)
*** 2248,2253 ****
--- 2251,2290 ----
return "unknown";
}
+ /*
+ * Parse entered unicode linestyle. Returns true, when entered string is
+ * known linestyle: single, double else returns false.
+ */
+ static bool
+ set_unicode_line_style(printQueryOpt *popt, const char *value, size_t vallen, unicode_linestyle *linestyle)
+ {
+ if (pg_strncasecmp("single", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_SINGLE;
+ else if (pg_strncasecmp("double", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_DOUBLE;
+ else
+ return false;
+
+ /* input is ok, generate new unicode style */
+ refresh_utf8format(&(popt->topt));
+
+ return true;
+ }
+
+ static const char *
+ _unicode_linestyle2string(int linestyle)
+ {
+ switch (linestyle)
+ {
+ case UNICODE_LINESTYLE_SINGLE:
+ return "single";
+ break;
+ case UNICODE_LINESTYLE_DOUBLE:
+ return "double";
+ break;
+ }
+ return "unknown";
+ }
bool
do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
*************** do_pset(const char *param, const char *v
*** 2305,2310 ****
--- 2342,2383 ----
}
+ /* set unicode border line style */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(popt, value, vallen, &popt->topt.unicode_border_linestyle))
+ {
+ psql_error("\\pset: allowed unicode border linestyle are single, double\n");
+ return false;
+ }
+ }
+
+ /* set unicode column line style */
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(popt, value, vallen, &popt->topt.unicode_column_linestyle))
+ {
+ psql_error("\\pset: allowed unicode column linestyle are single, double\n");
+ return false;
+ }
+ }
+
+ /* set unicode header line style */
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(popt, value, vallen, &popt->topt.unicode_header_linestyle))
+ {
+ psql_error("\\pset: allowed unicode header linestyle are single, double\n");
+ return false;
+ }
+ }
+
/* set border style/width */
else if (strcmp(param, "border") == 0)
{
*************** printPsetInfo(const char *param, struct
*** 2601,2606 ****
--- 2674,2698 ----
printf(_("Tuples only (%s) is off.\n"), param);
}
+ /* unicode style formatting */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_border_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ printf(_("Unicode column linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_column_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_header_linestyle));
+ }
+
else
{
psql_error("\\pset: unknown option: %s\n", param);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
new file mode 100644
index ef35696..6035a77
*** a/src/bin/psql/help.c
--- b/src/bin/psql/help.c
*************** slashUsage(unsigned short int pager)
*** 249,255 ****
ON(pset.popt.topt.format == PRINT_HTML));
fprintf(output, _(" \\pset [NAME [VALUE]] set table output option\n"
" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n"
! " numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager})\n"));
fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"),
ON(pset.popt.topt.tuples_only));
fprintf(output, _(" \\T [STRING] set HTML <table> tag attributes, or unset if none\n"));
--- 249,256 ----
ON(pset.popt.topt.format == PRINT_HTML));
fprintf(output, _(" \\pset [NAME [VALUE]] set table output option\n"
" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n"
! " numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n"
! " unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n"));
fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"),
ON(pset.popt.topt.tuples_only));
fprintf(output, _(" \\T [STRING] set HTML <table> tag attributes, or unset if none\n"));
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
new file mode 100644
index 0b31bc1..39f8d6d
*** a/src/bin/psql/print.c
--- b/src/bin/psql/print.c
*************** const printTextFormat pg_asciiformat_old
*** 89,124 ****
false
};
! 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\224\202",
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- " ",
- /* ↵ */
- "\342\206\265",
- " ",
- /* ↵ */
- "\342\206\265",
- /* … */
- "\342\200\246",
- /* … */
- "\342\200\246",
- true
};
--- 89,172 ----
false
};
! /* Default unicode linestyle format */
! const printTextFormat pg_utf8format;
!
! typedef struct unicodeStyleRowFormat {
! const char *horizontal;
! const char *vertical_and_right[2];
! const char *vertical_and_left[2];
! } unicodeStyleRowFormat;
!
! typedef struct unicodeStyleColumnFormat {
! const char *vertical;
! const char *vertical_and_horizontal[2];
! const char *up_and_horizontal[2];
! const char *down_and_horizontal[2];
! } unicodeStyleColumnFormat;
!
! typedef struct unicodeStyleBorderFormat {
! const char *up_and_right;
! const char *vertical;
! const char *down_and_right;
! const char *horizontal;
! const char *down_and_left;
! const char *left_and_right;
! } unicodeStyleBorderFormat;
!
! typedef struct unicodeStyleFormat {
! unicodeStyleRowFormat row_style[2];
! unicodeStyleColumnFormat column_style[2];
! unicodeStyleBorderFormat border_style[2];
! } unicodeStyleFormat;
!
! const unicodeStyleFormat unicode_style = {
{
! {
! /* ─ */
! "\342\224\200",
! /* ├╟ */
! {"\342\224\234", "\342\225\237"},
! /* ┤╢ */
! {"\342\224\244", "\342\225\242"},
! },
! {
! /* ═ */
! "\342\225\220",
! /* ╞╠ */
! {"\342\225\236", "\342\225\240"},
! /* ╡╣ */
! {"\342\225\241", "\342\225\243"},
! },
! },
! {
! {
! /* │ */
! "\342\224\202",
! /* ┼╪ */
! {"\342\224\274", "\342\225\252"},
! /* ┴╧ */
! {"\342\224\264", "\342\225\247"},
! /* ┬╤ */
! {"\342\224\254", "\342\225\244"},
! },
! {
! /* ║ */
! "\342\225\221",
! /* ╫╬ */
! {"\342\225\253", "\342\225\254"},
! /* ╨╩ */
! {"\342\225\250", "\342\225\251"},
! /* ╥╦ */
! {"\342\225\245", "\342\225\246"},
! },
! },
! {
! /* └│┌─┐┘ */
! {"\342\224\224", "\342\224\202", "\342\224\214", "\342\224\200", "\342\224\220", "\342\224\230"},
! /* ╚║╔═╗╝ */
! {"\342\225\232", "\342\225\221", "\342\225\224", "\342\225\220", "\342\225\227", "\342\225\235"},
},
};
*************** get_line_style(const printTableOpt *opt)
*** 2953,2958 ****
--- 3001,3064 ----
return &pg_asciiformat;
}
+ void
+ refresh_utf8format(const printTableOpt *opt)
+ {
+ printTextFormat *popt = (printTextFormat *) &pg_utf8format;
+
+ const unicodeStyleBorderFormat *border;
+ const unicodeStyleRowFormat *header;
+ const unicodeStyleColumnFormat *column;
+
+ popt->name = "unicode";
+
+ border = &unicode_style.border_style[opt->unicode_border_linestyle];
+ header = &unicode_style.row_style[opt->unicode_header_linestyle];
+ column = &unicode_style.column_style[opt->unicode_column_linestyle];
+
+ popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_TOP].leftvrule = border->down_and_right;
+ popt->lrule[PRINT_RULE_TOP].midvrule = column->down_and_horizontal[opt->unicode_border_linestyle];;
+ popt->lrule[PRINT_RULE_TOP].rightvrule = border->down_and_left;
+
+ popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
+ popt->lrule[PRINT_RULE_MIDDLE].leftvrule = header->vertical_and_right[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].midvrule = column->vertical_and_horizontal[opt->unicode_header_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].rightvrule = header->vertical_and_left[opt->unicode_border_linestyle];
+
+ popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_BOTTOM].leftvrule = border->up_and_right;
+ popt->lrule[PRINT_RULE_BOTTOM].midvrule = column->up_and_horizontal[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_BOTTOM].rightvrule = border->left_and_right;
+
+ /* N/A */
+ popt->lrule[PRINT_RULE_DATA].hrule = "";
+ popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
+ popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
+ popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
+
+ popt->midvrule_nl = column->vertical;
+ popt->midvrule_wrap = column->vertical;
+ popt->midvrule_blank = column->vertical;
+ popt->header_nl_left = " ";
+
+ /* ↵ */
+ popt->header_nl_right = "\342\206\265";
+
+ popt->nl_left = " ";
+
+ /* ↵ */
+ popt->nl_right = "\342\206\265";
+
+ /* … */
+ popt->wrap_left = "\342\200\246";
+ popt->wrap_right = "\342\200\246";
+
+ popt->wrap_right_border = true;
+
+ return popt;
+ }
+
/*
* 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
new file mode 100644
index 87b2856..9bfa78a
*** a/src/bin/psql/print.h
--- b/src/bin/psql/print.h
*************** typedef struct printTextFormat
*** 68,73 ****
--- 68,79 ----
* marks when border=0? */
} printTextFormat;
+ typedef enum unicode_linestyle
+ {
+ UNICODE_LINESTYLE_SINGLE = 0,
+ UNICODE_LINESTYLE_DOUBLE
+ } unicode_linestyle;
+
struct separator
{
char *separator;
*************** typedef struct printTableOpt
*** 97,102 ****
--- 103,111 ----
int encoding; /* character encoding */
int env_columns; /* $COLUMNS on psql start, 0 is unset */
int columns; /* target width for wrapped format */
+ unicode_linestyle unicode_border_linestyle;
+ unicode_linestyle unicode_column_linestyle;
+ unicode_linestyle unicode_header_linestyle;
} printTableOpt;
/*
*************** extern void printQuery(const PGresult *r
*** 178,183 ****
--- 187,194 ----
extern void setDecimalLocale(void);
extern const printTextFormat *get_line_style(const printTableOpt *opt);
+ extern void refresh_utf8format(const printTableOpt *opt);
+
#ifndef __CYGWIN__
#define DEFAULT_PAGER "more"
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
new file mode 100644
index b879d0c..11a159a
*** a/src/bin/psql/startup.c
--- b/src/bin/psql/startup.c
***************
*** 26,31 ****
--- 26,32 ----
#include "help.h"
#include "input.h"
#include "mainloop.h"
+ #include "print.h"
#include "settings.h"
*************** main(int argc, char *argv[])
*** 131,136 ****
--- 132,144 ----
pset.popt.topt.start_table = true;
pset.popt.topt.stop_table = true;
pset.popt.topt.default_footer = true;
+
+ pset.popt.topt.unicode_border_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_column_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_header_linestyle = UNICODE_LINESTYLE_SINGLE;
+
+ refresh_utf8format(&(pset.popt.topt));
+
/* We must get COLUMNS here before readline() sets it */
pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
new file mode 100644
index 4ce47e9..b80fe13
*** a/src/bin/psql/tab-complete.c
--- b/src/bin/psql/tab-complete.c
*************** psql_completion(const char *text, int st
*** 3622,3628 ****
{"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
"footer", "format", "linestyle", "null", "numericlocale",
"pager", "recordsep", "recordsep_zero", "tableattr", "title",
! "tuples_only", NULL};
COMPLETE_WITH_LIST_CS(my_list);
}
--- 3622,3629 ----
{"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
"footer", "format", "linestyle", "null", "numericlocale",
"pager", "recordsep", "recordsep_zero", "tableattr", "title",
! "tuples_only", "unicode_border_linestyle",
! "unicode_column_linestyle", "unicode_header_linestyle", NULL};
COMPLETE_WITH_LIST_CS(my_list);
}
*************** psql_completion(const char *text, int st
*** 3643,3648 ****
--- 3644,3659 ----
COMPLETE_WITH_LIST_CS(my_list);
}
+ else if (strcmp(prev_wd, "unicode_border_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_column_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_header_linestyle") == 0)
+ {
+ static const char *const my_list[] =
+ {"single", "double", NULL};
+
+ COMPLETE_WITH_LIST_CS(my_list);
+
+ }
}
else if (strcmp(prev_wd, "\\unset") == 0)
{
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
new file mode 100644
index 199036d..3764127
*** a/src/test/regress/expected/psql.out
--- b/src/test/regress/expected/psql.out
*************** Record separator (recordsep) is <newline
*** 68,73 ****
--- 68,76 ----
Table attributes (tableattr) unset.
Title (title) unset.
Tuples only (tuples_only) is off.
+ Unicode border linestyle is "single".
+ Unicode column linestyle is "single".
+ Unicode border linestyle is "single".
-- test multi-line headers, wrapping, and newline indicators
prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
2014-09-11 16:42 GMT+02:00 Stephen Frost <sfrost@snowman.net>:
I don't particularly like this (having these fields set in
refresh_utf8format to hard-coded strings in the function), why not have
those handled the same as the rest, where the strings themselves are in
the unicode_style structure?I am not sure if I understand well.
With refresh_utf8format I can do shortly 6 possible combinations - or more
(when it will be requested)I have no idea how to write as rest without repeating all 6 combinations -
what was one noticed issue of some older variant, where I designed
unicode1, unicode2, ...Any idea, tip how to it?
All I was suggesting was pulling these strings out of the function:
+ /* âµ */
+ popt->header_nl_right = "\342\206\265";
+
+ popt->nl_left = " ";
+
+ /* âµ */
+ popt->nl_right = "\342\206\265";
+
+ /* ⦠*/
+ popt->wrap_left = "\342\200\246";
+ popt->wrap_right = "\342\200\246";
and adding them to unicode_style and then referencing them there,
similar to how the rest of printTextFormat popt (by the way- don't
really like that variable name, particularly as it's used elsewhere with
a very different meaning.. why not 'format' or 'ptf'?) is
set up in refresh_utf8format, that's all.
Thanks,
Stephen
Pavel,
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
Any idea, tip how to it?
Attached is what I had been thinking.
Thoughts?
Thanks!
Stephen
Attachments:
unicode-linestyle-05.patchtext/x-diff; charset=utf-8Download
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index aa71674..1d59dce 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2306,6 +2306,42 @@ lo_import 152801
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_border_style</literal></term>
+ <listitem>
+ <para>
+ Sets the border line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_column_style</literal></term>
+ <listitem>
+ <para>
+ Sets the column line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_header_style</literal></term>
+ <listitem>
+ <para>
+ Sets the header line drawing style to one
+ of <literal>single</literal> or <literal>double</literal>
+ This option only affects the <literal>unicode</>
+ linestyle
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 5d90ca2..d14d72a 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1054,6 +1054,9 @@ exec_command(const char *cmd,
"footer", "format", "linestyle", "null",
"numericlocale", "pager", "recordsep",
"tableattr", "title", "tuples_only",
+ "unicode_border_linestyle",
+ "unicode_column_linestyle",
+ "unicode_header_linestyle",
NULL
};
@@ -2248,6 +2251,40 @@ _align2string(enum printFormat in)
return "unknown";
}
+/*
+ * Parse entered unicode linestyle. Returns true, when entered string is
+ * known linestyle: single, double else returns false.
+ */
+static bool
+set_unicode_line_style(printQueryOpt *popt, const char *value, size_t vallen, unicode_linestyle *linestyle)
+{
+ if (pg_strncasecmp("single", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_SINGLE;
+ else if (pg_strncasecmp("double", value, vallen) == 0)
+ *linestyle = UNICODE_LINESTYLE_DOUBLE;
+ else
+ return false;
+
+ /* input is ok, generate new unicode style */
+ refresh_utf8format(&(popt->topt));
+
+ return true;
+}
+
+static const char *
+_unicode_linestyle2string(int linestyle)
+{
+ switch (linestyle)
+ {
+ case UNICODE_LINESTYLE_SINGLE:
+ return "single";
+ break;
+ case UNICODE_LINESTYLE_DOUBLE:
+ return "double";
+ break;
+ }
+ return "unknown";
+}
bool
do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
@@ -2305,6 +2342,42 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
}
+ /* set unicode border line style */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(popt, value, vallen, &popt->topt.unicode_border_linestyle))
+ {
+ psql_error("\\pset: allowed unicode border linestyle are single, double\n");
+ return false;
+ }
+ }
+
+ /* set unicode column line style */
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(popt, value, vallen, &popt->topt.unicode_column_linestyle))
+ {
+ psql_error("\\pset: allowed unicode column linestyle are single, double\n");
+ return false;
+ }
+ }
+
+ /* set unicode header line style */
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ if (!value)
+ ;
+ else if (!set_unicode_line_style(popt, value, vallen, &popt->topt.unicode_header_linestyle))
+ {
+ psql_error("\\pset: allowed unicode header linestyle are single, double\n");
+ return false;
+ }
+ }
+
/* set border style/width */
else if (strcmp(param, "border") == 0)
{
@@ -2601,6 +2674,25 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
printf(_("Tuples only (%s) is off.\n"), param);
}
+ /* unicode style formatting */
+ else if (strcmp(param, "unicode_border_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_border_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_column_linestyle") == 0)
+ {
+ printf(_("Unicode column linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_column_linestyle));
+ }
+
+ else if (strcmp(param, "unicode_header_linestyle") == 0)
+ {
+ printf(_("Unicode border linestyle is \"%s\".\n"),
+ _unicode_linestyle2string(popt->topt.unicode_header_linestyle));
+ }
+
else
{
psql_error("\\pset: unknown option: %s\n", param);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index ef35696..6035a77 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -249,7 +249,8 @@ slashUsage(unsigned short int pager)
ON(pset.popt.topt.format == PRINT_HTML));
fprintf(output, _(" \\pset [NAME [VALUE]] set table output option\n"
" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n"
- " numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager})\n"));
+ " numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n"
+ " unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n"));
fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"),
ON(pset.popt.topt.tuples_only));
fprintf(output, _(" \\T [STRING] set HTML <table> tag attributes, or unset if none\n"));
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 0b31bc1..34365fd 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -89,35 +89,97 @@ const printTextFormat pg_asciiformat_old =
false
};
-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"}
+/* Default unicode linestyle format */
+const printTextFormat pg_utf8format;
+
+typedef struct unicodeStyleRowFormat {
+ const char *horizontal;
+ const char *vertical_and_right[2];
+ const char *vertical_and_left[2];
+} unicodeStyleRowFormat;
+
+typedef struct unicodeStyleColumnFormat {
+ const char *vertical;
+ const char *vertical_and_horizontal[2];
+ const char *up_and_horizontal[2];
+ const char *down_and_horizontal[2];
+} unicodeStyleColumnFormat;
+
+typedef struct unicodeStyleBorderFormat {
+ const char *up_and_right;
+ const char *vertical;
+ const char *down_and_right;
+ const char *horizontal;
+ const char *down_and_left;
+ const char *left_and_right;
+} unicodeStyleBorderFormat;
+
+typedef struct unicodeStyleFormat {
+ unicodeStyleRowFormat row_style[2];
+ unicodeStyleColumnFormat column_style[2];
+ unicodeStyleBorderFormat border_style[2];
+ const char *header_nl_left;
+ const char *header_nl_right;
+ const char *nl_left;
+ const char *nl_right;
+ const char *wrap_left;
+ const char *wrap_right;
+ bool wrap_right_border;
+} unicodeStyleFormat;
+
+const unicodeStyleFormat unicode_style = {
+ {
+ {
+ /* ─ */
+ "\342\224\200",
+ /* ├╟ */
+ {"\342\224\234", "\342\225\237"},
+ /* ┤╢ */
+ {"\342\224\244", "\342\225\242"},
+ },
+ {
+ /* ═ */
+ "\342\225\220",
+ /* ╞╠ */
+ {"\342\225\236", "\342\225\240"},
+ /* ╡╣ */
+ {"\342\225\241", "\342\225\243"},
+ },
+ },
+ {
+ {
+ /* │ */
+ "\342\224\202",
+ /* ┼╪ */
+ {"\342\224\274", "\342\225\252"},
+ /* ┴╧ */
+ {"\342\224\264", "\342\225\247"},
+ /* ┬╤ */
+ {"\342\224\254", "\342\225\244"},
+ },
+ {
+ /* ║ */
+ "\342\225\221",
+ /* ╫╬ */
+ {"\342\225\253", "\342\225\254"},
+ /* ╨╩ */
+ {"\342\225\250", "\342\225\251"},
+ /* ╥╦ */
+ {"\342\225\245", "\342\225\246"},
+ },
+ },
+ {
+ /* └│┌─┐┘ */
+ {"\342\224\224", "\342\224\202", "\342\224\214", "\342\224\200", "\342\224\220", "\342\224\230"},
+ /* ╚║╔═╗╝ */
+ {"\342\225\232", "\342\225\221", "\342\225\224", "\342\225\220", "\342\225\227", "\342\225\235"},
},
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
- /* │ */
- "\342\224\202",
" ",
- /* ↵ */
- "\342\206\265",
+ "\342\206\265", /* ↵ */
" ",
- /* ↵ */
- "\342\206\265",
- /* … */
- "\342\200\246",
- /* … */
- "\342\200\246",
+ "\342\206\265", /* ↵ */
+ "\342\200\246", /* … */
+ "\342\200\246", /* … */
true
};
@@ -2953,6 +3015,58 @@ get_line_style(const printTableOpt *opt)
return &pg_asciiformat;
}
+void
+refresh_utf8format(const printTableOpt *opt)
+{
+ printTextFormat *popt = (printTextFormat *) &pg_utf8format;
+
+ const unicodeStyleBorderFormat *border;
+ const unicodeStyleRowFormat *header;
+ const unicodeStyleColumnFormat *column;
+
+ popt->name = "unicode";
+
+ border = &unicode_style.border_style[opt->unicode_border_linestyle];
+ header = &unicode_style.row_style[opt->unicode_header_linestyle];
+ column = &unicode_style.column_style[opt->unicode_column_linestyle];
+
+ popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_TOP].leftvrule = border->down_and_right;
+ popt->lrule[PRINT_RULE_TOP].midvrule = column->down_and_horizontal[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_TOP].rightvrule = border->down_and_left;
+
+ popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
+ popt->lrule[PRINT_RULE_MIDDLE].leftvrule = header->vertical_and_right[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].midvrule = column->vertical_and_horizontal[opt->unicode_header_linestyle];
+ popt->lrule[PRINT_RULE_MIDDLE].rightvrule = header->vertical_and_left[opt->unicode_border_linestyle];
+
+ popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
+ popt->lrule[PRINT_RULE_BOTTOM].leftvrule = border->up_and_right;
+ popt->lrule[PRINT_RULE_BOTTOM].midvrule = column->up_and_horizontal[opt->unicode_border_linestyle];
+ popt->lrule[PRINT_RULE_BOTTOM].rightvrule = border->left_and_right;
+
+ /* N/A */
+ popt->lrule[PRINT_RULE_DATA].hrule = "";
+ popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
+ popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
+ popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
+
+ popt->midvrule_nl = column->vertical;
+ popt->midvrule_wrap = column->vertical;
+ popt->midvrule_blank = column->vertical;
+
+ /* Same for all unicode today */
+ popt->header_nl_left = unicode_style.header_nl_left;
+ popt->header_nl_right = unicode_style.header_nl_right;
+ popt->nl_left = unicode_style.nl_left;
+ popt->nl_right = unicode_style.nl_right;
+ popt->wrap_left = unicode_style.wrap_left;
+ popt->wrap_right = unicode_style.wrap_right;
+ popt->wrap_right_border = unicode_style.wrap_right_border;
+
+ return;
+}
+
/*
* 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 87b2856..f668b23 100644
--- a/src/bin/psql/print.h
+++ b/src/bin/psql/print.h
@@ -68,6 +68,12 @@ typedef struct printTextFormat
* marks when border=0? */
} printTextFormat;
+typedef enum unicode_linestyle
+{
+ UNICODE_LINESTYLE_SINGLE = 0,
+ UNICODE_LINESTYLE_DOUBLE
+} unicode_linestyle;
+
struct separator
{
char *separator;
@@ -97,6 +103,9 @@ typedef struct printTableOpt
int encoding; /* character encoding */
int env_columns; /* $COLUMNS on psql start, 0 is unset */
int columns; /* target width for wrapped format */
+ unicode_linestyle unicode_border_linestyle;
+ unicode_linestyle unicode_column_linestyle;
+ unicode_linestyle unicode_header_linestyle;
} printTableOpt;
/*
@@ -178,6 +187,7 @@ extern void printQuery(const PGresult *result, const printQueryOpt *opt,
extern void setDecimalLocale(void);
extern const printTextFormat *get_line_style(const printTableOpt *opt);
+extern void refresh_utf8format(const printTableOpt *opt);
#ifndef __CYGWIN__
#define DEFAULT_PAGER "more"
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index b879d0c..11a159a 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -26,6 +26,7 @@
#include "help.h"
#include "input.h"
#include "mainloop.h"
+#include "print.h"
#include "settings.h"
@@ -131,6 +132,13 @@ main(int argc, char *argv[])
pset.popt.topt.start_table = true;
pset.popt.topt.stop_table = true;
pset.popt.topt.default_footer = true;
+
+ pset.popt.topt.unicode_border_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_column_linestyle = UNICODE_LINESTYLE_SINGLE;
+ pset.popt.topt.unicode_header_linestyle = UNICODE_LINESTYLE_SINGLE;
+
+ refresh_utf8format(&(pset.popt.topt));
+
/* We must get COLUMNS here before readline() sets it */
pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 4ce47e9..b80fe13 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3622,7 +3622,8 @@ psql_completion(const char *text, int start, int end)
{"border", "columns", "expanded", "fieldsep", "fieldsep_zero",
"footer", "format", "linestyle", "null", "numericlocale",
"pager", "recordsep", "recordsep_zero", "tableattr", "title",
- "tuples_only", NULL};
+ "tuples_only", "unicode_border_linestyle",
+ "unicode_column_linestyle", "unicode_header_linestyle", NULL};
COMPLETE_WITH_LIST_CS(my_list);
}
@@ -3643,6 +3644,16 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH_LIST_CS(my_list);
}
+ else if (strcmp(prev_wd, "unicode_border_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_column_linestyle") == 0 ||
+ strcmp(prev_wd, "unicode_header_linestyle") == 0)
+ {
+ static const char *const my_list[] =
+ {"single", "double", NULL};
+
+ COMPLETE_WITH_LIST_CS(my_list);
+
+ }
}
else if (strcmp(prev_wd, "\\unset") == 0)
{
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 199036d..3764127 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -68,6 +68,9 @@ Record separator (recordsep) is <newline>.
Table attributes (tableattr) unset.
Title (title) unset.
Tuples only (tuples_only) is off.
+Unicode border linestyle is "single".
+Unicode column linestyle is "single".
+Unicode border linestyle is "single".
-- test multi-line headers, wrapping, and newline indicators
prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab
2014-09-12 5:14 GMT+02:00 Stephen Frost <sfrost@snowman.net>:
Pavel,
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
Any idea, tip how to it?
Attached is what I had been thinking.
Thoughts?
yes, it is better. I didn't understand before.
I though about it because it allows to design multiline end style in future.
I am not a fan of "↵" and "…" in resulted tables, and can be nice if I can
to optionally change it.
With your change we can design other "pure" style against current "rich"
style. But I don't have a idea, how to name it.
Regards
Pavel
Show quoted text
Thanks!
Stephen
2014-09-12 8:19 GMT+02:00 Pavel Stehule <pavel.stehule@gmail.com>:
2014-09-12 5:14 GMT+02:00 Stephen Frost <sfrost@snowman.net>:
Pavel,
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
Any idea, tip how to it?
Attached is what I had been thinking.
Thoughts?
yes, it is better. I didn't understand before.
I though about it because it allows to design multiline end style in
future.I am not a fan of "↵" and "…" in resulted tables, and can be nice if I can
to optionally change it.
I though about it, and we cannot to drop it now. These symbols are
necessary, because we don't support line between rows.
I am thinking so 05 patch should be final
Regards
Pavel
Show quoted text
With your change we can design other "pure" style against current "rich"
style. But I don't have a idea, how to name it.Regards
Pavel
Thanks!
Stephen
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
I though about it, and we cannot to drop it now. These symbols are
necessary, because we don't support line between rows.I am thinking so 05 patch should be final
Ok. I'm going to play with it a bit more but barring issues, should get
it committed today.
Thanks!
Stephen
* Stephen Frost (sfrost@snowman.net) wrote:
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
I though about it, and we cannot to drop it now. These symbols are
necessary, because we don't support line between rows.I am thinking so 05 patch should be final
Ok. I'm going to play with it a bit more but barring issues, should get
it committed today.
Alright, pushed with some additional cleanup, and also cleaned up the
border documentation a bit.
Thanks!
Stephen
2014-09-12 18:09 GMT+02:00 Stephen Frost <sfrost@snowman.net>:
* Stephen Frost (sfrost@snowman.net) wrote:
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
I though about it, and we cannot to drop it now. These symbols are
necessary, because we don't support line between rows.I am thinking so 05 patch should be final
Ok. I'm going to play with it a bit more but barring issues, should get
it committed today.Alright, pushed with some additional cleanup, and also cleaned up the
border documentation a bit.
Thank you very much
Regards
Pavel
Show quoted text
Thanks!
Stephen
Hi Stephen
I forgot to fix new enhanced pset help
fix attached
Regards
Pavel
2014-09-12 18:15 GMT+02:00 Pavel Stehule <pavel.stehule@gmail.com>:
Show quoted text
2014-09-12 18:09 GMT+02:00 Stephen Frost <sfrost@snowman.net>:
* Stephen Frost (sfrost@snowman.net) wrote:
* Pavel Stehule (pavel.stehule@gmail.com) wrote:
I though about it, and we cannot to drop it now. These symbols are
necessary, because we don't support line between rows.I am thinking so 05 patch should be final
Ok. I'm going to play with it a bit more but barring issues, should get
it committed today.Alright, pushed with some additional cleanup, and also cleaned up the
border documentation a bit.Thank you very much
Regards
Pavel
Thanks!
Stephen
Attachments:
unicode-style-help.patchtext/x-patch; charset=US-ASCII; name=unicode-style-help.patchDownload
commit aec4a03babdbed49d80253112b0d31108761e860
Author: Pavel Stehule <pavel.stehule@gooddata.com>
Date: Thu Sep 18 12:45:27 2014 +0200
initial
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 6035a77..d323a14 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -305,7 +305,7 @@ helpVariables(unsigned short int pager)
{
FILE *output;
- output = PageOutput(81, pager);
+ output = PageOutput(87, pager);
fprintf(output, _("List of specially treated variables.\n"));
@@ -364,6 +364,10 @@ helpVariables(unsigned short int pager)
" column width of left aligned data type in latex format\n"));
fprintf(output, _(" title set the table title for any subsequently printed tables\n"));
fprintf(output, _(" tuples_only if set, only actual table data is shown\n"));
+ fprintf(output, _(" unicode_border_linestyle\n"));
+ fprintf(output, _(" unicode_column_linestyle\n"));
+ fprintf(output, _(" unicode_header_linestyle\n"
+ " set the style of unicode line drawing [single, double]\n"));
fprintf(output, _("\nEnvironment variables:\n"));
fprintf(output, _("Usage:\n"));
On 2014-09-18 12:47:25 +0200, Pavel Stehule wrote:
- output = PageOutput(81, pager); + output = PageOutput(87, pager);fprintf(output, _("List of specially treated variables.\n"));
@@ -364,6 +364,10 @@ helpVariables(unsigned short int pager) " column width of left aligned data type in latex format\n")); fprintf(output, _(" title set the table title for any subsequently printed tables\n")); fprintf(output, _(" tuples_only if set, only actual table data is shown\n")); + fprintf(output, _(" unicode_border_linestyle\n")); + fprintf(output, _(" unicode_column_linestyle\n")); + fprintf(output, _(" unicode_header_linestyle\n" + " set the style of unicode line drawing [single, double]\n"));fprintf(output, _("\nEnvironment variables:\n"));
fprintf(output, _("Usage:\n"));
Either the current line count is wrong, or you added the wrong number of
new lines to PageOutput(). Your patch only adds four \n, while you
increased from 81 to 87.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
2014-09-18 12:51 GMT+02:00 Andres Freund <andres@2ndquadrant.com>:
On 2014-09-18 12:47:25 +0200, Pavel Stehule wrote:
- output = PageOutput(81, pager); + output = PageOutput(87, pager);fprintf(output, _("List of specially treated variables.\n"));
@@ -364,6 +364,10 @@ helpVariables(unsigned short int pager)
" columnwidth of left aligned data type in latex format\n"));
fprintf(output, _(" title set the table title for
any subsequently printed tables\n"));
fprintf(output, _(" tuples_only if set, only actual table
data is shown\n"));
+ fprintf(output, _(" unicode_border_linestyle\n")); + fprintf(output, _(" unicode_column_linestyle\n")); + fprintf(output, _(" unicode_header_linestyle\n" + " set thestyle of unicode line drawing [single, double]\n"));
fprintf(output, _("\nEnvironment variables:\n"));
fprintf(output, _("Usage:\n"));Either the current line count is wrong, or you added the wrong number of
new lines to PageOutput(). Your patch only adds four \n, while you
increased from 81 to 87.
true, sorry, I have a different wording in first design
fixed
Regards
Pavel
Show quoted text
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
Attachments:
unicode-style-help-2.patchtext/x-patch; charset=US-ASCII; name=unicode-style-help-2.patchDownload
commit aec4a03babdbed49d80253112b0d31108761e860
Author: Pavel Stehule <pavel.stehule@gooddata.com>
Date: Thu Sep 18 12:45:27 2014 +0200
initial
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 6035a77..d323a14 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -305,7 +305,7 @@ helpVariables(unsigned short int pager)
{
FILE *output;
- output = PageOutput(81, pager);
+ output = PageOutput(85, pager);
fprintf(output, _("List of specially treated variables.\n"));
@@ -364,6 +364,10 @@ helpVariables(unsigned short int pager)
" column width of left aligned data type in latex format\n"));
fprintf(output, _(" title set the table title for any subsequently printed tables\n"));
fprintf(output, _(" tuples_only if set, only actual table data is shown\n"));
+ fprintf(output, _(" unicode_border_linestyle\n"));
+ fprintf(output, _(" unicode_column_linestyle\n"));
+ fprintf(output, _(" unicode_header_linestyle\n"
+ " set the style of unicode line drawing [single, double]\n"));
fprintf(output, _("\nEnvironment variables:\n"));
fprintf(output, _("Usage:\n"));