Hi Tomas 2014-07-22 23:20 GMT+02:00 Tomas Vondra <t...@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 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}) > > 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 > > > 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 >
commit fb99f3b1e12d7dfb203b70187e63647e5d0a674d Author: Pavel Stehule <pavel.steh...@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) {
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers