Bryce Nesbitt wrote:
>
>
> Bruce Momjian wrote:
> > I spent time reviewing your patch --- quite impressive. I have attached
> > and updated version with mostly stylistic changes.
> >
> > In testing I found the regression tests were failing because of a divide
> > by zero error (fixed), and a missing case where the column delimiter has
> > to be ":". In fact I now see all your line continuation cases using ":"
> > rather than "!". It actually looks better --- "!" was too close to "|"
> > to be easily recognized. (Did you update your patch to use ":". I
> > didn't see "!" in your patch.)
> Nice! I'll merge with my current version. As you note I changed to ":".
Good, I thought so.
> I also found that for hugely wide output it was better to give up (do
> nothing), rather than mangle the output in a futile attempt to squash it
> to the window width. So there is one more clause in the wrapping if.
Was it because of performance? I have a way to fix that by decrementing
by more than one to shrink a column? I am attaching a new patch with my
improved loop. It remembers the previous maximum ratio.
> I have tested on several unix flavors, but not on Windows or cygwin.
I don't think you need to do that to get it applied --- there is nothing
windows-specific in your code.
Is this ready to be applied? Do you want to send a final update or are
you still testing?
--
Bruce Momjian <[EMAIL PROTECTED]> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ If your life is a hard drive, Christ can be your backup. +
Index: doc/src/sgml/ref/psql-ref.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v
retrieving revision 1.199
diff -c -c -r1.199 psql-ref.sgml
*** doc/src/sgml/ref/psql-ref.sgml 30 Mar 2008 18:10:20 -0000 1.199
--- doc/src/sgml/ref/psql-ref.sgml 17 Apr 2008 14:05:39 -0000
***************
*** 1513,1519 ****
<listitem>
<para>
Sets the output format to one of <literal>unaligned</literal>,
! <literal>aligned</literal>, <literal>html</literal>,
<literal>latex</literal>, or <literal>troff-ms</literal>.
Unique abbreviations are allowed. (That would mean one letter
is enough.)
--- 1513,1520 ----
<listitem>
<para>
Sets the output format to one of <literal>unaligned</literal>,
! <literal>aligned</literal>, <literal>wrapped</literal>,
! <literal>html</literal>,
<literal>latex</literal>, or <literal>troff-ms</literal>.
Unique abbreviations are allowed. (That would mean one letter
is enough.)
***************
*** 1525,1531 ****
is intended to create output that might be intended to be read
in by other programs (tab-separated, comma-separated).
<quote>Aligned</quote> mode is the standard, human-readable,
! nicely formatted text output that is default. The
<quote><acronym>HTML</acronym></quote> and
<quote>LaTeX</quote> modes put out tables that are intended to
be included in documents using the respective mark-up
--- 1526,1535 ----
is intended to create output that might be intended to be read
in by other programs (tab-separated, comma-separated).
<quote>Aligned</quote> mode is the standard, human-readable,
! nicely formatted text output that is default.
! <quote>Wrapped</quote> is like <literal>aligned</> but wraps
! the output to fit the screen's width, based on the environment
! variable <envar>COLUMNS</> or the autodetected width. The
<quote><acronym>HTML</acronym></quote> and
<quote>LaTeX</quote> modes put out tables that are intended to
be included in documents using the respective mark-up
***************
*** 2708,2713 ****
--- 2712,2730 ----
<variablelist>
<varlistentry>
+ <term><envar>COLUMNS</envar></term>
+
+ <listitem>
+ <para>
+ The character width to wrap output in <literal>wrapped</> format
+ mode. Many shells automatically update <envar>COLUMNS</> when
+ a window is resized. If not set the screen width is automatically
+ detected, if possible.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><envar>PAGER</envar></term>
<listitem>
Index: src/bin/psql/command.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/command.c,v
retrieving revision 1.186
diff -c -c -r1.186 command.c
*** src/bin/psql/command.c 1 Jan 2008 19:45:55 -0000 1.186
--- src/bin/psql/command.c 17 Apr 2008 14:05:39 -0000
***************
*** 1526,1531 ****
--- 1526,1534 ----
case PRINT_ALIGNED:
return "aligned";
break;
+ case PRINT_WRAP:
+ return "wrapped";
+ break;
case PRINT_HTML:
return "html";
break;
***************
*** 1559,1564 ****
--- 1562,1569 ----
popt->topt.format = PRINT_UNALIGNED;
else if (pg_strncasecmp("aligned", value, vallen) == 0)
popt->topt.format = PRINT_ALIGNED;
+ else if (pg_strncasecmp("wrapped", value, vallen) == 0)
+ popt->topt.format = PRINT_WRAP;
else if (pg_strncasecmp("html", value, vallen) == 0)
popt->topt.format = PRINT_HTML;
else if (pg_strncasecmp("latex", value, vallen) == 0)
***************
*** 1567,1573 ****
popt->topt.format = PRINT_TROFF_MS;
else
{
! psql_error("\\pset: allowed formats are unaligned,
aligned, html, latex, troff-ms\n");
return false;
}
--- 1572,1578 ----
popt->topt.format = PRINT_TROFF_MS;
else
{
! psql_error("\\pset: allowed formats are unaligned,
aligned, wrapped, html, latex, troff-ms\n");
return false;
}
Index: src/bin/psql/mbprint.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/mbprint.c,v
retrieving revision 1.30
diff -c -c -r1.30 mbprint.c
*** src/bin/psql/mbprint.c 16 Apr 2008 18:18:00 -0000 1.30
--- src/bin/psql/mbprint.c 17 Apr 2008 14:05:40 -0000
***************
*** 279,284 ****
--- 279,288 ----
return width;
}
+ /*
+ * Filter out unprintable characters, companion to wcs_size.
+ * Break input into lines (based on \n or \r).
+ */
void
pg_wcsformat(unsigned char *pwcs, size_t len, int encoding,
struct lineptr * lines, int count)
***************
*** 353,364 ****
}
len -= chlen;
}
! *ptr++ = '\0';
lines->width = linewidth;
! lines++;
! count--;
! if (count > 0)
lines->ptr = NULL;
}
unsigned char *
--- 357,373 ----
}
len -= chlen;
}
! *ptr++ = '\0'; /* Terminate formatted string */
!
lines->width = linewidth;
!
! /* Fill remaining array slots with nulls */
! while (--count)
! {
! lines++;
lines->ptr = NULL;
+ lines->width = 0;
+ }
}
unsigned char *
Index: src/bin/psql/print.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/print.c,v
retrieving revision 1.97
diff -c -c -r1.97 print.c
*** src/bin/psql/print.c 27 Mar 2008 03:57:34 -0000 1.97
--- src/bin/psql/print.c 17 Apr 2008 14:05:40 -0000
***************
*** 43,48 ****
--- 43,52 ----
static char *grouping;
static char *thousands_sep;
+ #define COL_RATIO(col_num) \
+ ((double) width_wrap[col_num] / width_average[col_num]
+ \
+ width_max[col_num] * 0.01) /* Penalize
wide columns */
+
static void *
pg_local_malloc(size_t size)
{
***************
*** 396,401 ****
--- 400,408 ----
}
+ /*
+ * Prety pretty boxes around cells.
+ */
static void
print_aligned_text(const char *title, const char *const * headers,
const char *const * cells, const char *const
* footers,
***************
*** 404,429 ****
{
bool opt_tuples_only = opt->tuples_only;
bool opt_numeric_locale = opt->numericLocale;
- unsigned short int opt_border = opt->border;
int encoding = opt->encoding;
! unsigned int col_count = 0;
! unsigned int cell_count = 0;
! unsigned int i;
! int tmp;
! unsigned int *widths,
! total_w;
! unsigned int *heights;
! unsigned int *format_space;
unsigned char **format_buf;
const char *const * ptr;
! struct lineptr **col_lineptrs; /* pointers to line pointer for
each
!
* column */
struct lineptr *lineptr_list; /* complete list of
linepointers */
int *complete; /* Array remembering which
columns have
* completed
output */
if (cancel_pressed)
return;
--- 411,441 ----
{
bool opt_tuples_only = opt->tuples_only;
bool opt_numeric_locale = opt->numericLocale;
int encoding = opt->encoding;
! unsigned short int opt_border = opt->border;
!
! unsigned int col_count = 0, cell_count = 0;
!
! unsigned int i,
! j;
!
! unsigned int *width_header,
! *width_max,
! *width_wrap,
! *width_average;
! unsigned int *heights,
! *format_space;
unsigned char **format_buf;
+ unsigned int width_total;
const char *const * ptr;
! struct lineptr **col_lineptrs; /* pointers to line pointer per
column */
struct lineptr *lineptr_list; /* complete list of
linepointers */
int *complete; /* Array remembering which
columns have
* completed
output */
+ int tcolumns = 0; /* Width of interactive console
*/
if (cancel_pressed)
return;
***************
*** 437,443 ****
if (col_count > 0)
{
! widths = pg_local_calloc(col_count, sizeof(*widths));
heights = pg_local_calloc(col_count, sizeof(*heights));
col_lineptrs = pg_local_calloc(col_count,
sizeof(*col_lineptrs));
format_space = pg_local_calloc(col_count,
sizeof(*format_space));
--- 449,458 ----
if (col_count > 0)
{
! width_header = pg_local_calloc(col_count,
sizeof(*width_header));
! width_average = pg_local_calloc(col_count,
sizeof(*width_average));
! width_max = pg_local_calloc(col_count, sizeof(*width_max));
! width_wrap = pg_local_calloc(col_count, sizeof(*width_wrap));
heights = pg_local_calloc(col_count, sizeof(*heights));
col_lineptrs = pg_local_calloc(col_count,
sizeof(*col_lineptrs));
format_space = pg_local_calloc(col_count,
sizeof(*format_space));
***************
*** 446,452 ****
}
else
{
! widths = NULL;
heights = NULL;
col_lineptrs = NULL;
format_space = NULL;
--- 461,470 ----
}
else
{
! width_header = NULL;
! width_average = NULL;
! width_max = NULL;
! width_wrap = NULL;
heights = NULL;
col_lineptrs = NULL;
format_space = NULL;
***************
*** 454,533 ****
complete = NULL;
}
! /* count cells (rows * cols) */
! for (ptr = cells; *ptr; ptr++)
! cell_count++;
!
! /* calc column widths */
for (i = 0; i < col_count; i++)
{
/* Get width & height */
! int height,
space;
! pg_wcssize((unsigned char *) headers[i], strlen(headers[i]),
encoding, &tmp, &height, &space);
! if (tmp > widths[i])
! widths[i] = tmp;
if (height > heights[i])
heights[i] = height;
if (space > format_space[i])
format_space[i] = space;
}
! for (i = 0, ptr = cells; *ptr; ptr++, i++)
{
! int numeric_locale_len;
! int height,
space;
- if (opt_align[i % col_count] == 'r' && opt_numeric_locale)
- numeric_locale_len =
additional_numeric_locale_len(*ptr);
- else
- numeric_locale_len = 0;
-
/* Get width, ignore height */
! pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
&tmp, &height, &space);
! tmp += numeric_locale_len;
! if (tmp > widths[i % col_count])
! widths[i % col_count] = tmp;
if (height > heights[i % col_count])
heights[i % col_count] = height;
if (space > format_space[i % col_count])
format_space[i % col_count] = space;
}
if (opt_border == 0)
! total_w = col_count - 1;
else if (opt_border == 1)
! total_w = col_count * 3 - 1;
else
! total_w = col_count * 3 + 1;
for (i = 0; i < col_count; i++)
! total_w += widths[i];
/*
! * At this point: widths contains the max width of each column heights
! * contains the max height of a cell of each column format_space
contains
! * maximum space required to store formatted string so we prepare the
! * formatting structures
*/
if (col_count > 0)
{
! int heights_total = 0;
struct lineptr *lineptr;
for (i = 0; i < col_count; i++)
! heights_total += heights[i];
! lineptr = lineptr_list = pg_local_calloc(heights_total,
sizeof(*lineptr_list));
for (i = 0; i < col_count; i++)
{
col_lineptrs[i] = lineptr;
lineptr += heights[i];
! format_buf[i] = pg_local_malloc(format_space[i]);
col_lineptrs[i]->ptr = format_buf[i];
}
--- 472,564 ----
complete = NULL;
}
! /* scan all column headers, find maximum width */
for (i = 0; i < col_count; i++)
{
/* Get width & height */
! int width,
! height,
space;
! pg_wcssize((unsigned char *) headers[i], strlen(headers[i]),
encoding, &width, &height, &space);
! if (width > width_max[i])
! width_max[i] = width;
if (height > heights[i])
heights[i] = height;
if (space > format_space[i])
format_space[i] = space;
+
+ width_header[i] = width;
}
! /* scan all rows, find maximum width, compute cell_count */
! for (i = 0, ptr = cells; *ptr; ptr++, i++, cell_count++)
{
! int width,
! height,
space;
/* Get width, ignore height */
! pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
&width, &height, &space);
! if (opt_numeric_locale && opt_align[i % col_count] == 'r')
! {
! width += additional_numeric_locale_len(*ptr);
! space += additional_numeric_locale_len(*ptr);
! }
!
! if (width > width_max[i % col_count])
! width_max[i % col_count] = width;
if (height > heights[i % col_count])
heights[i % col_count] = height;
if (space > format_space[i % col_count])
format_space[i % col_count] = space;
+
+ width_average[i % col_count] += width;
}
+ /* If we have rows, compute average */
+ if (col_count != 0 && cell_count != 0)
+ {
+ int rows = cell_count / col_count;
+
+ for (i = 0; i < col_count; i++)
+ width_average[i % col_count] /= rows;
+ }
+
+ /* adjust the total display width based on border style */
if (opt_border == 0)
! width_total = col_count - 1;
else if (opt_border == 1)
! width_total = col_count * 3 - 1;
else
! width_total = col_count * 3 + 1;
for (i = 0; i < col_count; i++)
! width_total += width_max[i];
/*
! * At this point: width_max[] contains the max width of each column,
! * heights[] contains the max number of lines in each column,
! * format_space[] contains the maximum storage space for formatting
! * strings, width_total contains the giant width sum. Now we allocate
! * some memory...
*/
if (col_count > 0)
{
! int height_total = 0;
struct lineptr *lineptr;
for (i = 0; i < col_count; i++)
! height_total += heights[i];
! lineptr = lineptr_list = pg_local_calloc(height_total,
sizeof(*lineptr_list));
for (i = 0; i < col_count; i++)
{
col_lineptrs[i] = lineptr;
lineptr += heights[i];
! format_buf[i] = pg_local_malloc(format_space[i] + 1);
col_lineptrs[i]->ptr = format_buf[i];
}
***************
*** 535,553 ****
else
lineptr_list = NULL;
if (opt->start_table)
{
/* print title */
if (title && !opt_tuples_only)
{
! /* Get width & height */
! int height;
! pg_wcssize((unsigned char *) title, strlen(title),
encoding, &tmp, &height, NULL);
! if (tmp >= total_w)
! fprintf(fout, "%s\n", title);
else
! fprintf(fout, "%-*s%s\n", (total_w - tmp) / 2,
"", title);
}
/* print headers */
--- 566,652 ----
else
lineptr_list = NULL;
+
+ /* Default word wrap to the full width, i.e. no word wrap */
+ for (i = 0; i < col_count; i++)
+ width_wrap[i] = width_max[i];
+
+ /*
+ * Optional optimized word wrap. Shrink columns with a high max/avg
ratio.
+ * Slighly bias against wider columns (increases chance a narrow column
+ * will fit in its cell)
+ */
+ if (opt->format == PRINT_WRAP)
+ {
+ /* If we can get the terminal width */
+ char *env = getenv("COLUMNS");
+
+ if (env != NULL)
+ tcolumns = atoi(env);
+ #ifdef TIOCGWINSZ
+ else
+ {
+ struct winsize screen_size;
+
+ if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) !=
-1)
+ tcolumns = screen_size.ws_col;
+ }
+ #endif
+
+ if (tcolumns > 0)
+ {
+ /* Shink high ratio columns */
+ while (width_total > tcolumns)
+ {
+ double max_ratio = 0, prev_max_ratio =
0;
+ double curr_ratio = 0;
+ int worst_col = -1;
+
+ /*
+ * Find column that has the highest ratio
of its maximum
+ * width compared to its average width.
This tells us which
+ * column will produce the fewest wrapped
values if shortened.
+ * width_wrap starts as equal to width_max.
+ */
+ for (i = 0; i < col_count; i++)
+ if (width_average[i] && width_wrap[i] >
width_header[i])
+ {
+ if (COL_RATIO(i) > max_ratio)
+ {
+ prev_max_ratio =
max_ratio;
+ max_ratio = curr_ratio;
+ worst_col = i;
+ }
+ }
+
+ /* Exit loop if we can't squeeze any more. */
+ if (worst_col < 0)
+ break;
+
+ /* Squeeze the worst column. Lather, rinse,
repeat */
+ do
+ {
+ width_wrap[worst_col]--;
+ width_total--;
+ } while (width_total > tcolumns && COL_RATIO(i)
>= prev_max_ratio);
+ }
+ }
+ }
+
+ /* time to output */
if (opt->start_table)
{
/* print title */
if (title && !opt_tuples_only)
{
! int width,
! height;
! pg_wcssize((unsigned char *) title, strlen(title),
encoding, &width, &height, NULL);
! if (width >= width_total)
! fprintf(fout, "%s\n", title); /* Aligned */
else
! fprintf(fout, "%-*s%s\n", (width_total - width)
/ 2, "", title); /* Centered */
}
/* print headers */
***************
*** 557,563 ****
int line_count;
if (opt_border == 2)
! _print_horizontal_line(col_count, widths,
opt_border, fout);
for (i = 0; i < col_count; i++)
pg_wcsformat((unsigned char *) headers[i],
strlen(headers[i]), encoding, col_lineptrs[i], heights[i]);
--- 656,662 ----
int line_count;
if (opt_border == 2)
! _print_horizontal_line(col_count, width_wrap,
opt_border, fout);
for (i = 0; i < col_count; i++)
pg_wcsformat((unsigned char *) headers[i],
strlen(headers[i]), encoding, col_lineptrs[i], heights[i]);
***************
*** 580,586 ****
if (!complete[i])
{
! nbspace = widths[i] -
this_line->width;
/* centered */
fprintf(fout, "%-*s%s%-*s",
--- 679,685 ----
if (!complete[i])
{
! nbspace = width_wrap[i] -
this_line->width;
/* centered */
fprintf(fout, "%-*s%s%-*s",
***************
*** 593,599 ****
}
}
else
! fprintf(fout, "%*s", widths[i],
"");
if (i < col_count - 1)
{
if (opt_border == 0)
--- 692,698 ----
}
}
else
! fprintf(fout, "%*s",
width_wrap[i], "");
if (i < col_count - 1)
{
if (opt_border == 0)
***************
*** 611,711 ****
fputc('\n', fout);
}
! _print_horizontal_line(col_count, widths, opt_border,
fout);
}
}
/* print cells */
for (i = 0, ptr = cells; *ptr; i += col_count, ptr += col_count)
{
! int j;
! int cols_todo = col_count;
! int line_count; /* Number of lines output
so far in row */
if (cancel_pressed)
break;
for (j = 0; j < col_count; j++)
pg_wcsformat((unsigned char *) ptr[j], strlen(ptr[j]),
encoding, col_lineptrs[j], heights[j]);
! line_count = 0;
memset(complete, 0, col_count * sizeof(int));
! while (cols_todo)
{
! /* beginning of line */
! if (opt_border == 2)
! fputs("| ", fout);
! else if (opt_border == 1)
! fputc(' ', fout);
!
! for (j = 0; j < col_count; j++)
{
! struct lineptr *this_line = col_lineptrs[j] +
line_count;
! bool finalspaces = (opt_border == 2
|| j != col_count - 1);
! if (complete[j]) /* Just print spaces...
*/
! {
! if (finalspaces)
! fprintf(fout, "%*s", widths[j],
"");
! }
! else
{
! /* content */
! if (opt_align[j] == 'r')
{
! if (opt_numeric_locale)
{
! /*
! * Assumption: This
code used only on strings
! * without multibyte
characters, otherwise
! * this_line->width <
strlen(this_ptr) and we get
! * an overflow
! */
! char *my_cell =
format_numeric_locale((char *) this_line->ptr);
!
! fprintf(fout, "%*s%s",
! (int)
(widths[i % col_count] - strlen(my_cell)), "",
!
my_cell);
! free(my_cell);
}
else
! fprintf(fout, "%*s%s",
!
widths[j] - this_line->width, "",
!
this_line->ptr);
}
! else
! fprintf(fout, "%-s%*s",
this_line->ptr,
! finalspaces ? (widths[j] -
this_line->width) : 0, "");
! /* If at the right height, done this
col */
! if (line_count == heights[j] - 1 ||
!this_line[1].ptr)
{
! complete[j] = 1;
! cols_todo--;
}
}
! /* divider */
! if ((j + 1) % col_count)
{
! if (opt_border == 0)
! fputc(' ', fout);
! else if (line_count == 0)
! fputs(" | ", fout);
! else
! fprintf(fout, " %c ",
complete[j + 1] ? ' ' : ':');
}
}
- if (opt_border == 2)
- fputs(" |", fout);
- fputc('\n', fout);
- line_count++;
}
}
if (opt->stop_table)
{
if (opt_border == 2 && !cancel_pressed)
! _print_horizontal_line(col_count, widths, opt_border,
fout);
/* print footers */
if (footers && !opt_tuples_only && !cancel_pressed)
--- 710,857 ----
fputc('\n', fout);
}
! _print_horizontal_line(col_count, width_wrap,
opt_border, fout);
}
}
/* print cells */
for (i = 0, ptr = cells; *ptr; i += col_count, ptr += col_count)
{
! bool line_todo,
! cols_todo;
! int line_count;
if (cancel_pressed)
break;
+ /*
+ * Format each cell. Format again, it is a numeric formatting
locale
+ * (e.g. 123,456 vs. 123456)
+ */
for (j = 0; j < col_count; j++)
+ {
pg_wcsformat((unsigned char *) ptr[j], strlen(ptr[j]),
encoding, col_lineptrs[j], heights[j]);
+ if (opt_numeric_locale && opt_align[j % col_count] ==
'r')
+ {
+ char *my_cell;
! my_cell = format_numeric_locale((char *)
col_lineptrs[j]->ptr);
! strcpy((char *) col_lineptrs[j]->ptr, my_cell);
/* Buffer IS large
!
* enough... now */
! free(my_cell);
! }
! }
!
! /* Print rows to console */
memset(complete, 0, col_count * sizeof(int));
! line_count = 0;
! line_todo = true;
! while (line_todo)
{
! cols_todo = true;
! while (cols_todo)
{
! char border_cell = '*';
! cols_todo = false;
!
! /* left border */
! if (opt_border == 2)
! fputs("| ", fout);
! else if (opt_border == 1)
! fputc(' ', fout);
!
! /* for each column */
! for (j = 0; j < col_count; j++)
{
! struct lineptr *this_line =
&col_lineptrs[j][line_count];
!
! if (heights[j] <= line_count)
/* Blank column content */
! {
! fprintf(fout, "%*s",
width_wrap[j], "");
! border_cell = '|';
! }
! else if (opt_align[j] == 'r')
/* Right aligned cell */
{
! int
strlen_remaining = strlen((char *) this_line->ptr + complete[j]);
!
! if (strlen_remaining >
width_wrap[j])
{
! fprintf(fout, "%.*s",
(int) width_wrap[j], this_line->ptr + complete[j]);
! complete[j] +=
width_wrap[j]; /* We've done THIS much */
! cols_todo = true;
/* And there is more to do... */
! border_cell = ':';
}
else
! {
! fprintf(fout, "%*s",
width_wrap[j] - strlen_remaining, "");
! fprintf(fout, "%-s",
this_line->ptr + complete[j]);
! complete[j] +=
strlen_remaining;
! border_cell = '|';
! }
}
! else /* Left aligned cell */
! {
! int
strlen_remaining = strlen((char *) this_line->ptr + complete[j]);
!
! if (strlen_remaining >
width_wrap[j])
! {
! fprintf(fout, "%.*s",
(int) width_wrap[j], this_line->ptr + complete[j]);
! complete[j] +=
width_wrap[j]; /* We've done THIS much */
! cols_todo = true;
/* And there is more to do... */
! border_cell = ':';
! }
! else
! {
! fprintf(fout, "%-s",
this_line->ptr + complete[j]);
! fprintf(fout, "%*s",
width_wrap[j] - strlen_remaining, "");
! complete[j] +=
strlen_remaining;
! border_cell = '|';
! }
! }
!
! /* print a divider, middle of columns
only */
! if ((j + 1) % col_count)
{
! if (opt_border == 0)
! fputc(' ', fout);
! else if (line_count == 0)
! fprintf(fout, " %c ",
border_cell);
! else
! fprintf(fout, " %c ",
complete[j + 1] ? ' ' : ':');
}
}
! /* end of row border */
! if (opt_border == 2)
! fprintf(fout, " %c", border_cell);
! fputc('\n', fout);
! }
!
! /*
! * Check if any columns have line continuations due to
\n in the
! * cell.
! */
! line_count++;
! line_todo = false;
! for (j = 0; j < col_count; j++)
! {
! if (line_count < heights[j])
{
! if (col_lineptrs[j][line_count].ptr)
! {
! line_todo = true;
! complete[j] = 0;
! }
}
}
}
}
if (opt->stop_table)
{
if (opt_border == 2 && !cancel_pressed)
! _print_horizontal_line(col_count, width_wrap,
opt_border, fout);
/* print footers */
if (footers && !opt_tuples_only && !cancel_pressed)
***************
*** 722,728 ****
}
/* clean up */
! free(widths);
free(heights);
free(col_lineptrs);
free(format_space);
--- 868,877 ----
}
/* clean up */
! free(width_header);
! free(width_average);
! free(width_max);
! free(width_wrap);
free(heights);
free(col_lineptrs);
free(format_space);
***************
*** 754,760 ****
dheight = 1,
hformatsize = 0,
dformatsize = 0;
- int tmp = 0;
char *divider;
unsigned int cell_count = 0;
struct lineptr *hlineptr,
--- 903,908 ----
***************
*** 779,790 ****
/* Find the maximum dimensions for the headers */
for (i = 0; i < col_count; i++)
{
! int height,
fs;
! pg_wcssize((unsigned char *) headers[i], strlen(headers[i]),
encoding, &tmp, &height, &fs);
! if (tmp > hwidth)
! hwidth = tmp;
if (height > hheight)
hheight = height;
if (fs > hformatsize)
--- 927,939 ----
/* Find the maximum dimensions for the headers */
for (i = 0; i < col_count; i++)
{
! int width,
! height,
fs;
! pg_wcssize((unsigned char *) headers[i], strlen(headers[i]),
encoding, &width, &height, &fs);
! if (width > hwidth)
! hwidth = width;
if (height > hheight)
hheight = height;
if (fs > hformatsize)
***************
*** 799,805 ****
for (i = 0, ptr = cells; *ptr; ptr++, i++)
{
int numeric_locale_len;
! int height,
fs;
if (opt_align[i % col_count] == 'r' && opt_numeric_locale)
--- 948,955 ----
for (i = 0, ptr = cells; *ptr; ptr++, i++)
{
int numeric_locale_len;
! int width,
! height,
fs;
if (opt_align[i % col_count] == 'r' && opt_numeric_locale)
***************
*** 807,816 ****
else
numeric_locale_len = 0;
! pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
&tmp, &height, &fs);
! tmp += numeric_locale_len;
! if (tmp > dwidth)
! dwidth = tmp;
if (height > dheight)
dheight = height;
if (fs > dformatsize)
--- 957,966 ----
else
numeric_locale_len = 0;
! pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
&width, &height, &fs);
! width += numeric_locale_len;
! if (width > dwidth)
! dwidth = width;
if (height > dheight)
dheight = height;
if (fs > dformatsize)
***************
*** 1879,1884 ****
--- 2029,2035 ----
opt,
output);
break;
case PRINT_ALIGNED:
+ case PRINT_WRAP:
if (opt->expanded)
print_aligned_vertical(title, headers, cells,
footers, align,
opt,
output);
Index: src/bin/psql/print.h
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/print.h,v
retrieving revision 1.35
diff -c -c -r1.35 print.h
*** src/bin/psql/print.h 1 Jan 2008 19:45:56 -0000 1.35
--- src/bin/psql/print.h 17 Apr 2008 14:05:40 -0000
***************
*** 21,26 ****
--- 21,27 ----
PRINT_NOTHING = 0, /* to make sure someone
initializes this */
PRINT_UNALIGNED,
PRINT_ALIGNED,
+ PRINT_WRAP,
PRINT_HTML,
PRINT_LATEX,
PRINT_TROFF_MS
--
Sent via pgsql-patches mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches