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)));
1303 if (opt_border == 2)
1304 dwidth =
Min(dwidth,
Max(0, (
int) (output_columns - hwidth - 7)));
1310 if (dwidth < reclen)
1313 for (
i = reclen;
i < dwidth;
i++)
1314 fputs(opt_border > 0 ? lformat->
hrule :
" ", fout);
1315 if (opt_border == 2)
1324 FILE *fout,
bool is_pager)
1327 unsigned short opt_border = cont->
opt->
border;
1332 const char *
const *
ptr;
1342 bool is_local_pager =
false,
1345 int output_columns = 0;
1362 for (f = footers; f; f = f->
next)
1379 is_local_pager = is_pager;
1393 if (height > hheight)
1398 if (fs > hformatsize)
1410 &
width, &height, &fs);
1413 if (height > dheight)
1418 if (fs > dformatsize)
1426 dlineptr =
pg_malloc((
sizeof(*dlineptr)) * (dheight + 1));
1427 hlineptr =
pg_malloc((
sizeof(*hlineptr)) * (hheight + 1));
1435 if (!opt_tuples_only && cont->
title)
1444 else if ((fout ==
stdout && isatty(fileno(
stdout))) || is_pager)
1451 struct winsize screen_size;
1453 if (ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size) != -1)
1454 output_columns = screen_size.ws_col;
1464 unsigned int swidth,
1468 if (opt_border == 0)
1482 else if (opt_border == 1)
1511 if (!opt_tuples_only)
1513 if (cont->
nrows > 0)
1514 rwidth = 1 + (int) log10(cont->
nrows);
1515 if (opt_border == 0)
1517 else if (opt_border == 1)
1529 width = hwidth + swidth + dwidth;
1534 if (output_columns > 0)
1536 unsigned int min_width;
1539 min_width = hwidth + swidth + 3;
1541 if (min_width < rwidth)
1544 if (output_columns >= width)
1548 newdwidth = width - hwidth - swidth;
1550 else if (output_columns < min_width)
1553 newdwidth = min_width - hwidth - swidth;
1558 newdwidth = output_columns - hwidth - swidth;
1565 newdwidth = width - hwidth - swidth;
1572 if (newdwidth < dwidth && !dmultiline &&
1586 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
1607 unsigned int lhwidth = hwidth;
1609 if ((opt_border < 2) &&
1614 if (!opt_tuples_only)
1616 lhwidth, dwidth, output_columns,
1620 dwidth, output_columns, pos, fout);
1636 dcomplete = hcomplete = 0;
1638 chars_to_output = dlineptr[dline].
width;
1639 while (!dcomplete || !hcomplete)
1642 if (opt_border == 2)
1648 int swidth = hwidth,
1649 target_width = hwidth;
1654 if ((opt_border == 2) ||
1656 fputs(hline ?
format->header_nl_left :
" ", fout);
1663 fprintf(fout,
"%-s", hlineptr[hline].ptr);
1668 swidth -= target_width;
1670 fprintf(fout,
"%*s", swidth,
" ");
1675 if (hlineptr[hline + 1].ptr)
1678 if ((opt_border > 0) ||
1680 fputs(
format->header_nl_right, fout);
1686 if ((opt_border > 0) ||
1694 unsigned int swidth = hwidth + opt_border;
1696 if ((opt_border < 2) &&
1701 if ((opt_border == 0) &&
1706 fprintf(fout,
"%*s", swidth,
" ");
1713 fputs(
format->midvrule_wrap, fout);
1714 else if (dline == 0)
1717 fputs(
format->midvrule_nl, fout);
1723 int target_width = dwidth,
1730 fputs(offset == 0 ?
" " :
format->wrap_left, fout);
1737 fwrite((
char *) (dlineptr[dline].ptr + offset),
1738 1, bytes_to_output, fout);
1740 chars_to_output -= target_width;
1741 offset += bytes_to_output;
1744 swidth -= target_width;
1746 if (chars_to_output)
1749 if ((opt_border > 1) ||
1753 fprintf(fout,
"%*s", swidth,
" ");
1754 fputs(
format->wrap_right, fout);
1757 else if (dlineptr[dline + 1].ptr)
1760 if ((opt_border > 1) ||
1764 fprintf(fout,
"%*s", swidth,
" ");
1765 fputs(
format->nl_right, fout);
1769 chars_to_output = dlineptr[dline].
width;
1777 fprintf(fout,
"%*s", swidth,
" ");
1784 if (opt_border == 2)
1844 for (p =
str; *p; p++)
1869 if (strchr(
str, sep) != NULL ||
1870 strcspn(
str,
"\r\n\"") != strlen(
str) ||
1871 strcmp(
str,
"\\.") == 0 ||
1872 sep ==
'\\' || sep ==
'.')
1881 const char *
const *ptr;
1898 for (ptr = cont->
headers; *ptr; ptr++)
1908 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
1921 const char *
const *ptr;
1925 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
1954 bool leading_space =
true;
1956 for (p = in; *p; p++)
1961 fputs(
"&", fout);
1964 fputs(
"<", fout);
1967 fputs(
">", fout);
1970 fputs(
"<br />\n", fout);
1973 fputs(
""", fout);
1978 fputs(
" ", fout);
1986 leading_space =
false;
1995 unsigned short opt_border = cont->
opt->
border;
1998 const char *
const *ptr;
2005 fprintf(fout,
"<table border=\"%d\"", opt_border);
2007 fprintf(fout,
" %s", opt_table_attr);
2011 if (!opt_tuples_only && cont->
title)
2013 fputs(
" <caption>", fout);
2015 fputs(
"</caption>\n", fout);
2019 if (!opt_tuples_only)
2021 fputs(
" <tr>\n", fout);
2022 for (ptr = cont->
headers; *ptr; ptr++)
2024 fputs(
" <th align=\"center\">", fout);
2026 fputs(
"</th>\n", fout);
2028 fputs(
" </tr>\n", fout);
2033 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2039 fputs(
" <tr valign=\"top\">\n", fout);
2044 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2045 fputs(
" ", fout);
2049 fputs(
"</td>\n", fout);
2052 fputs(
" </tr>\n", fout);
2059 fputs(
"</table>\n", fout);
2067 for (f = footers; f; f = f->
next)
2070 fputs(
"<br />\n", fout);
2072 fputs(
"</p>", fout);
2084 unsigned short opt_border = cont->
opt->
border;
2088 const char *
const *ptr;
2095 fprintf(fout,
"<table border=\"%d\"", opt_border);
2097 fprintf(fout,
" %s", opt_table_attr);
2101 if (!opt_tuples_only && cont->
title)
2103 fputs(
" <caption>", fout);
2105 fputs(
"</caption>\n", fout);
2110 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2116 if (!opt_tuples_only)
2118 "\n <tr><td colspan=\"2\" align=\"center\">Record %lu</td></tr>\n",
2121 fputs(
"\n <tr><td colspan=\"2\"> </td></tr>\n", fout);
2123 fputs(
" <tr valign=\"top\">\n"
2126 fputs(
"</th>\n", fout);
2130 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2131 fputs(
" ", fout);
2135 fputs(
"</td>\n </tr>\n", fout);
2140 fputs(
"</table>\n", fout);
2151 fputs(
"<br />\n", fout);
2153 fputs(
"</p>", fout);
2171 for (p = in; *p; p++)
2188 unsigned short opt_border = cont->
opt->
border;
2190 const char *
const *ptr;
2201 if (!opt_tuples_only && cont->
title)
2204 fputs(cont->
title, fout);
2209 fprintf(fout,
"[%scols=\"", !opt_tuples_only ?
"options=\"header\"," :
"");
2220 fputs(
",frame=\"none\",grid=\"none\"", fout);
2223 fputs(
",frame=\"none\"", fout);
2226 fputs(
",frame=\"all\",grid=\"all\"", fout);
2230 fputs(
"|====\n", fout);
2233 if (!opt_tuples_only)
2235 for (ptr = cont->
headers; *ptr; ptr++)
2247 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2260 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2272 fputs(
"|====\n", fout);
2283 fputs(
"\n....\n", fout);
2284 for (f = footers; f; f = f->
next)
2286 fputs(f->
data, fout);
2289 fputs(
"....\n", fout);
2298 unsigned short opt_border = cont->
opt->
border;
2301 const char *
const *ptr;
2312 if (!opt_tuples_only && cont->
title)
2315 fputs(cont->
title, fout);
2320 fputs(
"[cols=\"h,l\"", fout);
2324 fputs(
",frame=\"none\",grid=\"none\"", fout);
2327 fputs(
",frame=\"none\"", fout);
2330 fputs(
",frame=\"all\",grid=\"all\"", fout);
2334 fputs(
"|====\n", fout);
2338 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2344 if (!opt_tuples_only)
2349 fputs(
"2+|\n", fout);
2357 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2364 fputs(
"|====\n", fout);
2373 fputs(
"\n....\n", fout);
2376 fputs(f->
data, fout);
2379 fputs(
"....\n", fout);
2395 for (p = in; *p; p++)
2416 fputs(
"\\textless{}", fout);
2419 fputs(
"\\textgreater{}", fout);
2422 fputs(
"\\textbackslash{}", fout);
2425 fputs(
"\\^{}", fout);
2434 fputs(
"\\textbar{}", fout);
2440 fputs(
"\\~{}", fout);
2444 fputs(
"\\\\", fout);
2456 unsigned short opt_border = cont->
opt->
border;
2458 const char *
const *ptr;
2469 if (!opt_tuples_only && cont->
title)
2471 fputs(
"\\begin{center}\n", fout);
2473 fputs(
"\n\\end{center}\n\n", fout);
2477 fputs(
"\\begin{tabular}{", fout);
2479 if (opt_border >= 2)
2483 fputc(*(cont->
aligns +
i), fout);
2484 if (opt_border != 0 && i < cont->ncolumns - 1)
2487 if (opt_border >= 2)
2492 if (!opt_tuples_only && opt_border >= 2)
2493 fputs(
"\\hline\n", fout);
2496 if (!opt_tuples_only)
2498 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2502 fputs(
"\\textit{", fout);
2506 fputs(
" \\\\\n", fout);
2507 fputs(
"\\hline\n", fout);
2512 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2518 fputs(
" \\\\\n", fout);
2519 if (opt_border == 3)
2520 fputs(
"\\hline\n", fout);
2532 if (opt_border == 2)
2533 fputs(
"\\hline\n", fout);
2535 fputs(
"\\end{tabular}\n\n\\noindent ", fout);
2542 for (f = footers; f; f = f->
next)
2545 fputs(
" \\\\\n", fout);
2563 unsigned short opt_border = cont->
opt->
border;
2566 const char *next_opt_table_attr_char = opt_table_attr;
2567 const char *last_opt_table_attr_char = NULL;
2568 const char *
const *ptr;
2579 fputs(
"\\begin{longtable}{", fout);
2581 if (opt_border >= 2)
2588 if (*(cont->
aligns +
i) ==
'l' && opt_table_attr)
2590 #define LONGTABLE_WHITESPACE " \t\n"
2593 next_opt_table_attr_char += strspn(next_opt_table_attr_char,
2596 if (next_opt_table_attr_char[0] !=
'\0')
2599 fwrite(next_opt_table_attr_char, strcspn(next_opt_table_attr_char,
2601 last_opt_table_attr_char = next_opt_table_attr_char;
2602 next_opt_table_attr_char += strcspn(next_opt_table_attr_char,
2604 fputs(
"\\textwidth}", fout);
2607 else if (last_opt_table_attr_char != NULL)
2610 fwrite(last_opt_table_attr_char, strcspn(last_opt_table_attr_char,
2612 fputs(
"\\textwidth}", fout);
2618 fputc(*(cont->
aligns +
i), fout);
2620 if (opt_border != 0 && i < cont->ncolumns - 1)
2624 if (opt_border >= 2)
2630 if (!opt_tuples_only)
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);
2644 fputs(
"\\midrule\n\\endfirsthead\n", fout);
2647 if (opt_border >= 2)
2648 fputs(
"\\toprule\n", fout);
2649 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2653 fputs(
"\\small\\textbf{\\textit{", fout);
2657 fputs(
" \\\\\n", fout);
2659 if (opt_border != 3)
2660 fputs(
"\\midrule\n", fout);
2661 fputs(
"\\endhead\n", fout);
2664 if (!opt_tuples_only && cont->
title)
2667 if (opt_border == 2)
2668 fputs(
"\\bottomrule\n", fout);
2669 fputs(
"\\caption[", fout);
2671 fputs(
" (Continued)]{", fout);
2673 fputs(
"}\n\\endfoot\n", fout);
2674 if (opt_border == 2)
2675 fputs(
"\\bottomrule\n", fout);
2676 fputs(
"\\caption[", fout);
2680 fputs(
"}\n\\endlastfoot\n", fout);
2683 else if (opt_border >= 2)
2685 fputs(
"\\bottomrule\n\\endfoot\n", fout);
2686 fputs(
"\\bottomrule\n\\endlastfoot\n", fout);
2692 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2696 fputs(
"\n&\n", fout);
2697 fputs(
"\\raggedright{", fout);
2702 fputs(
" \\tabularnewline\n", fout);
2703 if (opt_border == 3)
2704 fputs(
" \\hline\n", fout);
2711 fputs(
"\\end{longtable}\n", fout);
2719 unsigned short opt_border = cont->
opt->
border;
2722 const char *
const *ptr;
2733 if (!opt_tuples_only && cont->
title)
2735 fputs(
"\\begin{center}\n", fout);
2737 fputs(
"\n\\end{center}\n\n", fout);
2741 fputs(
"\\begin{tabular}{", fout);
2742 if (opt_border == 0)
2744 else if (opt_border == 1)
2746 else if (opt_border == 2)
2747 fputs(
"|c|l|", fout);
2752 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2759 if (!opt_tuples_only)
2761 if (opt_border == 2)
2763 fputs(
"\\hline\n", fout);
2764 fprintf(fout,
"\\multicolumn{2}{|c|}{\\textit{Record %lu}} \\\\\n", record++);
2767 fprintf(fout,
"\\multicolumn{2}{c}{\\textit{Record %lu}} \\\\\n", record++);
2769 if (opt_border >= 1)
2770 fputs(
"\\hline\n", fout);
2776 fputs(
" \\\\\n", fout);
2781 if (opt_border == 2)
2782 fputs(
"\\hline\n", fout);
2784 fputs(
"\\end{tabular}\n\n\\noindent ", fout);
2794 fputs(
" \\\\\n", fout);
2813 for (p = in; *p; p++)
2817 fputs(
"\\(rs", fout);
2829 unsigned short opt_border = cont->
opt->
border;
2831 const char *
const *ptr;
2842 if (!opt_tuples_only && cont->
title)
2844 fputs(
".LP\n.DS C\n", fout);
2846 fputs(
"\n.DE\n", fout);
2850 fputs(
".LP\n.TS\n", fout);
2851 if (opt_border == 2)
2852 fputs(
"center box;\n", fout);
2854 fputs(
"center;\n", fout);
2858 fputc(*(cont->
aligns +
i), fout);
2859 if (opt_border > 0 && i < cont->ncolumns - 1)
2865 if (!opt_tuples_only)
2867 for (
i = 0, ptr = cont->
headers; i < cont->ncolumns;
i++, ptr++)
2871 fputs(
"\\fI", fout);
2873 fputs(
"\\fP", fout);
2875 fputs(
"\n_\n", fout);
2880 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2898 fputs(
".TE\n.DS L\n", fout);
2905 for (f = footers; f; f = f->
next)
2912 fputs(
".DE\n", fout);
2921 unsigned short opt_border = cont->
opt->
border;
2924 const char *
const *ptr;
2925 unsigned short current_format = 0;
2936 if (!opt_tuples_only && cont->
title)
2938 fputs(
".LP\n.DS C\n", fout);
2940 fputs(
"\n.DE\n", fout);
2944 fputs(
".LP\n.TS\n", fout);
2945 if (opt_border == 2)
2946 fputs(
"center box;\n", fout);
2948 fputs(
"center;\n", fout);
2951 if (opt_tuples_only)
2952 fputs(
"c l;\n", fout);
2958 for (
i = 0, ptr = cont->
cells; *ptr;
i++, ptr++)
2965 if (!opt_tuples_only)
2967 if (current_format != 1)
2969 if (opt_border == 2 && record > 1)
2971 if (current_format != 0)
2972 fputs(
".T&\n", fout);
2973 fputs(
"c s.\n", fout);
2976 fprintf(fout,
"\\fIRecord %lu\\fP\n", record++);
2978 if (opt_border >= 1)
2982 if (!opt_tuples_only)
2984 if (current_format != 2)
2986 if (current_format != 0)
2987 fputs(
".T&\n", fout);
2988 if (opt_border != 1)
2989 fputs(
"c l.\n", fout);
2991 fputs(
"c | l.\n", fout);
3005 fputs(
".TE\n.DS L\n", fout);
3019 fputs(
".DE\n", fout);
3091 if (topt && topt->
pager && isatty(fileno(stdin)) && isatty(fileno(
stdout)))
3094 unsigned short int pager = topt->
pager;
3097 struct winsize screen_size;
3099 result = ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size);
3103 || (lines >= screen_size.ws_row && lines >= min_lines)
3107 const char *pagerprog;
3110 pagerprog = getenv(
"PSQL_PAGER");
3112 pagerprog = getenv(
"PAGER");
3118 if (strspn(pagerprog,
" \t\r\n") == strlen(pagerprog))
3123 pagerpipe = popen(pagerprog,
"w");
3142 if (pagerpipe && pagerpipe !=
stdout)
3153 fprintf(pagerpipe,
_(
"Interrupted\n"));
3172 const char *title,
const int ncolumns,
const int nrows)
3175 content->
title = title;
3177 content->
nrows = nrows;
3217 fprintf(stderr,
_(
"Cannot add header to table content: "
3218 "column count of %d exceeded.\n"),
3231 *content->
align = align;
3249 const bool translate,
const bool mustfree)
3257 fprintf(stderr,
_(
"Cannot add cell to table content: "
3258 "total cell count of %d exceeded.\n"),
3357 content->
opt = NULL;
3358 content->
title = NULL;
3360 content->
cells = NULL;
3363 content->
cell = NULL;
3364 content->
align = NULL;
3389 FILE **fout,
bool *is_pager)
3398 lines = cont->
nrows + 1;
3413 *is_pager = (*fout !=
stdout);
3429 FILE *fout,
bool is_pager, FILE *flog)
3431 bool is_local_pager =
false;
3445 is_local_pager = is_pager;
3515 fprintf(stderr,
_(
"invalid output format (internal error): %d"),
3535 FILE *fout,
bool is_pager, FILE *flog)
3560 for (r = 0; r < cont.
nrows; r++)
3565 bool mustfree =
false;
3590 for (footer = opt->
footers; *footer; footer++)
3628 struct lconv *extlconv;
3630 extlconv = localeconv();
3633 if (*extlconv->decimal_point)
3646 if (groupdigits <= 0 || groupdigits > 6)
3651 if (*extlconv->thousands_sep)
3684 popt->
name =
"unicode";
3733 unsigned char *start =
str;
3734 unsigned char *end =
str + strlen((
char *)
str);
3747 if (*target_width < curr_width + char_width && curr_width != 0)
3750 curr_width += char_width;
3758 *target_width = curr_width;
static void cleanup(void)
#define unconstify(underlying_type, expr)
#define ngettext(s, p, n)
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)
Assert(fmt[strlen(fmt) - 1] !='\n')
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)
static void header(const char *fmt,...) pg_attribute_printf(1
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