@@ -1346,88 +1346,115 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
13461346#endif
13471347 }
13481348
1349+ /*
1350+ * Calculate available width for data in wrapped mode
1351+ */
13491352 if (cont -> opt -> format == PRINT_WRAPPED )
13501353 {
1351- /*
1352- * Separators width
1353- */
1354- unsigned int width ,
1355- min_width ,
1356- swidth ,
1357- iwidth = 0 ;
1354+ unsigned int swidth ,
1355+ rwidth = 0 ,
1356+ newdwidth ;
13581357
13591358 if (opt_border == 0 )
13601359 {
13611360 /*
1362- * For border = 0, one space in the middle.
1361+ * For border = 0, one space in the middle. (If we discover we
1362+ * need to wrap, the spacer column will be replaced by a wrap
1363+ * marker, and we'll make room below for another wrap marker at
1364+ * the end of the line. But for now, assume no wrap is needed.)
13631365 */
13641366 swidth = 1 ;
1367+
1368+ /* We might need a column for header newline markers, too */
1369+ if (hmultiline )
1370+ swidth ++ ;
13651371 }
13661372 else if (opt_border == 1 )
13671373 {
13681374 /*
1369- * For border = 1, one for the pipe (|) in the middle between the
1370- * two spaces.
1375+ * For border = 1, two spaces and a vrule in the middle. (As
1376+ * above, we might need one more column for a wrap marker.)
13711377 */
13721378 swidth = 3 ;
1379+
1380+ /* We might need a column for left header newline markers, too */
1381+ if (hmultiline && (format == & pg_asciiformat_old ))
1382+ swidth ++ ;
13731383 }
13741384 else
1375-
1385+ {
13761386 /*
1377- * For border = 2, two more for the pipes (|) at the beginning and
1378- * at the end of the lines.
1387+ * For border = 2, two more for the vrules at the beginning and
1388+ * end of the lines, plus spacer columns adjacent to these. (We
1389+ * won't need extra columns for wrap/newline markers, we'll just
1390+ * repurpose the spacers.)
13791391 */
13801392 swidth = 7 ;
1393+ }
13811394
1382- if ((opt_border < 2 ) &&
1383- ((hmultiline &&
1384- (format == & pg_asciiformat_old )) ||
1385- (dmultiline &&
1386- (format != & pg_asciiformat_old ))))
1387- iwidth ++ ; /* for newline indicators */
1388-
1389- min_width = hwidth + iwidth + swidth + 3 ;
1395+ /* Reserve a column for data newline indicators, too, if needed */
1396+ if (dmultiline &&
1397+ opt_border < 2 && format != & pg_asciiformat_old )
1398+ swidth ++ ;
13901399
1391- /*
1392- * Record header width
1393- */
1400+ /* Determine width required for record header lines */
13941401 if (!opt_tuples_only )
13951402 {
1396- /*
1397- * Record number
1398- */
1399- unsigned int rwidth = 1 + log10 (cont -> nrows );
1400-
1403+ rwidth = 1 + log10 (cont -> nrows );
14011404 if (opt_border == 0 )
14021405 rwidth += 9 ; /* "* RECORD " */
14031406 else if (opt_border == 1 )
14041407 rwidth += 12 ; /* "-[ RECORD ]" */
14051408 else
14061409 rwidth += 15 ; /* "+-[ RECORD ]-+" */
1410+ }
1411+
1412+ /* We might need to do the rest of the calculation twice */
1413+ for (;;)
1414+ {
1415+ unsigned int width ,
1416+ min_width ;
1417+
1418+ /* Total width required to not wrap data */
1419+ width = hwidth + swidth + dwidth ;
14071420
1421+ /* Minimum acceptable width: room for just 3 columns of data */
1422+ min_width = hwidth + swidth + 3 ;
1423+ /* ... but not less than what the record header lines need */
14081424 if (rwidth > min_width )
14091425 min_width = rwidth ;
1410- }
14111426
1412- /* Wrap to minimum width */
1413- width = hwidth + iwidth + swidth + dwidth ;
1414- if ((width < min_width ) || (output_columns < min_width ))
1415- width = min_width - hwidth - iwidth - swidth ;
1416- else if (output_columns > 0 )
1427+ if (width < min_width || output_columns < min_width )
1428+ {
1429+ /* Set data width to match min_width */
1430+ newdwidth = min_width - hwidth - swidth ;
1431+ }
1432+ else if (output_columns > 0 )
1433+ {
1434+ /* Set data width to match output_columns */
1435+ newdwidth = output_columns - hwidth - swidth ;
1436+ }
1437+ else
1438+ {
1439+ /* Use native data width */
1440+ newdwidth = dwidth ;
1441+ }
14171442
14181443 /*
1419- * Wrap to maximum width
1444+ * If we will need to wrap data and didn't already allocate a data
1445+ * newline/wrap marker column, do so and recompute.
14201446 */
1421- width = output_columns - hwidth - iwidth - swidth ;
1422-
1423- if (( width < dwidth ) || ( dheight > 1 ))
1424- {
1425- dmultiline = true ;
1426- if (( opt_border == 0 ) &&
1427- ( format != & pg_asciiformat_old ))
1428- width -- ; /* for wrap indicators */
1447+ if ( newdwidth < dwidth && ! dmultiline &&
1448+ opt_border < 2 && format != & pg_asciiformat_old )
1449+ {
1450+ dmultiline = true;
1451+ swidth ++ ;
1452+ }
1453+ else
1454+ break ;
14291455 }
1430- dwidth = width ;
1456+
1457+ dwidth = newdwidth ;
14311458 }
14321459
14331460 /* print records */
@@ -1558,12 +1585,10 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
15581585 {
15591586 if (offset )
15601587 fputs (format -> midvrule_wrap , fout );
1561- else if (! dline )
1588+ else if (dline == 0 )
15621589 fputs (dformat -> midvrule , fout );
1563- else if (dline )
1564- fputs (format -> midvrule_nl , fout );
15651590 else
1566- fputs (format -> midvrule_blank , fout );
1591+ fputs (format -> midvrule_nl , fout );
15671592 }
15681593
15691594 /* Data */
@@ -1574,9 +1599,9 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
15741599 swidth = dwidth ;
15751600
15761601 /*
1577- * Left spacer on wrap indicator
1602+ * Left spacer or wrap indicator
15781603 */
1579- fputs (! dcomplete && ! offset ? " " : format -> wrap_left , fout );
1604+ fputs (offset == 0 ? " " : format -> wrap_left , fout );
15801605
15811606 /*
15821607 * Data text
0 commit comments