32#include "catalog/pg_type_d.h"
38#define NEED_COUNT_TABLE_LINES
156 {
"\342\224\234",
"\342\225\237"},
163 {
"\342\224\244",
"\342\225\242"},
174 {
"\342\225\236",
"\342\225\240"},
181 {
"\342\225\241",
"\342\225\243"},
194 {
"\342\224\274",
"\342\225\252"},
201 {
"\342\224\264",
"\342\225\247"},
208 {
"\342\224\254",
"\342\225\244"},
219 {
"\342\225\253",
"\342\225\254"},
226 {
"\342\225\250",
"\342\225\251"},
233 {
"\342\225\245",
"\342\225\246"},
246 {
"\342\224\224",
"\342\224\202",
"\342\224\214",
"\342\224\200",
"\342\224\220",
"\342\224\230"},
257 {
"\342\225\232",
"\342\225\221",
"\342\225\224",
"\342\225\220",
"\342\225\227",
"\342\225\235"},
276 const unsigned int *width_wrap,
279 const unsigned int *width_wrap,
281 FILE **fout,
bool *is_pager);
282#ifdef NEED_COUNT_TABLE_LINES
284 const unsigned int *width_wrap,
289 FILE *fout,
bool is_pager);
297 if (my_str[0] ==
'-' || my_str[0] ==
'+')
300 return strspn(my_str,
"0123456789");
315 if (strchr(my_str,
'.') != NULL)
343 if (strspn(my_str,
"0123456789+-.eE") != strlen(my_str))
353 if (leading_digits == 0)
357 if (my_str[0] ==
'-' || my_str[0] ==
'+')
359 new_str[new_str_pos++] = my_str[0];
364 for (
i = 0;
i < int_len;
i++)
367 if (
i > 0 && --leading_digits == 0)
373 new_str[new_str_pos++] = my_str[
i];
377 if (my_str[
i] ==
'.')
385 strcpy(&new_str[new_str_pos], &my_str[
i]);
388 Assert(strlen(new_str) <= new_len);
418 unsigned long total_records;
422 ngettext(
"(%lu row)",
"(%lu rows)", total_records),
442 const char *
const *ptr;
443 bool need_recordsep =
false;
451 if (!opt_tuples_only && cont->
title)
453 fputs(cont->
title, fout);
458 if (!opt_tuples_only)
460 for (ptr = cont->
headers; *ptr; ptr++)
466 need_recordsep =
true;
471 need_recordsep =
true;
474 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
479 need_recordsep =
false;
488 need_recordsep =
true;
500 for (f = footers; f; f = f->
next)
505 need_recordsep =
false;
507 fputs(f->
data, fout);
508 need_recordsep =
true;
533 const char *
const *ptr;
534 bool need_recordsep =
false;
542 if (!opt_tuples_only && cont->
title)
544 fputs(cont->
title, fout);
545 need_recordsep =
true;
550 need_recordsep =
true;
553 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
560 need_recordsep =
false;
572 need_recordsep =
true;
586 fputs(f->
data, fout);
619 fputs(lformat->
hrule, fout);
620 else if (border == 2)
623 for (
i = 0;
i < ncolumns;
i++)
625 for (
j = 0;
j < widths[
i];
j++)
626 fputs(lformat->
hrule, fout);
628 if (
i < ncolumns - 1)
640 else if (border == 1)
641 fputs(lformat->
hrule, fout);
655 unsigned short opt_border = cont->
opt->
border;
659 unsigned int col_count = 0,
665 unsigned int *width_header,
669 unsigned int *max_nl_lines,
672 unsigned char **format_buf;
673 unsigned int width_total;
674 unsigned int total_header_width;
676 const char *
const *ptr;
683 int output_columns = 0;
684 bool is_local_pager =
false;
695 width_header =
pg_malloc0(col_count *
sizeof(*width_header));
696 width_average =
pg_malloc0(col_count *
sizeof(*width_average));
697 max_width =
pg_malloc0(col_count *
sizeof(*max_width));
698 width_wrap =
pg_malloc0(col_count *
sizeof(*width_wrap));
699 max_nl_lines =
pg_malloc0(col_count *
sizeof(*max_nl_lines));
700 curr_nl_line =
pg_malloc0(col_count *
sizeof(*curr_nl_line));
701 col_lineptrs =
pg_malloc0(col_count *
sizeof(*col_lineptrs));
702 max_bytes =
pg_malloc0(col_count *
sizeof(*max_bytes));
703 format_buf =
pg_malloc0(col_count *
sizeof(*format_buf));
704 header_done =
pg_malloc0(col_count *
sizeof(*header_done));
705 bytes_output =
pg_malloc0(col_count *
sizeof(*bytes_output));
711 width_average = NULL;
725 for (
i = 0;
i < col_count;
i++)
735 if (nl_lines > max_nl_lines[
i])
736 max_nl_lines[
i] = nl_lines;
737 if (bytes_required > max_bytes[
i])
738 max_bytes[
i] = bytes_required;
751 &
width, &nl_lines, &bytes_required);
755 if (nl_lines > max_nl_lines[
i])
756 max_nl_lines[
i] = nl_lines;
757 if (bytes_required > max_bytes[
i])
758 max_bytes[
i] = bytes_required;
760 width_average[
i] +=
width;
763 if (++
i >= col_count)
768 if (col_count != 0 && cell_count != 0)
770 int rows = cell_count / col_count;
772 for (
i = 0;
i < col_count;
i++)
773 width_average[
i] /= rows;
778 width_total = col_count;
779 else if (opt_border == 1)
780 width_total = col_count * 3 - ((col_count > 0) ? 1 : 0);
782 width_total = col_count * 3 + 1;
783 total_header_width = width_total;
785 for (
i = 0;
i < col_count;
i++)
787 width_total += max_width[
i];
788 total_header_width += width_header[
i];
798 for (
i = 0;
i < col_count;
i++)
802 sizeof(**col_lineptrs));
806 col_lineptrs[
i]->
ptr = format_buf[
i];
810 for (
i = 0;
i < col_count;
i++)
811 width_wrap[
i] = max_width[
i];
818 else if ((fout ==
stdout && isatty(fileno(
stdout))) || is_pager)
825 struct winsize screen_size;
827 if (ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size) != -1)
828 output_columns = screen_size.ws_col;
842 if (output_columns > 0 && output_columns >= total_header_width)
845 while (width_total > output_columns)
847 double max_ratio = 0;
856 for (
i = 0;
i < col_count;
i++)
858 if (width_average[
i] && width_wrap[
i] > width_header[
i])
863 ratio = (double) width_wrap[
i] / width_average[
i] +
865 if (ratio > max_ratio)
878 width_wrap[worst_col]--;
891 (output_columns < total_header_width || output_columns < width_total))
898 if (!is_pager && fout ==
stdout && output_columns > 0 &&
899 (output_columns < total_header_width || output_columns < width_total))
902 is_pager = is_local_pager =
true;
909 is_local_pager = is_pager;
916 if (cont->
title && !opt_tuples_only)
923 if (width >= width_total)
928 fprintf(fout,
"%-*s%s\n", (width_total - width) / 2,
"",
933 if (!opt_tuples_only)
935 int more_col_wrapping;
942 for (
i = 0;
i < col_count;
i++)
945 col_lineptrs[
i], max_nl_lines[
i]);
947 more_col_wrapping = col_count;
950 memset(header_done,
false, col_count *
sizeof(
bool));
951 while (more_col_wrapping)
958 struct lineptr *this_line = col_lineptrs[
i] + curr_nl_line;
959 unsigned int nbspace;
961 if (opt_border != 0 ||
962 (!
format->wrap_right_border &&
i > 0))
963 fputs(curr_nl_line ?
format->header_nl_left :
" ",
968 nbspace = width_wrap[
i] - this_line->
width;
972 nbspace / 2,
"", this_line->
ptr, (nbspace + 1) / 2,
"");
974 if (!(this_line + 1)->
ptr)
981 fprintf(fout,
"%*s", width_wrap[
i],
"");
983 if (opt_border != 0 ||
format->wrap_right_border)
984 fputs(!header_done[
i] ?
format->header_nl_right :
" ",
987 if (opt_border != 0 && col_count > 0 &&
i < col_count - 1)
1013 for (
j = 0;
j < col_count;
j++)
1016 col_lineptrs[
j], max_nl_lines[
j]);
1017 curr_nl_line[
j] = 0;
1020 memset(bytes_output, 0, col_count *
sizeof(
int));
1032 if (opt_border == 2)
1036 for (
j = 0;
j < col_count;
j++)
1039 struct lineptr *this_line = &col_lineptrs[
j][curr_nl_line[
j]];
1040 int bytes_to_output;
1041 int chars_to_output = width_wrap[
j];
1042 bool finalspaces = (opt_border == 2 ||
1043 (col_count > 0 &&
j < col_count - 1));
1046 if (opt_border != 0)
1049 fputs(
format->wrap_left, fout);
1051 fputs(
format->nl_left, fout);
1056 if (!this_line->
ptr)
1060 fprintf(fout,
"%*s", chars_to_output,
"");
1075 if (chars_to_output > width_wrap[
j])
1076 chars_to_output = width_wrap[
j];
1081 fprintf(fout,
"%*s", width_wrap[
j] - chars_to_output,
"");
1082 fwrite((
char *) (this_line->
ptr + bytes_output[
j]),
1083 1, bytes_to_output, fout);
1088 fwrite((
char *) (this_line->
ptr + bytes_output[
j]),
1089 1, bytes_to_output, fout);
1092 bytes_output[
j] += bytes_to_output;
1095 if (*(this_line->
ptr + bytes_output[
j]) !=
'\0')
1101 if (col_lineptrs[
j][curr_nl_line[
j]].
ptr != NULL)
1103 bytes_output[
j] = 0;
1109 if (col_lineptrs[
j][curr_nl_line[
j]].
ptr != NULL)
1111 if (bytes_output[
j] != 0)
1113 else if (curr_nl_line[
j] != 0)
1127 width_wrap[
j] - chars_to_output,
"");
1132 fputs(
format->wrap_right, fout);
1134 fputs(
format->nl_right, fout);
1135 else if (opt_border == 2 || (col_count > 0 &&
j < col_count - 1))
1139 if (opt_border != 0 && (col_count > 0 &&
j < col_count - 1))
1142 fputs(
format->midvrule_wrap, fout);
1144 fputs(
format->midvrule_nl, fout);
1145 else if (col_lineptrs[
j + 1][curr_nl_line[
j + 1]].
ptr == NULL)
1146 fputs(
format->midvrule_blank, fout);
1153 if (opt_border == 2)
1156 }
while (more_lines);
1172 for (f = footers; f; f = f->
next)
1181 for (
i = 0;
i < col_count;
i++)
1183 free(col_lineptrs[
i]);
1184 free(format_buf[
i]);
1187 free(width_average);
1206 unsigned long record,
1207 unsigned int hwidth,
1208 unsigned int dwidth,
1214 const unsigned short opt_border = topt->
border;
1218 if (opt_border == 2)
1220 else if (opt_border == 1)
1221 fputs(lformat->
hrule, fout);
1225 if (opt_border == 0)
1226 reclen =
fprintf(fout,
"* Record %lu", record);
1228 reclen =
fprintf(fout,
"[ RECORD %lu ]", record);
1230 if (opt_border != 2)
1234 for (
i = reclen;
i < hwidth;
i++)
1235 fputs(opt_border > 0 ? lformat->
hrule :
" ", fout);
1241 fputs(lformat->
hrule, fout);
1255 fputs(lformat->
hrule, fout);
1272 if (output_columns > 0)
1274 if (opt_border == 0)
1275 dwidth =
Min(dwidth,
Max(0, (
int) (output_columns - hwidth)));
1276 if (opt_border == 1)
1277 dwidth =
Min(dwidth,
Max(0, (
int) (output_columns - hwidth - 3)));
1284 if (opt_border == 2)
1285 dwidth =
Min(dwidth,
Max(0, (
int) (output_columns - hwidth - 7)));
1291 if (dwidth < reclen)
1294 for (
i = reclen;
i < dwidth;
i++)
1295 fputs(opt_border > 0 ? lformat->
hrule :
" ", fout);
1296 if (opt_border == 2)
1305 FILE *fout,
bool is_pager)
1308 unsigned short opt_border = cont->
opt->
border;
1313 const char *
const *
ptr;
1323 bool is_local_pager =
false,
1326 int output_columns = 0;
1348 for (f = footers; f; f = f->
next)
1365 is_local_pager = is_pager;
1379 if (height > hheight)
1384 if (fs > hformatsize)
1396 &
width, &height, &fs);
1399 if (height > dheight)
1404 if (fs > dformatsize)
1412 dlineptr =
pg_malloc((
sizeof(*dlineptr)) * (dheight + 1));
1413 hlineptr =
pg_malloc((
sizeof(*hlineptr)) * (hheight + 1));
1421 if (!opt_tuples_only && cont->
title)
1430 else if ((fout ==
stdout && isatty(fileno(
stdout))) || is_pager)
1437 struct winsize screen_size;
1439 if (ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size) != -1)
1440 output_columns = screen_size.ws_col;
1450 unsigned int swidth,
1454 if (opt_border == 0)
1468 else if (opt_border == 1)
1497 if (!opt_tuples_only)
1499 if (cont->
nrows > 0)
1500 rwidth = 1 + (int) log10(cont->
nrows);
1501 if (opt_border == 0)
1503 else if (opt_border == 1)
1515 width = hwidth + swidth + dwidth;
1520 if (output_columns > 0)
1522 unsigned int min_width;
1525 min_width = hwidth + swidth + 3;
1527 if (min_width < rwidth)
1530 if (output_columns >= width)
1534 newdwidth = width - hwidth - swidth;
1536 else if (output_columns < min_width)
1539 newdwidth = min_width - hwidth - swidth;
1544 newdwidth = output_columns - hwidth - swidth;
1551 newdwidth = width - hwidth - swidth;
1558 if (newdwidth < dwidth && !dmultiline &&
1572 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
1593 unsigned int lhwidth = hwidth;
1595 if ((opt_border < 2) &&
1600 if (!opt_tuples_only)
1602 lhwidth, dwidth, output_columns,
1606 dwidth, output_columns, pos, fout);
1622 dcomplete = hcomplete = 0;
1624 chars_to_output = dlineptr[dline].
width;
1625 while (!dcomplete || !hcomplete)
1628 if (opt_border == 2)
1634 int swidth = hwidth,
1635 target_width = hwidth;
1640 if ((opt_border == 2) ||
1642 fputs(hline ?
format->header_nl_left :
" ", fout);
1649 fprintf(fout,
"%-s", hlineptr[hline].ptr);
1654 swidth -= target_width;
1656 fprintf(fout,
"%*s", swidth,
" ");
1661 if (hlineptr[hline + 1].ptr)
1664 if ((opt_border > 0) ||
1666 fputs(
format->header_nl_right, fout);
1672 if ((opt_border > 0) ||
1680 unsigned int swidth = hwidth + opt_border;
1682 if ((opt_border < 2) &&
1687 if ((opt_border == 0) &&
1692 fprintf(fout,
"%*s", swidth,
" ");
1699 fputs(
format->midvrule_wrap, fout);
1700 else if (dline == 0)
1703 fputs(
format->midvrule_nl, fout);
1709 int target_width = dwidth,
1716 fputs(offset == 0 ?
" " :
format->wrap_left, fout);
1723 fwrite((
char *) (dlineptr[dline].ptr + offset),
1724 1, bytes_to_output, fout);
1726 chars_to_output -= target_width;
1727 offset += bytes_to_output;
1730 swidth -= target_width;
1732 if (chars_to_output)
1735 if ((opt_border > 1) ||
1739 fprintf(fout,
"%*s", swidth,
" ");
1740 fputs(
format->wrap_right, fout);
1743 else if (dlineptr[dline + 1].ptr)
1746 if ((opt_border > 1) ||
1750 fprintf(fout,
"%*s", swidth,
" ");
1751 fputs(
format->nl_right, fout);
1755 chars_to_output = dlineptr[dline].
width;
1763 fprintf(fout,
"%*s", swidth,
" ");
1770 if (opt_border == 2)
1830 for (p =
str; *p; p++)
1855 if (strchr(
str, sep) != NULL ||
1856 strcspn(
str,
"\r\n\"") != strlen(
str) ||
1857 strcmp(
str,
"\\.") == 0 ||
1858 sep ==
'\\' || sep ==
'.')
1867 const char *
const *ptr;
1884 for (ptr = cont->
headers; *ptr; ptr++)
1894 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
1907 const char *
const *ptr;
1911 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
1940 bool leading_space =
true;
1942 for (p = in; *p; p++)
1947 fputs(
"&", fout);
1950 fputs(
"<", fout);
1953 fputs(
">", fout);
1956 fputs(
"<br />\n", fout);
1959 fputs(
""", fout);
1964 fputs(
" ", fout);
1972 leading_space =
false;
1981 unsigned short opt_border = cont->
opt->
border;
1984 const char *
const *ptr;
1991 fprintf(fout,
"<table border=\"%d\"", opt_border);
1993 fprintf(fout,
" %s", opt_table_attr);
1997 if (!opt_tuples_only && cont->
title)
1999 fputs(
" <caption>", fout);
2001 fputs(
"</caption>\n", fout);
2005 if (!opt_tuples_only)
2007 fputs(
" <tr>\n", fout);
2008 for (ptr = cont->
headers; *ptr; ptr++)
2010 fputs(
" <th align=\"center\">", fout);
2012 fputs(
"</th>\n", fout);
2014 fputs(
" </tr>\n", fout);
2019 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2025 fputs(
" <tr valign=\"top\">\n", fout);
2030 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2031 fputs(
" ", fout);
2035 fputs(
"</td>\n", fout);
2038 fputs(
" </tr>\n", fout);
2045 fputs(
"</table>\n", fout);
2053 for (f = footers; f; f = f->
next)
2056 fputs(
"<br />\n", fout);
2058 fputs(
"</p>", fout);
2070 unsigned short opt_border = cont->
opt->
border;
2074 const char *
const *ptr;
2081 fprintf(fout,
"<table border=\"%d\"", opt_border);
2083 fprintf(fout,
" %s", opt_table_attr);
2087 if (!opt_tuples_only && cont->
title)
2089 fputs(
" <caption>", fout);
2091 fputs(
"</caption>\n", fout);
2096 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2102 if (!opt_tuples_only)
2104 "\n <tr><td colspan=\"2\" align=\"center\">Record %lu</td></tr>\n",
2107 fputs(
"\n <tr><td colspan=\"2\"> </td></tr>\n", fout);
2109 fputs(
" <tr valign=\"top\">\n"
2112 fputs(
"</th>\n", fout);
2116 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2117 fputs(
" ", fout);
2121 fputs(
"</td>\n </tr>\n", fout);
2126 fputs(
"</table>\n", fout);
2137 fputs(
"<br />\n", fout);
2139 fputs(
"</p>", fout);
2157 for (p = in; *p; p++)
2174 unsigned short opt_border = cont->
opt->
border;
2176 const char *
const *ptr;
2187 if (!opt_tuples_only && cont->
title)
2190 fputs(cont->
title, fout);
2195 fprintf(fout,
"[%scols=\"", !opt_tuples_only ?
"options=\"header\"," :
"");
2206 fputs(
",frame=\"none\",grid=\"none\"", fout);
2209 fputs(
",frame=\"none\"", fout);
2212 fputs(
",frame=\"all\",grid=\"all\"", fout);
2216 fputs(
"|====\n", fout);
2219 if (!opt_tuples_only)
2221 for (ptr = cont->
headers; *ptr; ptr++)
2233 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2246 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2258 fputs(
"|====\n", fout);
2269 fputs(
"\n....\n", fout);
2270 for (f = footers; f; f = f->
next)
2272 fputs(f->
data, fout);
2275 fputs(
"....\n", fout);
2284 unsigned short opt_border = cont->
opt->
border;
2287 const char *
const *ptr;
2298 if (!opt_tuples_only && cont->
title)
2301 fputs(cont->
title, fout);
2306 fputs(
"[cols=\"h,l\"", fout);
2310 fputs(
",frame=\"none\",grid=\"none\"", fout);
2313 fputs(
",frame=\"none\"", fout);
2316 fputs(
",frame=\"all\",grid=\"all\"", fout);
2320 fputs(
"|====\n", fout);
2324 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2330 if (!opt_tuples_only)
2335 fputs(
"2+|\n", fout);
2343 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2350 fputs(
"|====\n", fout);
2359 fputs(
"\n....\n", fout);
2362 fputs(f->
data, fout);
2365 fputs(
"....\n", fout);
2381 for (p = in; *p; p++)
2402 fputs(
"\\textless{}", fout);
2405 fputs(
"\\textgreater{}", fout);
2408 fputs(
"\\textbackslash{}", fout);
2411 fputs(
"\\^{}", fout);
2420 fputs(
"\\textbar{}", fout);
2426 fputs(
"\\~{}", fout);
2430 fputs(
"\\\\", fout);
2442 unsigned short opt_border = cont->
opt->
border;
2444 const char *
const *ptr;
2455 if (!opt_tuples_only && cont->
title)
2457 fputs(
"\\begin{center}\n", fout);
2459 fputs(
"\n\\end{center}\n\n", fout);
2463 fputs(
"\\begin{tabular}{", fout);
2465 if (opt_border >= 2)
2469 fputc(*(cont->
aligns +
i), fout);
2470 if (opt_border != 0 && i < cont->ncolumns - 1)
2473 if (opt_border >= 2)
2478 if (!opt_tuples_only && opt_border >= 2)
2479 fputs(
"\\hline\n", fout);
2482 if (!opt_tuples_only)
2484 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2488 fputs(
"\\textit{", fout);
2492 fputs(
" \\\\\n", fout);
2493 fputs(
"\\hline\n", fout);
2498 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2504 fputs(
" \\\\\n", fout);
2505 if (opt_border == 3)
2506 fputs(
"\\hline\n", fout);
2518 if (opt_border == 2)
2519 fputs(
"\\hline\n", fout);
2521 fputs(
"\\end{tabular}\n\n\\noindent ", fout);
2528 for (f = footers; f; f = f->
next)
2531 fputs(
" \\\\\n", fout);
2549 unsigned short opt_border = cont->
opt->
border;
2552 const char *next_opt_table_attr_char = opt_table_attr;
2553 const char *last_opt_table_attr_char = NULL;
2554 const char *
const *ptr;
2565 fputs(
"\\begin{longtable}{", fout);
2567 if (opt_border >= 2)
2574 if (*(cont->
aligns +
i) ==
'l' && opt_table_attr)
2576#define LONGTABLE_WHITESPACE " \t\n"
2579 next_opt_table_attr_char += strspn(next_opt_table_attr_char,
2582 if (next_opt_table_attr_char[0] !=
'\0')
2585 fwrite(next_opt_table_attr_char, strcspn(next_opt_table_attr_char,
2587 last_opt_table_attr_char = next_opt_table_attr_char;
2588 next_opt_table_attr_char += strcspn(next_opt_table_attr_char,
2590 fputs(
"\\textwidth}", fout);
2593 else if (last_opt_table_attr_char != NULL)
2596 fwrite(last_opt_table_attr_char, strcspn(last_opt_table_attr_char,
2598 fputs(
"\\textwidth}", fout);
2604 fputc(*(cont->
aligns +
i), fout);
2606 if (opt_border != 0 && i < cont->ncolumns - 1)
2610 if (opt_border >= 2)
2616 if (!opt_tuples_only)
2619 if (opt_border >= 2)
2620 fputs(
"\\toprule\n", fout);
2621 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2625 fputs(
"\\small\\textbf{\\textit{", fout);
2629 fputs(
" \\\\\n", fout);
2630 fputs(
"\\midrule\n\\endfirsthead\n", fout);
2633 if (opt_border >= 2)
2634 fputs(
"\\toprule\n", fout);
2635 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2639 fputs(
"\\small\\textbf{\\textit{", fout);
2643 fputs(
" \\\\\n", fout);
2645 if (opt_border != 3)
2646 fputs(
"\\midrule\n", fout);
2647 fputs(
"\\endhead\n", fout);
2650 if (!opt_tuples_only && cont->
title)
2653 if (opt_border == 2)
2654 fputs(
"\\bottomrule\n", fout);
2655 fputs(
"\\caption[", fout);
2657 fputs(
" (Continued)]{", fout);
2659 fputs(
"}\n\\endfoot\n", fout);
2660 if (opt_border == 2)
2661 fputs(
"\\bottomrule\n", fout);
2662 fputs(
"\\caption[", fout);
2666 fputs(
"}\n\\endlastfoot\n", fout);
2669 else if (opt_border >= 2)
2671 fputs(
"\\bottomrule\n\\endfoot\n", fout);
2672 fputs(
"\\bottomrule\n\\endlastfoot\n", fout);
2678 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2682 fputs(
"\n&\n", fout);
2683 fputs(
"\\raggedright{", fout);
2688 fputs(
" \\tabularnewline\n", fout);
2689 if (opt_border == 3)
2690 fputs(
" \\hline\n", fout);
2697 fputs(
"\\end{longtable}\n", fout);
2705 unsigned short opt_border = cont->
opt->
border;
2708 const char *
const *ptr;
2719 if (!opt_tuples_only && cont->
title)
2721 fputs(
"\\begin{center}\n", fout);
2723 fputs(
"\n\\end{center}\n\n", fout);
2727 fputs(
"\\begin{tabular}{", fout);
2728 if (opt_border == 0)
2730 else if (opt_border == 1)
2732 else if (opt_border == 2)
2733 fputs(
"|c|l|", fout);
2738 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2745 if (!opt_tuples_only)
2747 if (opt_border == 2)
2749 fputs(
"\\hline\n", fout);
2750 fprintf(fout,
"\\multicolumn{2}{|c|}{\\textit{Record %lu}} \\\\\n", record++);
2753 fprintf(fout,
"\\multicolumn{2}{c}{\\textit{Record %lu}} \\\\\n", record++);
2755 if (opt_border >= 1)
2756 fputs(
"\\hline\n", fout);
2762 fputs(
" \\\\\n", fout);
2767 if (opt_border == 2)
2768 fputs(
"\\hline\n", fout);
2770 fputs(
"\\end{tabular}\n\n\\noindent ", fout);
2780 fputs(
" \\\\\n", fout);
2799 for (p = in; *p; p++)
2803 fputs(
"\\(rs", fout);
2815 unsigned short opt_border = cont->
opt->
border;
2817 const char *
const *ptr;
2828 if (!opt_tuples_only && cont->
title)
2830 fputs(
".LP\n.DS C\n", fout);
2832 fputs(
"\n.DE\n", fout);
2836 fputs(
".LP\n.TS\n", fout);
2837 if (opt_border == 2)
2838 fputs(
"center box;\n", fout);
2840 fputs(
"center;\n", fout);
2844 fputc(*(cont->
aligns +
i), fout);
2845 if (opt_border > 0 && i < cont->ncolumns - 1)
2851 if (!opt_tuples_only)
2853 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2857 fputs(
"\\fI", fout);
2859 fputs(
"\\fP", fout);
2861 fputs(
"\n_\n", fout);
2866 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2884 fputs(
".TE\n.DS L\n", fout);
2891 for (f = footers; f; f = f->
next)
2898 fputs(
".DE\n", fout);
2907 unsigned short opt_border = cont->
opt->
border;
2910 const char *
const *ptr;
2911 unsigned short current_format = 0;
2922 if (!opt_tuples_only && cont->
title)
2924 fputs(
".LP\n.DS C\n", fout);
2926 fputs(
"\n.DE\n", fout);
2930 fputs(
".LP\n.TS\n", fout);
2931 if (opt_border == 2)
2932 fputs(
"center box;\n", fout);
2934 fputs(
"center;\n", fout);
2937 if (opt_tuples_only)
2938 fputs(
"c l;\n", fout);
2944 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2951 if (!opt_tuples_only)
2953 if (current_format != 1)
2955 if (opt_border == 2 && record > 1)
2957 if (current_format != 0)
2958 fputs(
".T&\n", fout);
2959 fputs(
"c s.\n", fout);
2962 fprintf(fout,
"\\fIRecord %lu\\fP\n", record++);
2964 if (opt_border >= 1)
2968 if (!opt_tuples_only)
2970 if (current_format != 2)
2972 if (current_format != 0)
2973 fputs(
".T&\n", fout);
2974 if (opt_border != 1)
2975 fputs(
"c l.\n", fout);
2977 fputs(
"c | l.\n", fout);
2991 fputs(
".TE\n.DS L\n", fout);
3005 fputs(
".DE\n", fout);
3092 const unsigned int *width_wrap,
3096 if (topt && topt->
pager && isatty(fileno(stdin)) && isatty(fileno(
stdout)))
3100 unsigned short int pager = topt->
pager;
3106 struct winsize screen_size;
3108 result = ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size);
3113 int threshold =
Max(screen_size.ws_row, min_lines);
3116 lines = count_table_lines(cont, width_wrap, vertical,
3119 if (lines >= threshold)
3127 const char *pagerprog;
3130 pagerprog = getenv(
"PSQL_PAGER");
3132 pagerprog = getenv(
"PAGER");
3138 if (strspn(pagerprog,
" \t\r\n") == strlen(pagerprog))
3143 pagerpipe = popen(pagerprog,
"w");
3162 if (pagerpipe && pagerpipe !=
stdout)
3173 fprintf(pagerpipe,
_(
"Interrupted\n"));
3192 const char *title,
const int ncolumns,
const int nrows)
3197 content->
title = title;
3199 content->
nrows = nrows;
3203 total_cells = (
uint64) ncolumns * nrows;
3205 if (total_cells >= SIZE_MAX /
sizeof(*content->
cells))
3207 fprintf(stderr,
_(
"Cannot print table contents: number of cells %" PRIu64
" is equal to or exceeds maximum %zu.\n"),
3209 SIZE_MAX /
sizeof(*content->
cells));
3248 fprintf(stderr,
_(
"Cannot add header to table content: "
3249 "column count of %d exceeded.\n"),
3262 *content->
align = align;
3280 const bool translate,
const bool mustfree)
3291 fprintf(stderr,
_(
"Cannot add cell to table content: total cell count of %" PRIu64
" exceeded.\n"),
3308 pg_malloc0((total_cells + 1) *
sizeof(
bool));
3391 content->
opt = NULL;
3392 content->
title = NULL;
3394 content->
cells = NULL;
3397 content->
cell = NULL;
3398 content->
align = NULL;
3432 FILE **fout,
bool *is_pager)
3437 *is_pager = (*fout !=
stdout);
3461#ifdef NEED_COUNT_TABLE_LINES
3464 const unsigned int *width_wrap,
3474 const char *
const *cell;
3485 NULL, &header_height[
i], NULL);
3501 lines = vertical ? cont->
nrows : 1;
3528 lines = vertical ? cont->
nrows : 1;
3537 for (
i = 0, cell = cont->
cells; *cell; cell++)
3543 &width, &nl_lines, NULL);
3546 if (width > 0 && width_wrap && width_wrap[
i])
3547 nl_lines += (width - 1) / width_wrap[
i];
3552 if (nl_lines > header_height[
i])
3555 lines += header_height[
i];
3560 if (nl_lines > max_lines)
3561 max_lines = nl_lines;
3575 if (lines > threshold)
3599 if (header_height[
i] > max_lines)
3600 max_lines = header_height[
i];
3610 f != NULL; f = f->
next)
3616 if (lines > threshold)
3621 free(header_height);
3637 FILE *fout,
bool is_pager, FILE *flog)
3639 bool is_local_pager =
false;
3653 is_local_pager = is_pager;
3719 fprintf(stderr,
_(
"invalid output format (internal error): %d"),
3743 FILE *fout,
bool is_pager, FILE *flog)
3768 for (r = 0; r < cont.
nrows; r++)
3773 bool mustfree =
false;
3778 else if (
PQftype(result,
c) == BOOLOID)
3802 for (footer = opt->
footers; *footer; footer++)
3840 struct lconv *extlconv;
3842 extlconv = localeconv();
3845 if (*extlconv->decimal_point)
3858 if (groupdigits <= 0 || groupdigits > 6)
3863 if (*extlconv->thousands_sep)
3896 popt->
name =
"unicode";
3946 unsigned char *end =
str + strlen((
char *)
str);
3959 if (*target_width < curr_width + char_width && curr_width != 0)
3962 curr_width += char_width;
3970 *target_width = curr_width;
static void cleanup(void)
#define unconstify(underlying_type, expr)
#define ngettext(s, p, n)
#define fprintf(file, fmt, msg)
Oid PQftype(const PGresult *res, int field_num)
int PQmblen(const char *s, int encoding)
int PQdsplen(const char *s, int encoding)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
void * pg_malloc0(size_t size)
struct unicodeStyleBorderFormat unicodeStyleBorderFormat
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
static void asciidoc_escaped_print(const char *in, FILE *fout)
static void csv_print_field(const char *str, FILE *fout, char sep)
void printTableCleanup(printTableContent *const content)
void restore_sigpipe_trap(void)
static void print_asciidoc_text(const printTableContent *cont, FILE *fout)
static char default_footer[100]
static void print_aligned_vertical_line(const printTableOpt *topt, unsigned long record, unsigned int hwidth, unsigned int dwidth, int output_columns, printTextRule pos, FILE *fout)
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
static printTableFooter default_footer_cell
static void print_unaligned_vertical(const printTableContent *cont, FILE *fout)
static int additional_numeric_locale_len(const char *my_str)
const printTextFormat * get_line_style(const printTableOpt *opt)
static printTableFooter * footers_with_default(const printTableContent *cont)
#define LONGTABLE_WHITESPACE
FILE * PageOutput(int lines, const printTableOpt *topt)
void refresh_utf8format(const printTableOpt *opt)
static void print_latex_text(const printTableContent *cont, FILE *fout)
char column_type_alignment(Oid ftype)
struct unicodeStyleFormat unicodeStyleFormat
static void IsPagerNeeded(const printTableContent *cont, const unsigned int *width_wrap, bool vertical, FILE **fout, bool *is_pager)
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
static void print_troff_ms_text(const printTableContent *cont, FILE *fout)
static void print_separator(struct separator sep, FILE *fout)
const printTextFormat pg_asciiformat
void printTableSetFooter(printTableContent *const content, const char *footer)
static void latex_escaped_print(const char *in, FILE *fout)
static char * thousands_sep
static void print_html_text(const printTableContent *cont, FILE *fout)
static void print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
void ClosePager(FILE *pagerpipe)
static void print_csv_text(const printTableContent *cont, FILE *fout)
static void print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager)
static void print_csv_vertical(const printTableContent *cont, FILE *fout)
const printTextFormat pg_asciiformat_old
static FILE * PageOutputInternal(int lines, const printTableOpt *topt, const printTableContent *cont, const unsigned int *width_wrap, bool vertical)
static bool always_ignore_sigpipe
static void print_html_vertical(const printTableContent *cont, FILE *fout)
void disable_sigpipe_trap(void)
static void csv_escaped_print(const char *str, FILE *fout)
static char * format_numeric_locale(const char *my_str)
static char * decimal_point
static int strlen_max_width(unsigned char *str, int *target_width, int encoding)
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
struct unicodeStyleRowFormat unicodeStyleRowFormat
static int integer_digits(const char *my_str)
static void print_asciidoc_vertical(const printTableContent *cont, FILE *fout)
static void print_unaligned_text(const printTableContent *cont, FILE *fout)
static void print_latex_vertical(const printTableContent *cont, FILE *fout)
void html_escaped_print(const char *in, FILE *fout)
struct unicodeStyleColumnFormat unicodeStyleColumnFormat
void printTableAddFooter(printTableContent *const content, const char *footer)
static void troff_ms_escaped_print(const char *in, FILE *fout)
void set_sigpipe_trap_state(bool ignore)
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
static const unicodeStyleFormat unicode_style
printTextFormat pg_utf8format
static void print_latex_longtable_text(const printTableContent *cont, FILE *fout)
static void print_aligned_vertical(const printTableContent *cont, FILE *fout, bool is_pager)
static void _print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths, unsigned short border, printTextRule pos, const printTextFormat *format, FILE *fout)
volatile sig_atomic_t cancel_pressed
void setDecimalLocale(void)
@ PRINT_XHEADER_EXACT_WIDTH
@ PRINT_LINE_WRAP_NEWLINE
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
void pg_wcssize(const unsigned char *pwcs, size_t len, int encoding, int *result_width, int *result_height, int *result_format_size)
void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, struct lineptr *lines, int count)
unsigned char * mbvalidate(unsigned char *pwcs, int encoding)
Datum translate(PG_FUNCTION_ARGS)
const bool * translate_columns
const printTableOpt * opt
printTableFooter * footers
printTableFooter * footer
unsigned short int expanded
unsigned long prior_records
unicode_linestyle unicode_border_linestyle
struct separator fieldSep
int expanded_header_exact_width
struct separator recordSep
printXheaderWidthType expanded_header_width_type
const printTextFormat * line_style
unsigned short int border
unicode_linestyle unicode_header_linestyle
unicode_linestyle unicode_column_linestyle
const char * midvrule_blank
const char * header_nl_left
printTextLineFormat lrule[4]
const char * midvrule_wrap
const char * header_nl_right