3
3
*
4
4
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
5
5
*
6
- * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.101 2008/05/13 00:14:11 alvherre Exp $
6
+ * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.102 2008/05/16 16:59:05 momjian Exp $
7
7
*/
8
8
#include "postgres_fe.h"
9
9
@@ -45,6 +45,8 @@ static char *thousands_sep;
45
45
46
46
/* Local functions */
47
47
static int strlen_max_width (unsigned char * str , int * target_width , int encoding );
48
+ static void IsPagerNeeded (const printTableContent * cont , const int extra_lines ,
49
+ FILE * * fout , bool * is_pager );
48
50
49
51
50
52
static void *
@@ -394,7 +396,7 @@ _print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths,
394
396
* Print pretty boxes around cells.
395
397
*/
396
398
static void
397
- print_aligned_text (const printTableContent * cont , bool is_pager , FILE * fout )
399
+ print_aligned_text (const printTableContent * cont , FILE * fout )
398
400
{
399
401
bool opt_tuples_only = cont -> opt -> tuples_only ;
400
402
bool opt_numeric_locale = cont -> opt -> numericLocale ;
@@ -416,6 +418,8 @@ print_aligned_text(const printTableContent *cont, bool is_pager, FILE *fout)
416
418
unsigned char * * format_buf ;
417
419
unsigned int width_total ;
418
420
unsigned int total_header_width ;
421
+ unsigned int extra_row_output_lines = 0 ;
422
+ unsigned int extra_output_lines = 0 ;
419
423
420
424
const char * const * ptr ;
421
425
@@ -424,6 +428,7 @@ print_aligned_text(const printTableContent *cont, bool is_pager, FILE *fout)
424
428
bool * header_done ; /* Have all header lines been output? */
425
429
int * bytes_output ; /* Bytes output for column value */
426
430
int output_columns = 0 ; /* Width of interactive console */
431
+ bool is_pager = false;
427
432
428
433
if (cancel_pressed )
429
434
return ;
@@ -476,9 +481,14 @@ print_aligned_text(const printTableContent *cont, bool is_pager, FILE *fout)
476
481
max_nl_lines [i ] = nl_lines ;
477
482
if (bytes_required > max_bytes [i ])
478
483
max_bytes [i ] = bytes_required ;
484
+ if (nl_lines > extra_row_output_lines )
485
+ extra_row_output_lines = nl_lines ;
479
486
480
487
width_header [i ] = width ;
481
488
}
489
+ /* Add height of tallest header column */
490
+ extra_output_lines += extra_row_output_lines ;
491
+ extra_row_output_lines = 0 ;
482
492
483
493
/* scan all cells, find maximum width, compute cell_count */
484
494
for (i = 0 , ptr = cont -> cells ; * ptr ; ptr ++ , i ++ , cell_count ++ )
@@ -487,7 +497,6 @@ print_aligned_text(const printTableContent *cont, bool is_pager, FILE *fout)
487
497
nl_lines ,
488
498
bytes_required ;
489
499
490
- /* Get width, ignore nl_lines */
491
500
pg_wcssize ((unsigned char * ) * ptr , strlen (* ptr ), encoding ,
492
501
& width , & nl_lines , & bytes_required );
493
502
if (opt_numeric_locale && cont -> aligns [i % col_count ] == 'r' )
@@ -552,28 +561,28 @@ print_aligned_text(const printTableContent *cont, bool is_pager, FILE *fout)
552
561
for (i = 0 ; i < col_count ; i ++ )
553
562
width_wrap [i ] = max_width [i ];
554
563
555
- if (cont -> opt -> format == PRINT_WRAPPED )
564
+ /*
565
+ * Choose target output width: \pset columns, or $COLUMNS, or ioctl
566
+ */
567
+ if (cont -> opt -> columns > 0 )
568
+ output_columns = cont -> opt -> columns ;
569
+ else if ((fout == stdout && isatty (fileno (stdout ))) || is_pager )
556
570
{
557
- /*
558
- * Choose target output width: \pset columns, or $COLUMNS, or ioctl
559
- */
560
- if (cont -> opt -> columns > 0 )
561
- output_columns = cont -> opt -> columns ;
562
- else if ((fout == stdout && isatty (fileno (stdout ))) || is_pager )
563
- {
564
- if (cont -> opt -> env_columns > 0 )
565
- output_columns = cont -> opt -> env_columns ;
571
+ if (cont -> opt -> env_columns > 0 )
572
+ output_columns = cont -> opt -> env_columns ;
566
573
#ifdef TIOCGWINSZ
567
- else
568
- {
569
- struct winsize screen_size ;
570
-
571
- if (ioctl (fileno (stdout ), TIOCGWINSZ , & screen_size ) != -1 )
572
- output_columns = screen_size .ws_col ;
573
- }
574
- #endif
574
+ else
575
+ {
576
+ struct winsize screen_size ;
577
+
578
+ if (ioctl (fileno (stdout ), TIOCGWINSZ , & screen_size ) != -1 )
579
+ output_columns = screen_size .ws_col ;
575
580
}
581
+ #endif
582
+ }
576
583
584
+ if (cont -> opt -> format == PRINT_WRAPPED )
585
+ {
577
586
/*
578
587
* Optional optimized word wrap. Shrink columns with a high max/avg
579
588
* ratio. Slighly bias against wider columns. (Increases chance a
@@ -623,6 +632,49 @@ print_aligned_text(const printTableContent *cont, bool is_pager, FILE *fout)
623
632
}
624
633
}
625
634
635
+ /* If we wrapped beyond the display width, use the pager */
636
+ if (!is_pager && output_columns > 0 &&
637
+ (output_columns < total_header_width || output_columns < width_total ))
638
+ {
639
+ fout = PageOutput (INT_MAX , cont -> opt -> pager ); /* force pager */
640
+ is_pager = true;
641
+ }
642
+
643
+ /* Check if newlines or our wrapping now need the pager */
644
+ if (!is_pager )
645
+ {
646
+ /* scan all cells, find maximum width, compute cell_count */
647
+ for (i = 0 , ptr = cont -> cells ; * ptr ; ptr ++ , i ++ , cell_count ++ )
648
+ {
649
+ int width ,
650
+ nl_lines ,
651
+ bytes_required ;
652
+
653
+ pg_wcssize ((unsigned char * ) * ptr , strlen (* ptr ), encoding ,
654
+ & width , & nl_lines , & bytes_required );
655
+ if (opt_numeric_locale && cont -> align [i % col_count ] == 'r' )
656
+ width += additional_numeric_locale_len (* ptr );
657
+
658
+ /*
659
+ * A row can have both wrapping and newlines that cause
660
+ * it to display across multiple lines. We check
661
+ * for both cases below.
662
+ */
663
+ if (width > 0 && width_wrap [i ] &&
664
+ (width - 1 ) / width_wrap [i ] + nl_lines > extra_row_output_lines )
665
+ extra_row_output_lines = (width - 1 ) / width_wrap [i ] + nl_lines ;
666
+
667
+ /* If last column, add tallest column height */
668
+ if (i % col_count == col_count - 1 )
669
+ {
670
+ /* Add height of tallest row */
671
+ extra_output_lines += extra_row_output_lines ;
672
+ extra_row_output_lines = 0 ;
673
+ }
674
+ }
675
+ IsPagerNeeded (cont , extra_output_lines , & fout , & is_pager );
676
+ }
677
+
626
678
/* time to output */
627
679
if (cont -> opt -> start_table )
628
680
{
@@ -882,6 +934,9 @@ print_aligned_text(const printTableContent *cont, bool is_pager, FILE *fout)
882
934
for (i = 0 ; i < col_count ; i ++ )
883
935
free (format_buf [i ]);
884
936
free (format_buf );
937
+
938
+ if (is_pager )
939
+ ClosePager (fout );
885
940
}
886
941
887
942
@@ -2115,21 +2170,15 @@ printTableCleanup(printTableContent *content)
2115
2170
}
2116
2171
2117
2172
/*
2118
- * Use this to print just any table in the supported formats.
2173
+ * IsPagerNeeded
2174
+ *
2175
+ * Setup pager if required
2119
2176
*/
2120
2177
void
2121
- printTable (const printTableContent * cont , FILE * fout , FILE * flog )
2178
+ IsPagerNeeded (const printTableContent * cont , const int extra_lines , FILE * * fout ,
2179
+ bool * is_pager )
2122
2180
{
2123
- FILE * output ;
2124
- bool is_pager = false;
2125
-
2126
- if (cancel_pressed )
2127
- return ;
2128
-
2129
- if (cont -> opt -> format == PRINT_NOTHING )
2130
- return ;
2131
-
2132
- if (fout == stdout )
2181
+ if (* fout == stdout )
2133
2182
{
2134
2183
int lines ;
2135
2184
@@ -2150,58 +2199,79 @@ printTable(const printTableContent *cont, FILE *fout, FILE *flog)
2150
2199
lines ++ ;
2151
2200
}
2152
2201
2153
- output = PageOutput (lines , cont -> opt -> pager );
2154
- is_pager = (output != fout );
2202
+ * fout = PageOutput (lines + extra_lines , cont -> opt -> pager );
2203
+ * is_pager = (* fout != stdout );
2155
2204
}
2156
2205
else
2157
- output = fout ;
2206
+ * is_pager = false;
2207
+ }
2208
+
2209
+ /*
2210
+ * Use this to print just any table in the supported formats.
2211
+ */
2212
+ void
2213
+ printTable (const printTableContent * cont , FILE * fout , FILE * flog )
2214
+ {
2215
+ bool is_pager = false;
2216
+
2217
+ if (cancel_pressed )
2218
+ return ;
2219
+
2220
+ if (cont -> opt -> format == PRINT_NOTHING )
2221
+ return ;
2222
+
2223
+ /* print_aligned_text() handles the pager itself */
2224
+ if ((cont -> opt -> format != PRINT_ALIGNED &&
2225
+ cont -> opt -> format != PRINT_WRAPPED ) ||
2226
+ cont -> opt -> expanded )
2227
+ IsPagerNeeded (cont , 0 , & fout , & is_pager );
2158
2228
2159
2229
/* print the stuff */
2160
2230
2161
2231
if (flog )
2162
- print_aligned_text (cont , is_pager , flog );
2232
+ print_aligned_text (cont , flog );
2163
2233
2164
2234
switch (cont -> opt -> format )
2165
2235
{
2166
2236
case PRINT_UNALIGNED :
2167
2237
if (cont -> opt -> expanded )
2168
- print_unaligned_vertical (cont , output );
2238
+ print_unaligned_vertical (cont , fout );
2169
2239
else
2170
- print_unaligned_text (cont , output );
2240
+ print_unaligned_text (cont , fout );
2171
2241
break ;
2172
2242
case PRINT_ALIGNED :
2173
2243
case PRINT_WRAPPED :
2174
2244
if (cont -> opt -> expanded )
2175
- print_aligned_vertical (cont , output );
2245
+ print_aligned_vertical (cont , fout );
2176
2246
else
2177
- print_aligned_text (cont , is_pager , output );
2247
+ print_aligned_text (cont , fout );
2178
2248
break ;
2179
2249
case PRINT_HTML :
2180
2250
if (cont -> opt -> expanded )
2181
- print_html_vertical (cont , output );
2251
+ print_html_vertical (cont , fout );
2182
2252
else
2183
- print_html_text (cont , output );
2253
+ print_html_text (cont , fout );
2184
2254
break ;
2185
2255
case PRINT_LATEX :
2186
2256
if (cont -> opt -> expanded )
2187
- print_latex_vertical (cont , output );
2257
+ print_latex_vertical (cont , fout );
2188
2258
else
2189
- print_latex_text (cont , output );
2259
+ print_latex_text (cont , fout );
2190
2260
break ;
2191
2261
case PRINT_TROFF_MS :
2192
2262
if (cont -> opt -> expanded )
2193
- print_troff_ms_vertical (cont , output );
2263
+ print_troff_ms_vertical (cont , fout );
2194
2264
else
2195
- print_troff_ms_text (cont , output );
2265
+ print_troff_ms_text (cont , fout );
2196
2266
break ;
2197
2267
default :
2198
- fprintf (stderr , _ ("invalid output format (internal error): %d" ),
2268
+ fprintf (stderr , _ ("invalid fout format (internal error): %d" ),
2199
2269
cont -> opt -> format );
2200
2270
exit (EXIT_FAILURE );
2201
2271
}
2202
2272
2203
2273
if (is_pager )
2204
- ClosePager (output );
2274
+ ClosePager (fout );
2205
2275
}
2206
2276
2207
2277
/*
0 commit comments