On Mon, Oct 26, 2009 at 01:33:19PM -0400, Tom Lane wrote: > Greg Stark <gsst...@mit.edu> writes: > > While i agree this looks nicer I wonder what it does to things like > > excel/gnumeric/ooffice auto-recognizing table layouts and importing > > files. I'm not sure our old format was so great for this so maybe this > > is actually an improvement I'm asking for. > > Yeah. We can do what we like with the UTF8 format but I'm considerably > more worried about the aspect of making random changes to the > plain-ASCII output. On the other hand, we changed that just a release > or so ago (to put in the multiline output in the first place) and > I didn't hear complaints about it that time.
The attached updated patch makes sure that the ASCII display remains the same (bar trailing whitespace used for padding). I'm tempted to add an additional ascii format such as "ascii-clean" which cleans up the inconsistencies in the formatting as for the unicode format, while the existing ascii format would remain the default for backwards compatibility. Regards, Roger -- .''`. Roger Leigh : :' : Debian GNU/Linux http://people.debian.org/~rleigh/ `. `' Printing on GNU/Linux? http://gutenprint.sourceforge.net/ `- GPG Public Key: 0x25BFB848 Please GPG sign your mail.
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index 026e043..3f61293 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -56,7 +56,14 @@ const printTextFormat pg_asciiformat = }, ":", ";", - " " + " ", + "+", + " ", + " ", + " ", + " ", + " ", + false }; const printTextFormat pg_utf8format = @@ -72,12 +79,23 @@ const printTextFormat pg_utf8format = /* N/A, │, │, │ */ { "", "\342\224\202", "\342\224\202", "\342\224\202" } }, - /* ╎ */ - "\342\225\216", - /* ┊ */ - "\342\224\212", - /* ╷ */ - "\342\225\267" + /* │ */ + "\342\224\202", + /* │ */ + "\342\224\202", + /* │ */ + "\342\224\202", + " ", + /* ↵ */ + "\342\206\265", + " ", + /* ↵ */ + "\342\206\265", + /* … */ + "\342\200\246", + /* … */ + "\342\200\246", + true }; @@ -479,6 +497,8 @@ print_aligned_text(const printTableContent *cont, FILE *fout) int output_columns = 0; /* Width of interactive console */ bool is_pager = false; + printTextLineWrap *wrap; + if (cancel_pressed) return; @@ -499,6 +519,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout) format_buf = pg_local_calloc(col_count, sizeof(*format_buf)); header_done = pg_local_calloc(col_count, sizeof(*header_done)); bytes_output = pg_local_calloc(col_count, sizeof(*bytes_output)); + wrap = pg_local_calloc(col_count, sizeof(*wrap)); } else { @@ -513,6 +534,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout) format_buf = NULL; header_done = NULL; bytes_output = NULL; + wrap = NULL; } /* scan all column headers, find maximum width and max max_nl_lines */ @@ -575,7 +597,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout) /* adjust the total display width based on border style */ if (opt_border == 0) - width_total = col_count - 1; + width_total = col_count; else if (opt_border == 1) width_total = col_count * 3 - 1; else @@ -770,16 +792,16 @@ print_aligned_text(const printTableContent *cont, FILE *fout) while (more_col_wrapping) { if (opt_border == 2) - fprintf(fout, "%s%c", dformat->leftvrule, - curr_nl_line ? '+' : ' '); - else if (opt_border == 1) - fputc(curr_nl_line ? '+' : ' ', fout); + fputs(dformat->leftvrule, fout); for (i = 0; i < cont->ncolumns; i++) { struct lineptr *this_line = col_lineptrs[i] + curr_nl_line; unsigned int nbspace; + if (opt_border != 0 || (format->cont_right_border == false && i > 0)) + fputs(curr_nl_line ? format->header_cont_left : " ", fout); + if (!header_done[i]) { nbspace = width_wrap[i] - this_line->width; @@ -796,21 +818,17 @@ print_aligned_text(const printTableContent *cont, FILE *fout) } else fprintf(fout, "%*s", width_wrap[i], ""); - if (i < col_count - 1) - { - if (opt_border == 0) - fputc(curr_nl_line ? '+' : ' ', fout); - else - fprintf(fout, " %s%c", dformat->midvrule, - curr_nl_line ? '+' : ' '); - } + + if (opt_border != 0 || format->cont_right_border == true) + fputs(!header_done[i] ? format->header_cont_right : " ", fout); + + if (opt_border != 0 && i < col_count - 1) + fputs(dformat->midvrule, fout); } curr_nl_line++; if (opt_border == 2) - fprintf(fout, " %s", dformat->rightvrule); - else if (opt_border == 1) - fputc(' ', fout); + fputs(dformat->rightvrule, fout); fputc('\n', fout); } @@ -861,19 +879,28 @@ print_aligned_text(const printTableContent *cont, FILE *fout) /* left border */ if (opt_border == 2) - fprintf(fout, "%s ", dformat->leftvrule); - else if (opt_border == 1) - fputc(' ', fout); + fputs(dformat->leftvrule, fout); /* for each column */ for (j = 0; j < col_count; j++) { /* We have a valid array element, so index it */ struct lineptr *this_line = &col_lineptrs[j][curr_nl_line[j]]; - int bytes_to_output; - int chars_to_output = width_wrap[j]; + int bytes_to_output; + int chars_to_output = width_wrap[j]; bool finalspaces = (opt_border == 2 || j < col_count - 1); + /* Print left-hand wrap or newline mark */ + if (opt_border != 0) + { + if (wrap[j] == PRINT_LINE_WRAP_WRAP) + fputs(format->wrap_left, fout); + else if (wrap[j] == PRINT_LINE_WRAP_CONT) + fputs(format->cont_left, fout); + else + fputc(' ', fout); + } + if (!this_line->ptr) { /* Past newline lines so just pad for other columns */ @@ -908,7 +935,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout) /* spaces second */ fprintf(fout, "%.*s", bytes_to_output, this_line->ptr + bytes_output[j]); - if (finalspaces) + if (finalspaces || col_lineptrs[j][curr_nl_line[j]].ptr != NULL) fprintf(fout, "%*s", width_wrap[j] - chars_to_output, ""); } @@ -927,29 +954,40 @@ print_aligned_text(const printTableContent *cont, FILE *fout) } } - /* print a divider, if not the last column */ - if (j < col_count - 1) + /* Determine if next line for this column is wrapped or a newline */ + wrap[j] = PRINT_LINE_WRAP_NONE; + if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL) { - if (opt_border == 0) - fputc(' ', fout); - /* Next value is beyond past newlines? */ + if (bytes_output[j] != 0) + wrap[j] = PRINT_LINE_WRAP_WRAP; + else if (curr_nl_line[j] != 0) + wrap[j] = PRINT_LINE_WRAP_CONT; + } + + /* Print right-hand wrap or newline mark */ + if (wrap[j] == PRINT_LINE_WRAP_WRAP) + fputs(format->wrap_right, fout); + else if (wrap[j] == PRINT_LINE_WRAP_CONT) + fputs(format->cont_right, fout); + else if (!(opt_border == 0 && j == col_count - 1)) + fputc(' ', fout); + + if (opt_border != 0 && j < col_count - 1) + { + if (wrap[j+1] == PRINT_LINE_WRAP_WRAP) + fputs(format->midvrule_wrap, fout); + else if (wrap[j+1] == PRINT_LINE_WRAP_CONT) + fputs(format->midvrule_cont, fout); else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL) - fprintf(fout, " %s ", format->midvrule_blank); - /* In wrapping of value? */ - else if (bytes_output[j + 1] != 0) - fprintf(fout, " %s ", format->midvrule_wrap); - /* After first newline value */ - else if (curr_nl_line[j + 1] != 0) - fprintf(fout, " %s ", format->midvrule_cont); - /* Ordinary line */ + fputs(format->midvrule_blank, fout); else - fprintf(fout, " %s ", dformat->midvrule); + fputs(dformat->midvrule, fout); } } /* end-of-row border */ if (opt_border == 2) - fprintf(fout, " %s", dformat->rightvrule); + fputs(dformat->rightvrule, fout); fputc('\n', fout); } while (more_lines); @@ -1196,9 +1234,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) fprintf(fout, "%*s", hwidth, ""); if (opt_border > 0) - fprintf(fout, " %s ", - (line_count == 0) ? - format->midvrule_cont : dformat->midvrule); + fprintf(fout, " %s ", dformat->midvrule); else fputc(' ', fout); diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h index 056aaa6..1007466 100644 --- a/src/bin/psql/print.h +++ b/src/bin/psql/print.h @@ -41,14 +41,30 @@ typedef enum printTextRule PRINT_RULE_DATA /* data line (hrule is unused here) */ } printTextRule; +typedef enum printTextLineWrap +{ + /* Types of line continuation and wrapping */ + PRINT_LINE_WRAP_NONE = 0, /* No wrapping */ + PRINT_LINE_WRAP_WRAP = 1, /* Line is wrapped */ + PRINT_LINE_WRAP_CONT = 2, /* Continuation after newline */ + PRINT_LINE_WRAP_BLANK = 3 /* Blank line after end of data */ +} printTextLineWrap; + typedef struct printTextFormat { /* A complete line style */ - const char *name; /* for display purposes */ + const char *name; /* for display purposes */ printTextLineFormat lrule[4]; /* indexed by enum printTextRule */ const char *midvrule_cont; /* vertical line for continue after newline */ const char *midvrule_wrap; /* vertical line for wrapped data */ const char *midvrule_blank; /* vertical line for blank data */ + const char *header_cont_left; /* continue after newline */ + const char *header_cont_right; /* continue after newline */ + const char *cont_left; /* continue after newline */ + const char *cont_right; /* continue after newline */ + const char *wrap_left; /* wrapped data */ + const char *wrap_right; /* wrapped data */ + bool cont_right_border; /* use right-hand border for continuation marks when border=0 */ } printTextFormat; typedef struct printTableOpt
signature.asc
Description: Digital signature