25 #include <sys/ioctl.h>
32 #include "catalog/pg_type_d.h"
151 {
"\342\224\234",
"\342\225\237"},
158 {
"\342\224\244",
"\342\225\242"},
169 {
"\342\225\236",
"\342\225\240"},
176 {
"\342\225\241",
"\342\225\243"},
189 {
"\342\224\274",
"\342\225\252"},
196 {
"\342\224\264",
"\342\225\247"},
203 {
"\342\224\254",
"\342\225\244"},
214 {
"\342\225\253",
"\342\225\254"},
221 {
"\342\225\250",
"\342\225\251"},
228 {
"\342\225\245",
"\342\225\246"},
241 {
"\342\224\224",
"\342\224\202",
"\342\224\214",
"\342\224\200",
"\342\224\220",
"\342\224\230"},
252 {
"\342\225\232",
"\342\225\221",
"\342\225\224",
"\342\225\220",
"\342\225\227",
"\342\225\235"},
270 FILE **fout,
bool *is_pager);
273 FILE *fout,
bool is_pager);
281 if (my_str[0] ==
'-' || my_str[0] ==
'+')
284 return strspn(my_str,
"0123456789");
299 if (strchr(my_str,
'.') != NULL)
327 if (strspn(my_str,
"0123456789+-.eE") != strlen(my_str))
337 if (leading_digits == 0)
341 if (my_str[0] ==
'-' || my_str[0] ==
'+')
343 new_str[new_str_pos++] = my_str[0];
348 for (
i = 0;
i < int_len;
i++)
351 if (
i > 0 && --leading_digits == 0)
357 new_str[new_str_pos++] = my_str[
i];
361 if (my_str[
i] ==
'.')
369 strcpy(&new_str[new_str_pos], &my_str[
i]);
372 Assert(strlen(new_str) <= new_len);
402 unsigned long total_records;
406 ngettext(
"(%lu row)",
"(%lu rows)", total_records),
426 const char *
const *ptr;
427 bool need_recordsep =
false;
435 if (!opt_tuples_only && cont->
title)
437 fputs(cont->
title, fout);
442 if (!opt_tuples_only)
444 for (ptr = cont->
headers; *ptr; ptr++)
450 need_recordsep =
true;
455 need_recordsep =
true;
458 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
463 need_recordsep =
false;
472 need_recordsep =
true;
484 for (f = footers; f; f = f->
next)
489 need_recordsep =
false;
491 fputs(f->
data, fout);
492 need_recordsep =
true;
517 const char *
const *ptr;
518 bool need_recordsep =
false;
526 if (!opt_tuples_only && cont->
title)
528 fputs(cont->
title, fout);
529 need_recordsep =
true;
534 need_recordsep =
true;
537 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
544 need_recordsep =
false;
556 need_recordsep =
true;
570 fputs(f->
data, fout);
603 fputs(lformat->
hrule, fout);
604 else if (border == 2)
607 for (
i = 0;
i < ncolumns;
i++)
609 for (
j = 0;
j < widths[
i];
j++)
610 fputs(lformat->
hrule, fout);
612 if (
i < ncolumns - 1)
624 else if (border == 1)
625 fputs(lformat->
hrule, fout);
639 unsigned short opt_border = cont->
opt->
border;
643 unsigned int col_count = 0,
649 unsigned int *width_header,
653 unsigned int *max_nl_lines,
656 unsigned char **format_buf;
657 unsigned int width_total;
658 unsigned int total_header_width;
659 unsigned int extra_row_output_lines = 0;
660 unsigned int extra_output_lines = 0;
662 const char *
const *ptr;
669 int output_columns = 0;
670 bool is_local_pager =
false;
681 width_header =
pg_malloc0(col_count *
sizeof(*width_header));
682 width_average =
pg_malloc0(col_count *
sizeof(*width_average));
683 max_width =
pg_malloc0(col_count *
sizeof(*max_width));
684 width_wrap =
pg_malloc0(col_count *
sizeof(*width_wrap));
685 max_nl_lines =
pg_malloc0(col_count *
sizeof(*max_nl_lines));
686 curr_nl_line =
pg_malloc0(col_count *
sizeof(*curr_nl_line));
687 col_lineptrs =
pg_malloc0(col_count *
sizeof(*col_lineptrs));
688 max_bytes =
pg_malloc0(col_count *
sizeof(*max_bytes));
689 format_buf =
pg_malloc0(col_count *
sizeof(*format_buf));
690 header_done =
pg_malloc0(col_count *
sizeof(*header_done));
691 bytes_output =
pg_malloc0(col_count *
sizeof(*bytes_output));
697 width_average = NULL;
711 for (
i = 0;
i < col_count;
i++)
721 if (nl_lines > max_nl_lines[
i])
722 max_nl_lines[
i] = nl_lines;
723 if (bytes_required > max_bytes[
i])
724 max_bytes[
i] = bytes_required;
725 if (nl_lines > extra_row_output_lines)
726 extra_row_output_lines = nl_lines;
731 extra_output_lines += extra_row_output_lines;
732 extra_row_output_lines = 0;
742 &
width, &nl_lines, &bytes_required);
744 if (
width > max_width[
i % col_count])
745 max_width[
i % col_count] =
width;
746 if (nl_lines > max_nl_lines[
i % col_count])
747 max_nl_lines[
i % col_count] = nl_lines;
748 if (bytes_required > max_bytes[
i % col_count])
749 max_bytes[
i % col_count] = bytes_required;
751 width_average[
i % col_count] +=
width;
755 if (col_count != 0 && cell_count != 0)
757 int rows = cell_count / col_count;
759 for (
i = 0;
i < col_count;
i++)
760 width_average[
i] /= rows;
765 width_total = col_count;
766 else if (opt_border == 1)
767 width_total = col_count * 3 - ((col_count > 0) ? 1 : 0);
769 width_total = col_count * 3 + 1;
770 total_header_width = width_total;
772 for (
i = 0;
i < col_count;
i++)
774 width_total += max_width[
i];
775 total_header_width += width_header[
i];
785 for (
i = 0;
i < col_count;
i++)
789 sizeof(**col_lineptrs));
793 col_lineptrs[
i]->
ptr = format_buf[
i];
797 for (
i = 0;
i < col_count;
i++)
798 width_wrap[
i] = max_width[
i];
805 else if ((fout ==
stdout && isatty(fileno(
stdout))) || is_pager)
812 struct winsize screen_size;
814 if (ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size) != -1)
815 output_columns = screen_size.ws_col;
829 if (output_columns > 0 && output_columns >= total_header_width)
832 while (width_total > output_columns)
834 double max_ratio = 0;
843 for (
i = 0;
i < col_count;
i++)
845 if (width_average[
i] && width_wrap[
i] > width_header[
i])
850 ratio = (double) width_wrap[
i] / width_average[
i] +
852 if (ratio > max_ratio)
865 width_wrap[worst_col]--;
878 (output_columns < total_header_width || output_columns < width_total))
885 if (!is_pager && fout ==
stdout && output_columns > 0 &&
886 (output_columns < total_header_width || output_columns < width_total))
889 is_pager = is_local_pager =
true;
893 if (!is_pager && fout ==
stdout)
896 for (
i = 0, ptr = cont->
cells; *ptr; ptr++, cell_count++)
903 &width, &nl_lines, &bytes_required);
909 if (width > 0 && width_wrap[
i])
911 unsigned int extra_lines;
914 extra_lines = ((width - 1) / width_wrap[
i]) + nl_lines - 1;
915 if (extra_lines > extra_row_output_lines)
916 extra_row_output_lines = extra_lines;
920 if (++
i >= col_count)
924 extra_output_lines += extra_row_output_lines;
925 extra_row_output_lines = 0;
928 IsPagerNeeded(cont, extra_output_lines,
false, &fout, &is_pager);
929 is_local_pager = is_pager;
936 if (cont->
title && !opt_tuples_only)
943 if (width >= width_total)
948 fprintf(fout,
"%-*s%s\n", (width_total - width) / 2,
"",
953 if (!opt_tuples_only)
955 int more_col_wrapping;
962 for (
i = 0;
i < col_count;
i++)
965 col_lineptrs[
i], max_nl_lines[
i]);
967 more_col_wrapping = col_count;
970 memset(header_done,
false, col_count *
sizeof(
bool));
971 while (more_col_wrapping)
978 struct lineptr *this_line = col_lineptrs[
i] + curr_nl_line;
979 unsigned int nbspace;
981 if (opt_border != 0 ||
982 (!
format->wrap_right_border &&
i > 0))
983 fputs(curr_nl_line ?
format->header_nl_left :
" ",
988 nbspace = width_wrap[
i] - this_line->
width;
992 nbspace / 2,
"", this_line->
ptr, (nbspace + 1) / 2,
"");
994 if (!(this_line + 1)->
ptr)
1001 fprintf(fout,
"%*s", width_wrap[
i],
"");
1003 if (opt_border != 0 ||
format->wrap_right_border)
1004 fputs(!header_done[
i] ?
format->header_nl_right :
" ",
1007 if (opt_border != 0 && col_count > 0 &&
i < col_count - 1)
1012 if (opt_border == 2)
1033 for (
j = 0;
j < col_count;
j++)
1036 col_lineptrs[
j], max_nl_lines[
j]);
1037 curr_nl_line[
j] = 0;
1040 memset(bytes_output, 0, col_count *
sizeof(
int));
1052 if (opt_border == 2)
1056 for (
j = 0;
j < col_count;
j++)
1059 struct lineptr *this_line = &col_lineptrs[
j][curr_nl_line[
j]];
1060 int bytes_to_output;
1061 int chars_to_output = width_wrap[
j];
1062 bool finalspaces = (opt_border == 2 ||
1063 (col_count > 0 &&
j < col_count - 1));
1066 if (opt_border != 0)
1069 fputs(
format->wrap_left, fout);
1071 fputs(
format->nl_left, fout);
1076 if (!this_line->
ptr)
1080 fprintf(fout,
"%*s", chars_to_output,
"");
1095 if (chars_to_output > width_wrap[
j])
1096 chars_to_output = width_wrap[
j];
1101 fprintf(fout,
"%*s", width_wrap[
j] - chars_to_output,
"");
1102 fwrite((
char *) (this_line->
ptr + bytes_output[
j]),
1103 1, bytes_to_output, fout);
1108 fwrite((
char *) (this_line->
ptr + bytes_output[
j]),
1109 1, bytes_to_output, fout);
1112 bytes_output[
j] += bytes_to_output;
1115 if (*(this_line->
ptr + bytes_output[
j]) !=
'\0')
1121 if (col_lineptrs[
j][curr_nl_line[
j]].
ptr != NULL)
1123 bytes_output[
j] = 0;
1129 if (col_lineptrs[
j][curr_nl_line[
j]].
ptr != NULL)
1131 if (bytes_output[
j] != 0)
1133 else if (curr_nl_line[
j] != 0)
1147 width_wrap[
j] - chars_to_output,
"");
1152 fputs(
format->wrap_right, fout);
1154 fputs(
format->nl_right, fout);
1155 else if (opt_border == 2 || (col_count > 0 &&
j < col_count - 1))
1159 if (opt_border != 0 && (col_count > 0 &&
j < col_count - 1))
1162 fputs(
format->midvrule_wrap, fout);
1164 fputs(
format->midvrule_nl, fout);
1165 else if (col_lineptrs[
j + 1][curr_nl_line[
j + 1]].
ptr == NULL)
1166 fputs(
format->midvrule_blank, fout);
1173 if (opt_border == 2)
1176 }
while (more_lines);
1192 for (f = footers; f; f = f->
next)
1201 for (
i = 0;
i < col_count;
i++)
1203 free(col_lineptrs[
i]);
1204 free(format_buf[
i]);
1207 free(width_average);
1226 unsigned long record,
1227 unsigned int hwidth,
1228 unsigned int dwidth,
1234 const unsigned short opt_border = topt->
border;
1238 if (opt_border == 2)
1240 else if (opt_border == 1)
1241 fputs(lformat->
hrule, fout);
1245 if (opt_border == 0)
1246 reclen =
fprintf(fout,
"* Record %lu", record);
1248 reclen =
fprintf(fout,
"[ RECORD %lu ]", record);
1250 if (opt_border != 2)
1254 for (
i = reclen;
i < hwidth;
i++)
1255 fputs(opt_border > 0 ? lformat->
hrule :
" ", fout);
1261 fputs(lformat->
hrule, fout);
1275 fputs(lformat->
hrule, fout);
1292 if (output_columns > 0)
1294 if (opt_border == 0)
1295 dwidth =
Min(dwidth,
Max(0, (
int) (output_columns - hwidth)));
1296 if (opt_border == 1)
1297 dwidth =
Min(dwidth,
Max(0, (
int) (output_columns - hwidth - 3)));
1304 if (opt_border == 2)
1305 dwidth =
Min(dwidth,
Max(0, (
int) (output_columns - hwidth - 7)));
1311 if (dwidth < reclen)
1314 for (
i = reclen;
i < dwidth;
i++)
1315 fputs(opt_border > 0 ? lformat->
hrule :
" ", fout);
1316 if (opt_border == 2)
1325 FILE *fout,
bool is_pager)
1328 unsigned short opt_border = cont->
opt->
border;
1333 const char *
const *
ptr;
1343 bool is_local_pager =
false,
1346 int output_columns = 0;
1363 for (f = footers; f; f = f->
next)
1380 is_local_pager = is_pager;
1394 if (height > hheight)
1399 if (fs > hformatsize)
1411 &
width, &height, &fs);
1414 if (height > dheight)
1419 if (fs > dformatsize)
1427 dlineptr =
pg_malloc((
sizeof(*dlineptr)) * (dheight + 1));
1428 hlineptr =
pg_malloc((
sizeof(*hlineptr)) * (hheight + 1));
1436 if (!opt_tuples_only && cont->
title)
1445 else if ((fout ==
stdout && isatty(fileno(
stdout))) || is_pager)
1452 struct winsize screen_size;
1454 if (ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size) != -1)
1455 output_columns = screen_size.ws_col;
1465 unsigned int swidth,
1469 if (opt_border == 0)
1483 else if (opt_border == 1)
1512 if (!opt_tuples_only)
1514 if (cont->
nrows > 0)
1515 rwidth = 1 + (int) log10(cont->
nrows);
1516 if (opt_border == 0)
1518 else if (opt_border == 1)
1530 width = hwidth + swidth + dwidth;
1535 if (output_columns > 0)
1537 unsigned int min_width;
1540 min_width = hwidth + swidth + 3;
1542 if (min_width < rwidth)
1545 if (output_columns >= width)
1549 newdwidth = width - hwidth - swidth;
1551 else if (output_columns < min_width)
1554 newdwidth = min_width - hwidth - swidth;
1559 newdwidth = output_columns - hwidth - swidth;
1566 newdwidth = width - hwidth - swidth;
1573 if (newdwidth < dwidth && !dmultiline &&
1587 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
1608 unsigned int lhwidth = hwidth;
1610 if ((opt_border < 2) &&
1615 if (!opt_tuples_only)
1617 lhwidth, dwidth, output_columns,
1621 dwidth, output_columns, pos, fout);
1637 dcomplete = hcomplete = 0;
1639 chars_to_output = dlineptr[dline].
width;
1640 while (!dcomplete || !hcomplete)
1643 if (opt_border == 2)
1649 int swidth = hwidth,
1650 target_width = hwidth;
1655 if ((opt_border == 2) ||
1657 fputs(hline ?
format->header_nl_left :
" ", fout);
1664 fprintf(fout,
"%-s", hlineptr[hline].ptr);
1669 swidth -= target_width;
1671 fprintf(fout,
"%*s", swidth,
" ");
1676 if (hlineptr[hline + 1].ptr)
1679 if ((opt_border > 0) ||
1681 fputs(
format->header_nl_right, fout);
1687 if ((opt_border > 0) ||
1695 unsigned int swidth = hwidth + opt_border;
1697 if ((opt_border < 2) &&
1702 if ((opt_border == 0) &&
1707 fprintf(fout,
"%*s", swidth,
" ");
1714 fputs(
format->midvrule_wrap, fout);
1715 else if (dline == 0)
1718 fputs(
format->midvrule_nl, fout);
1724 int target_width = dwidth,
1731 fputs(offset == 0 ?
" " :
format->wrap_left, fout);
1738 fwrite((
char *) (dlineptr[dline].ptr + offset),
1739 1, bytes_to_output, fout);
1741 chars_to_output -= target_width;
1742 offset += bytes_to_output;
1745 swidth -= target_width;
1747 if (chars_to_output)
1750 if ((opt_border > 1) ||
1754 fprintf(fout,
"%*s", swidth,
" ");
1755 fputs(
format->wrap_right, fout);
1758 else if (dlineptr[dline + 1].ptr)
1761 if ((opt_border > 1) ||
1765 fprintf(fout,
"%*s", swidth,
" ");
1766 fputs(
format->nl_right, fout);
1770 chars_to_output = dlineptr[dline].
width;
1778 fprintf(fout,
"%*s", swidth,
" ");
1785 if (opt_border == 2)
1845 for (p =
str; *p; p++)
1870 if (strchr(
str, sep) != NULL ||
1871 strcspn(
str,
"\r\n\"") != strlen(
str) ||
1872 strcmp(
str,
"\\.") == 0 ||
1873 sep ==
'\\' || sep ==
'.')
1882 const char *
const *ptr;
1899 for (ptr = cont->
headers; *ptr; ptr++)
1909 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
1922 const char *
const *ptr;
1926 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
1955 bool leading_space =
true;
1957 for (p = in; *p; p++)
1962 fputs(
"&", fout);
1965 fputs(
"<", fout);
1968 fputs(
">", fout);
1971 fputs(
"<br />\n", fout);
1974 fputs(
""", fout);
1979 fputs(
" ", fout);
1987 leading_space =
false;
1996 unsigned short opt_border = cont->
opt->
border;
1999 const char *
const *ptr;
2006 fprintf(fout,
"<table border=\"%d\"", opt_border);
2008 fprintf(fout,
" %s", opt_table_attr);
2012 if (!opt_tuples_only && cont->
title)
2014 fputs(
" <caption>", fout);
2016 fputs(
"</caption>\n", fout);
2020 if (!opt_tuples_only)
2022 fputs(
" <tr>\n", fout);
2023 for (ptr = cont->
headers; *ptr; ptr++)
2025 fputs(
" <th align=\"center\">", fout);
2027 fputs(
"</th>\n", fout);
2029 fputs(
" </tr>\n", fout);
2034 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2040 fputs(
" <tr valign=\"top\">\n", fout);
2045 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2046 fputs(
" ", fout);
2050 fputs(
"</td>\n", fout);
2053 fputs(
" </tr>\n", fout);
2060 fputs(
"</table>\n", fout);
2068 for (f = footers; f; f = f->
next)
2071 fputs(
"<br />\n", fout);
2073 fputs(
"</p>", fout);
2085 unsigned short opt_border = cont->
opt->
border;
2089 const char *
const *ptr;
2096 fprintf(fout,
"<table border=\"%d\"", opt_border);
2098 fprintf(fout,
" %s", opt_table_attr);
2102 if (!opt_tuples_only && cont->
title)
2104 fputs(
" <caption>", fout);
2106 fputs(
"</caption>\n", fout);
2111 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2117 if (!opt_tuples_only)
2119 "\n <tr><td colspan=\"2\" align=\"center\">Record %lu</td></tr>\n",
2122 fputs(
"\n <tr><td colspan=\"2\"> </td></tr>\n", fout);
2124 fputs(
" <tr valign=\"top\">\n"
2127 fputs(
"</th>\n", fout);
2131 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2132 fputs(
" ", fout);
2136 fputs(
"</td>\n </tr>\n", fout);
2141 fputs(
"</table>\n", fout);
2152 fputs(
"<br />\n", fout);
2154 fputs(
"</p>", fout);
2172 for (p = in; *p; p++)
2189 unsigned short opt_border = cont->
opt->
border;
2191 const char *
const *ptr;
2202 if (!opt_tuples_only && cont->
title)
2205 fputs(cont->
title, fout);
2210 fprintf(fout,
"[%scols=\"", !opt_tuples_only ?
"options=\"header\"," :
"");
2221 fputs(
",frame=\"none\",grid=\"none\"", fout);
2224 fputs(
",frame=\"none\"", fout);
2227 fputs(
",frame=\"all\",grid=\"all\"", fout);
2231 fputs(
"|====\n", fout);
2234 if (!opt_tuples_only)
2236 for (ptr = cont->
headers; *ptr; ptr++)
2248 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2261 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2273 fputs(
"|====\n", fout);
2284 fputs(
"\n....\n", fout);
2285 for (f = footers; f; f = f->
next)
2287 fputs(f->
data, fout);
2290 fputs(
"....\n", fout);
2299 unsigned short opt_border = cont->
opt->
border;
2302 const char *
const *ptr;
2313 if (!opt_tuples_only && cont->
title)
2316 fputs(cont->
title, fout);
2321 fputs(
"[cols=\"h,l\"", fout);
2325 fputs(
",frame=\"none\",grid=\"none\"", fout);
2328 fputs(
",frame=\"none\"", fout);
2331 fputs(
",frame=\"all\",grid=\"all\"", fout);
2335 fputs(
"|====\n", fout);
2339 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2345 if (!opt_tuples_only)
2350 fputs(
"2+|\n", fout);
2358 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2365 fputs(
"|====\n", fout);
2374 fputs(
"\n....\n", fout);
2377 fputs(f->
data, fout);
2380 fputs(
"....\n", fout);
2396 for (p = in; *p; p++)
2417 fputs(
"\\textless{}", fout);
2420 fputs(
"\\textgreater{}", fout);
2423 fputs(
"\\textbackslash{}", fout);
2426 fputs(
"\\^{}", fout);
2435 fputs(
"\\textbar{}", fout);
2441 fputs(
"\\~{}", fout);
2445 fputs(
"\\\\", fout);
2457 unsigned short opt_border = cont->
opt->
border;
2459 const char *
const *ptr;
2470 if (!opt_tuples_only && cont->
title)
2472 fputs(
"\\begin{center}\n", fout);
2474 fputs(
"\n\\end{center}\n\n", fout);
2478 fputs(
"\\begin{tabular}{", fout);
2480 if (opt_border >= 2)
2484 fputc(*(cont->
aligns +
i), fout);
2485 if (opt_border != 0 && i < cont->ncolumns - 1)
2488 if (opt_border >= 2)
2493 if (!opt_tuples_only && opt_border >= 2)
2494 fputs(
"\\hline\n", fout);
2497 if (!opt_tuples_only)
2499 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2503 fputs(
"\\textit{", fout);
2507 fputs(
" \\\\\n", fout);
2508 fputs(
"\\hline\n", fout);
2513 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2519 fputs(
" \\\\\n", fout);
2520 if (opt_border == 3)
2521 fputs(
"\\hline\n", fout);
2533 if (opt_border == 2)
2534 fputs(
"\\hline\n", fout);
2536 fputs(
"\\end{tabular}\n\n\\noindent ", fout);
2543 for (f = footers; f; f = f->
next)
2546 fputs(
" \\\\\n", fout);
2564 unsigned short opt_border = cont->
opt->
border;
2567 const char *next_opt_table_attr_char = opt_table_attr;
2568 const char *last_opt_table_attr_char = NULL;
2569 const char *
const *ptr;
2580 fputs(
"\\begin{longtable}{", fout);
2582 if (opt_border >= 2)
2589 if (*(cont->
aligns +
i) ==
'l' && opt_table_attr)
2591 #define LONGTABLE_WHITESPACE " \t\n"
2594 next_opt_table_attr_char += strspn(next_opt_table_attr_char,
2597 if (next_opt_table_attr_char[0] !=
'\0')
2600 fwrite(next_opt_table_attr_char, strcspn(next_opt_table_attr_char,
2602 last_opt_table_attr_char = next_opt_table_attr_char;
2603 next_opt_table_attr_char += strcspn(next_opt_table_attr_char,
2605 fputs(
"\\textwidth}", fout);
2608 else if (last_opt_table_attr_char != NULL)
2611 fwrite(last_opt_table_attr_char, strcspn(last_opt_table_attr_char,
2613 fputs(
"\\textwidth}", fout);
2619 fputc(*(cont->
aligns +
i), fout);
2621 if (opt_border != 0 && i < cont->ncolumns - 1)
2625 if (opt_border >= 2)
2631 if (!opt_tuples_only)
2634 if (opt_border >= 2)
2635 fputs(
"\\toprule\n", fout);
2636 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2640 fputs(
"\\small\\textbf{\\textit{", fout);
2644 fputs(
" \\\\\n", fout);
2645 fputs(
"\\midrule\n\\endfirsthead\n", fout);
2648 if (opt_border >= 2)
2649 fputs(
"\\toprule\n", fout);
2650 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2654 fputs(
"\\small\\textbf{\\textit{", fout);
2658 fputs(
" \\\\\n", fout);
2660 if (opt_border != 3)
2661 fputs(
"\\midrule\n", fout);
2662 fputs(
"\\endhead\n", fout);
2665 if (!opt_tuples_only && cont->
title)
2668 if (opt_border == 2)
2669 fputs(
"\\bottomrule\n", fout);
2670 fputs(
"\\caption[", fout);
2672 fputs(
" (Continued)]{", fout);
2674 fputs(
"}\n\\endfoot\n", fout);
2675 if (opt_border == 2)
2676 fputs(
"\\bottomrule\n", fout);
2677 fputs(
"\\caption[", fout);
2681 fputs(
"}\n\\endlastfoot\n", fout);
2684 else if (opt_border >= 2)
2686 fputs(
"\\bottomrule\n\\endfoot\n", fout);
2687 fputs(
"\\bottomrule\n\\endlastfoot\n", fout);
2693 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2697 fputs(
"\n&\n", fout);
2698 fputs(
"\\raggedright{", fout);
2703 fputs(
" \\tabularnewline\n", fout);
2704 if (opt_border == 3)
2705 fputs(
" \\hline\n", fout);
2712 fputs(
"\\end{longtable}\n", fout);
2720 unsigned short opt_border = cont->
opt->
border;
2723 const char *
const *ptr;
2734 if (!opt_tuples_only && cont->
title)
2736 fputs(
"\\begin{center}\n", fout);
2738 fputs(
"\n\\end{center}\n\n", fout);
2742 fputs(
"\\begin{tabular}{", fout);
2743 if (opt_border == 0)
2745 else if (opt_border == 1)
2747 else if (opt_border == 2)
2748 fputs(
"|c|l|", fout);
2753 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2760 if (!opt_tuples_only)
2762 if (opt_border == 2)
2764 fputs(
"\\hline\n", fout);
2765 fprintf(fout,
"\\multicolumn{2}{|c|}{\\textit{Record %lu}} \\\\\n", record++);
2768 fprintf(fout,
"\\multicolumn{2}{c}{\\textit{Record %lu}} \\\\\n", record++);
2770 if (opt_border >= 1)
2771 fputs(
"\\hline\n", fout);
2777 fputs(
" \\\\\n", fout);
2782 if (opt_border == 2)
2783 fputs(
"\\hline\n", fout);
2785 fputs(
"\\end{tabular}\n\n\\noindent ", fout);
2795 fputs(
" \\\\\n", fout);
2814 for (p = in; *p; p++)
2818 fputs(
"\\(rs", fout);
2830 unsigned short opt_border = cont->
opt->
border;
2832 const char *
const *ptr;
2843 if (!opt_tuples_only && cont->
title)
2845 fputs(
".LP\n.DS C\n", fout);
2847 fputs(
"\n.DE\n", fout);
2851 fputs(
".LP\n.TS\n", fout);
2852 if (opt_border == 2)
2853 fputs(
"center box;\n", fout);
2855 fputs(
"center;\n", fout);
2859 fputc(*(cont->
aligns +
i), fout);
2860 if (opt_border > 0 && i < cont->ncolumns - 1)
2866 if (!opt_tuples_only)
2868 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2872 fputs(
"\\fI", fout);
2874 fputs(
"\\fP", fout);
2876 fputs(
"\n_\n", fout);
2881 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2899 fputs(
".TE\n.DS L\n", fout);
2906 for (f = footers; f; f = f->
next)
2913 fputs(
".DE\n", fout);
2922 unsigned short opt_border = cont->
opt->
border;
2925 const char *
const *ptr;
2926 unsigned short current_format = 0;
2937 if (!opt_tuples_only && cont->
title)
2939 fputs(
".LP\n.DS C\n", fout);
2941 fputs(
"\n.DE\n", fout);
2945 fputs(
".LP\n.TS\n", fout);
2946 if (opt_border == 2)
2947 fputs(
"center box;\n", fout);
2949 fputs(
"center;\n", fout);
2952 if (opt_tuples_only)
2953 fputs(
"c l;\n", fout);
2959 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2966 if (!opt_tuples_only)
2968 if (current_format != 1)
2970 if (opt_border == 2 && record > 1)
2972 if (current_format != 0)
2973 fputs(
".T&\n", fout);
2974 fputs(
"c s.\n", fout);
2977 fprintf(fout,
"\\fIRecord %lu\\fP\n", record++);
2979 if (opt_border >= 1)
2983 if (!opt_tuples_only)
2985 if (current_format != 2)
2987 if (current_format != 0)
2988 fputs(
".T&\n", fout);
2989 if (opt_border != 1)
2990 fputs(
"c l.\n", fout);
2992 fputs(
"c | l.\n", fout);
3006 fputs(
".TE\n.DS L\n", fout);
3020 fputs(
".DE\n", fout);
3092 if (topt && topt->
pager && isatty(fileno(stdin)) && isatty(fileno(
stdout)))
3095 unsigned short int pager = topt->
pager;
3098 struct winsize screen_size;
3100 result = ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size);
3104 || (lines >= screen_size.ws_row && lines >= min_lines)
3108 const char *pagerprog;
3111 pagerprog = getenv(
"PSQL_PAGER");
3113 pagerprog = getenv(
"PAGER");
3119 if (strspn(pagerprog,
" \t\r\n") == strlen(pagerprog))
3124 pagerpipe = popen(pagerprog,
"w");
3143 if (pagerpipe && pagerpipe !=
stdout)
3154 fprintf(pagerpipe,
_(
"Interrupted\n"));
3173 const char *title,
const int ncolumns,
const int nrows)
3178 content->
title = title;
3180 content->
nrows = nrows;
3184 total_cells = (
uint64) ncolumns * nrows;
3186 if (total_cells >= SIZE_MAX /
sizeof(*content->
cells))
3188 fprintf(stderr,
_(
"Cannot print table contents: number of cells %lld is equal to or exceeds maximum %lld.\n"),
3189 (
long long int) total_cells,
3190 (
long long int) (SIZE_MAX /
sizeof(*content->
cells)));
3229 fprintf(stderr,
_(
"Cannot add header to table content: "
3230 "column count of %d exceeded.\n"),
3243 *content->
align = align;
3261 const bool translate,
const bool mustfree)
3272 fprintf(stderr,
_(
"Cannot add cell to table content: total cell count of %lld exceeded.\n"),
3273 (
long long int) total_cells);
3289 pg_malloc0((total_cells + 1) *
sizeof(
bool));
3372 content->
opt = NULL;
3373 content->
title = NULL;
3375 content->
cells = NULL;
3378 content->
cell = NULL;
3379 content->
align = NULL;
3404 FILE **fout,
bool *is_pager)
3413 lines = cont->
nrows + 1;
3428 *is_pager = (*fout !=
stdout);
3444 FILE *fout,
bool is_pager, FILE *flog)
3446 bool is_local_pager =
false;
3460 is_local_pager = is_pager;
3530 fprintf(stderr,
_(
"invalid output format (internal error): %d"),
3550 FILE *fout,
bool is_pager, FILE *flog)
3575 for (r = 0; r < cont.
nrows; r++)
3580 bool mustfree =
false;
3605 for (footer = opt->
footers; *footer; footer++)
3643 struct lconv *extlconv;
3645 extlconv = localeconv();
3648 if (*extlconv->decimal_point)
3661 if (groupdigits <= 0 || groupdigits > 6)
3666 if (*extlconv->thousands_sep)
3699 popt->
name =
"unicode";
3749 unsigned char *end =
str + strlen((
char *)
str);
3762 if (*target_width < curr_width + char_width && curr_width != 0)
3765 curr_width += char_width;
3773 *target_width = curr_width;
static void cleanup(void)
#define unconstify(underlying_type, expr)
#define ngettext(s, p, n)
#define Assert(condition)
Oid PQftype(const PGresult *res, int field_num)
int PQntuples(const PGresult *res)
char * PQfname(const PGresult *res, int field_num)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
int PQnfields(const PGresult *res)
int PQmblen(const char *s, int encoding)
int PQdsplen(const char *s, int encoding)
void * pg_malloc0(size_t size)
char * pg_strdup(const char *in)
void * pg_malloc(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)
#define LONGTABLE_WHITESPACE
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
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 bool always_ignore_sigpipe
static void print_html_vertical(const printTableContent *cont, FILE *fout)
void disable_sigpipe_trap(void)
FILE * PageOutput(int lines, const printTableOpt *topt)
static void csv_escaped_print(const char *str, FILE *fout)
static char * decimal_point
const printTextFormat * get_line_style(const printTableOpt *opt)
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)
static void IsPagerNeeded(const printTableContent *cont, int extra_lines, bool expanded, FILE **fout, bool *is_pager)
struct unicodeStyleColumnFormat unicodeStyleColumnFormat
void printTableAddFooter(printTableContent *const content, const char *footer)
static void troff_ms_escaped_print(const char *in, FILE *fout)
static printTableFooter * footers_with_default(const printTableContent *cont)
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
static char * format_numeric_locale(const char *my_str)
void setDecimalLocale(void)
@ PRINT_XHEADER_EXACT_WIDTH
@ PRINT_LINE_WRAP_NEWLINE
if(TABLE==NULL||TABLE_index==NULL)
static void const char fflush(stdout)
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)
pqsigfunc pqsignal(int signo, pqsigfunc func)
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