On Sun, Oct 25, 2009 at 11:48:27PM +0000, Roger Leigh wrote: > There's just one tiny display glitch I can see, and that's if you have > mixed wrapping and newlines, you miss the lefthand wrap mark if the line > is the last wrapped line and it ends in a newline. It might not be > possible to pick that up if we can't discover that from the line state > when printing out the line. Might possibly require storing the wrap > state so we know what happened on the previous line, though if there's > a slightly cleverer approach to detecting if we're already wrapped > that would be better.
This appears simpler and more robust, so I've gone with this approach, and attached a new patch which fixes it. 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..36183f2 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -54,9 +54,10 @@ const printTextFormat pg_asciiformat = { "-", "+", "+", "+" }, { "", "|", "|", "|" } }, - ":", - ";", - " " + " ", + "+", + ".", + "." }; const printTextFormat pg_utf8format = @@ -72,12 +73,13 @@ 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\206\265", + /* … */ + "\342\200\246", + /* … */ + "\342\200\246" }; @@ -479,6 +481,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 +503,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 +518,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 +581,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 +776,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) + fputs(curr_nl_line ? format->cont_left : " ", fout); + if (!header_done[i]) { nbspace = width_wrap[i] - this_line->width; @@ -796,21 +802,16 @@ 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 ? '+' : ' '); - } + + fputs(!header_done[i] ? format->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 +862,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 +918,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 +937,30 @@ 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? */ - 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 */ - else - fprintf(fout, " %s ", dformat->midvrule); + 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) + 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 +1207,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..6ca8896 100644 --- a/src/bin/psql/print.h +++ b/src/bin/psql/print.h @@ -41,14 +41,23 @@ 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 */ +} printTextLineWrap; + typedef struct printTextFormat { /* A complete line style */ const char *name; /* for display purposes */ printTextLineFormat lrule[4]; /* indexed by enum printTextRule */ - const char *midvrule_cont; /* vertical line for continue after newline */ - const char *midvrule_wrap; /* vertical line for wrapped data */ - const char *midvrule_blank; /* vertical line for blank data */ + 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 */ } printTextFormat; typedef struct printTableOpt
signature.asc
Description: Digital signature