26 #include <sys/ioctl.h> 33 #include "catalog/pg_type_d.h" 112 const char *vertical_and_horizontal[2];
113 const char *up_and_horizontal[2];
114 const char *down_and_horizontal[2];
147 {
"\342\224\234",
"\342\225\237"},
149 {
"\342\224\244",
"\342\225\242"},
155 {
"\342\225\236",
"\342\225\240"},
157 {
"\342\225\241",
"\342\225\243"},
165 {
"\342\224\274",
"\342\225\252"},
167 {
"\342\224\264",
"\342\225\247"},
169 {
"\342\224\254",
"\342\225\244"},
175 {
"\342\225\253",
"\342\225\254"},
177 {
"\342\225\250",
"\342\225\251"},
179 {
"\342\225\245",
"\342\225\246"},
184 {
"\342\224\224",
"\342\224\202",
"\342\224\214",
"\342\224\200",
"\342\224\220",
"\342\224\230"},
186 {
"\342\225\232",
"\342\225\221",
"\342\225\224",
"\342\225\220",
"\342\225\227",
"\342\225\235"},
201 FILE **fout,
bool *is_pager);
204 FILE *fout,
bool is_pager);
212 if (my_str[0] ==
'-' || my_str[0] ==
'+')
215 return strspn(my_str,
"0123456789");
230 if (strchr(my_str,
'.') != NULL)
258 if (strspn(my_str,
"0123456789+-.eE") != strlen(my_str))
268 if (leading_digits == 0)
272 if (my_str[0] ==
'-' || my_str[0] ==
'+')
274 new_str[new_str_pos++] = my_str[0];
279 for (i = 0; i < int_len; i++)
282 if (i > 0 && --leading_digits == 0)
288 new_str[new_str_pos++] = my_str[
i];
292 if (my_str[i] ==
'.')
300 strcpy(&new_str[new_str_pos], &my_str[i]);
303 Assert(strlen(new_str) <= new_len);
347 unsigned long total_records;
351 ngettext(
"(%lu row)",
"(%lu rows)", total_records),
371 const char *
const *ptr;
372 bool need_recordsep =
false;
380 if (!opt_tuples_only && cont->
title)
382 fputs(cont->
title, fout);
387 if (!opt_tuples_only)
389 for (ptr = cont->
headers; *ptr; ptr++)
395 need_recordsep =
true;
400 need_recordsep =
true;
403 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
408 need_recordsep =
false;
417 need_recordsep =
true;
429 for (f = footers; f; f = f->
next)
434 need_recordsep =
false;
436 fputs(f->
data, fout);
437 need_recordsep =
true;
462 const char *
const *ptr;
463 bool need_recordsep =
false;
471 if (!opt_tuples_only && cont->
title)
473 fputs(cont->
title, fout);
474 need_recordsep =
true;
479 need_recordsep =
true;
482 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
489 need_recordsep =
false;
501 need_recordsep =
true;
515 fputs(f->
data, fout);
548 fputs(lformat->
hrule, fout);
549 else if (border == 2)
552 for (i = 0; i < ncolumns; i++)
554 for (j = 0; j < widths[
i]; j++)
555 fputs(lformat->
hrule, fout);
557 if (i < ncolumns - 1)
569 else if (border == 1)
570 fputs(lformat->
hrule, fout);
584 unsigned short opt_border = cont->
opt->
border;
588 unsigned int col_count = 0,
594 unsigned int *width_header,
598 unsigned int *max_nl_lines,
601 unsigned char **format_buf;
602 unsigned int width_total;
603 unsigned int total_header_width;
604 unsigned int extra_row_output_lines = 0;
605 unsigned int extra_output_lines = 0;
607 const char *
const *ptr;
614 int output_columns = 0;
615 bool is_local_pager =
false;
626 width_header =
pg_malloc0(col_count *
sizeof(*width_header));
627 width_average =
pg_malloc0(col_count *
sizeof(*width_average));
628 max_width =
pg_malloc0(col_count *
sizeof(*max_width));
629 width_wrap =
pg_malloc0(col_count *
sizeof(*width_wrap));
630 max_nl_lines =
pg_malloc0(col_count *
sizeof(*max_nl_lines));
631 curr_nl_line =
pg_malloc0(col_count *
sizeof(*curr_nl_line));
632 col_lineptrs =
pg_malloc0(col_count *
sizeof(*col_lineptrs));
633 max_bytes =
pg_malloc0(col_count *
sizeof(*max_bytes));
634 format_buf =
pg_malloc0(col_count *
sizeof(*format_buf));
635 header_done =
pg_malloc0(col_count *
sizeof(*header_done));
636 bytes_output =
pg_malloc0(col_count *
sizeof(*bytes_output));
642 width_average = NULL;
656 for (i = 0; i < col_count; i++)
663 encoding, &width, &nl_lines, &bytes_required);
664 if (width > max_width[i])
666 if (nl_lines > max_nl_lines[i])
667 max_nl_lines[
i] = nl_lines;
668 if (bytes_required > max_bytes[i])
669 max_bytes[
i] = bytes_required;
670 if (nl_lines > extra_row_output_lines)
671 extra_row_output_lines = nl_lines;
676 extra_output_lines += extra_row_output_lines;
677 extra_row_output_lines = 0;
680 for (i = 0, ptr = cont->
cells; *ptr; ptr++, i++, cell_count++)
686 pg_wcssize((
const unsigned char *) *ptr, strlen(*ptr), encoding,
687 &width, &nl_lines, &bytes_required);
689 if (width > max_width[i % col_count])
690 max_width[i % col_count] =
width;
691 if (nl_lines > max_nl_lines[i % col_count])
692 max_nl_lines[i % col_count] = nl_lines;
693 if (bytes_required > max_bytes[i % col_count])
694 max_bytes[i % col_count] = bytes_required;
696 width_average[i % col_count] +=
width;
700 if (col_count != 0 && cell_count != 0)
702 int rows = cell_count / col_count;
704 for (i = 0; i < col_count; i++)
705 width_average[i] /= rows;
710 width_total = col_count;
711 else if (opt_border == 1)
712 width_total = col_count * 3 - ((col_count > 0) ? 1 : 0);
714 width_total = col_count * 3 + 1;
715 total_header_width = width_total;
717 for (i = 0; i < col_count; i++)
719 width_total += max_width[
i];
720 total_header_width += width_header[
i];
730 for (i = 0; i < col_count; i++)
733 col_lineptrs[
i] =
pg_malloc0((max_nl_lines[i] + 1) *
734 sizeof(**col_lineptrs));
738 col_lineptrs[
i]->
ptr = format_buf[
i];
742 for (i = 0; i < col_count; i++)
743 width_wrap[i] = max_width[i];
750 else if ((fout ==
stdout && isatty(fileno(
stdout))) || is_pager)
757 struct winsize screen_size;
759 if (ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size) != -1)
760 output_columns = screen_size.ws_col;
774 if (output_columns > 0 && output_columns >= total_header_width)
777 while (width_total > output_columns)
779 double max_ratio = 0;
788 for (i = 0; i < col_count; i++)
790 if (width_average[i] && width_wrap[i] > width_header[i])
795 ratio = (double) width_wrap[i] / width_average[i] +
797 if (ratio > max_ratio)
810 width_wrap[worst_col]--;
823 (output_columns < total_header_width || output_columns < width_total))
830 if (!is_pager && fout ==
stdout && output_columns > 0 &&
831 (output_columns < total_header_width || output_columns < width_total))
834 is_pager = is_local_pager =
true;
838 if (!is_pager && fout ==
stdout)
841 for (i = 0, ptr = cont->
cells; *ptr; ptr++, cell_count++)
847 pg_wcssize((
const unsigned char *) *ptr, strlen(*ptr), encoding,
848 &width, &nl_lines, &bytes_required);
854 if (width > 0 && width_wrap[i])
856 unsigned int extra_lines;
859 extra_lines = ((width - 1) / width_wrap[i]) + nl_lines - 1;
860 if (extra_lines > extra_row_output_lines)
861 extra_row_output_lines = extra_lines;
865 if (++i >= col_count)
869 extra_output_lines += extra_row_output_lines;
870 extra_row_output_lines = 0;
873 IsPagerNeeded(cont, extra_output_lines,
false, &fout, &is_pager);
874 is_local_pager = is_pager;
881 if (cont->
title && !opt_tuples_only)
887 encoding, &width, &height, NULL);
888 if (width >= width_total)
893 fprintf(fout,
"%-*s%s\n", (width_total - width) / 2,
"",
898 if (!opt_tuples_only)
900 int more_col_wrapping;
907 for (i = 0; i < col_count; i++)
909 strlen(cont->
headers[i]), encoding,
910 col_lineptrs[i], max_nl_lines[i]);
912 more_col_wrapping = col_count;
914 memset(header_done,
false, col_count *
sizeof(
bool));
915 while (more_col_wrapping)
920 for (i = 0; i < cont->
ncolumns; i++)
922 struct lineptr *this_line = col_lineptrs[
i] + curr_nl_line;
923 unsigned int nbspace;
925 if (opt_border != 0 ||
932 nbspace = width_wrap[
i] - this_line->
width;
936 nbspace / 2,
"", this_line->
ptr, (nbspace + 1) / 2,
"");
938 if (!(this_line + 1)->ptr)
945 fprintf(fout,
"%*s", width_wrap[i],
"");
951 if (opt_border != 0 && col_count > 0 && i < col_count - 1)
967 for (i = 0, ptr = cont->
cells; *ptr; i += col_count, ptr += col_count)
977 for (j = 0; j < col_count; j++)
979 pg_wcsformat((
const unsigned char *) ptr[j], strlen(ptr[j]), encoding,
980 col_lineptrs[j], max_nl_lines[j]);
984 memset(bytes_output, 0, col_count *
sizeof(
int));
1000 for (j = 0; j < col_count; j++)
1003 struct lineptr *this_line = &col_lineptrs[j][curr_nl_line[j]];
1004 int bytes_to_output;
1005 int chars_to_output = width_wrap[j];
1006 bool finalspaces = (opt_border == 2 ||
1007 (col_count > 0 && j < col_count - 1));
1010 if (opt_border != 0)
1020 if (!this_line->
ptr)
1024 fprintf(fout,
"%*s", chars_to_output,
"");
1031 &chars_to_output, encoding);
1039 if (chars_to_output > width_wrap[j])
1040 chars_to_output = width_wrap[j];
1042 if (cont->
aligns[j] ==
'r')
1045 fprintf(fout,
"%*s", width_wrap[j] - chars_to_output,
"");
1047 (
char *) (this_line->
ptr + bytes_output[j]),
1054 (
char *) (this_line->
ptr + bytes_output[j]),
1058 bytes_output[j] += bytes_to_output;
1061 if (*(this_line->
ptr + bytes_output[j]) !=
'\0')
1067 if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
1069 bytes_output[j] = 0;
1075 if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
1077 if (bytes_output[j] != 0)
1079 else if (curr_nl_line[j] != 0)
1087 if (cont->
aligns[j] !=
'r')
1093 width_wrap[j] - chars_to_output,
"");
1101 else if (opt_border == 2 || (col_count > 0 && j < col_count - 1))
1105 if (opt_border != 0 && (col_count > 0 && j < col_count - 1))
1111 else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL)
1119 if (opt_border == 2)
1123 }
while (more_lines);
1139 for (f = footers; f; f = f->
next)
1148 for (i = 0; i < col_count; i++)
1150 free(col_lineptrs[i]);
1151 free(format_buf[i]);
1154 free(width_average);
1173 const unsigned short opt_border,
1174 unsigned long record,
1175 unsigned int hwidth,
1176 unsigned int dwidth,
1184 if (opt_border == 2)
1186 else if (opt_border == 1)
1187 fputs(lformat->
hrule, fout);
1191 if (opt_border == 0)
1192 reclen =
fprintf(fout,
"* Record %lu", record);
1194 reclen =
fprintf(fout,
"[ RECORD %lu ]", record);
1196 if (opt_border != 2)
1200 for (i = reclen; i < hwidth; i++)
1201 fputs(opt_border > 0 ? lformat->
hrule :
" ", fout);
1207 fputs(lformat->
hrule, fout);
1211 fputs(lformat->
hrule, fout);
1220 for (i = reclen; i < dwidth; i++)
1221 fputs(opt_border > 0 ? lformat->
hrule :
" ", fout);
1222 if (opt_border == 2)
1229 FILE *fout,
bool is_pager)
1232 unsigned short opt_border = cont->
opt->
border;
1237 const char *
const *
ptr;
1247 bool is_local_pager =
false,
1250 int output_columns = 0;
1267 for (f = footers; f; f = f->
next)
1284 is_local_pager = is_pager;
1288 for (i = 0; i < cont->
ncolumns; i++)
1295 encoding, &width, &height, &fs);
1298 if (height > hheight)
1303 if (fs > hformatsize)
1308 for (i = 0, ptr = cont->
cells; *ptr; ptr++, i++)
1314 pg_wcssize((
const unsigned char *) *ptr, strlen(*ptr), encoding,
1315 &width, &height, &fs);
1318 if (height > dheight)
1323 if (fs > dformatsize)
1331 dlineptr =
pg_malloc((
sizeof(*dlineptr)) * (dheight + 1));
1332 hlineptr =
pg_malloc((
sizeof(*hlineptr)) * (hheight + 1));
1340 if (!opt_tuples_only && cont->
title)
1349 else if ((fout ==
stdout && isatty(fileno(
stdout))) || is_pager)
1356 struct winsize screen_size;
1358 if (ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size) != -1)
1359 output_columns = screen_size.ws_col;
1369 unsigned int swidth,
1373 if (opt_border == 0)
1387 else if (opt_border == 1)
1396 if (hmultiline && (format == &pg_asciiformat_old))
1412 opt_border < 2 && format != &pg_asciiformat_old)
1416 if (!opt_tuples_only)
1418 if (cont->
nrows > 0)
1419 rwidth = 1 + (int) log10(cont->
nrows);
1420 if (opt_border == 0)
1422 else if (opt_border == 1)
1434 width = hwidth + swidth + dwidth;
1439 if (output_columns > 0)
1441 unsigned int min_width;
1444 min_width = hwidth + swidth + 3;
1446 if (min_width < rwidth)
1449 if (output_columns >= width)
1453 newdwidth = width - hwidth - swidth;
1455 else if (output_columns < min_width)
1458 newdwidth = min_width - hwidth - swidth;
1463 newdwidth = output_columns - hwidth - swidth;
1470 newdwidth = width - hwidth - swidth;
1477 if (newdwidth < dwidth && !dmultiline &&
1478 opt_border < 2 && format != &pg_asciiformat_old)
1491 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
1512 unsigned int lhwidth = hwidth;
1514 if ((opt_border < 2) &&
1516 (format == &pg_asciiformat_old))
1519 if (!opt_tuples_only)
1521 lhwidth, dwidth, pos, fout);
1530 encoding, hlineptr, hheight);
1532 pg_wcsformat((
const unsigned char *) *ptr, strlen(*ptr), encoding,
1540 dcomplete = hcomplete = 0;
1542 chars_to_output = dlineptr[dline].
width;
1543 while (!dcomplete || !hcomplete)
1546 if (opt_border == 2)
1552 int swidth = hwidth,
1553 target_width = hwidth;
1558 if ((opt_border == 2) ||
1559 (hmultiline && (format == &pg_asciiformat_old)))
1567 fprintf(fout,
"%-s", hlineptr[hline].ptr);
1572 swidth -= target_width;
1574 fprintf(fout,
"%*s", swidth,
" ");
1579 if (hlineptr[hline + 1].ptr)
1582 if ((opt_border > 0) ||
1583 (hmultiline && (format != &pg_asciiformat_old)))
1590 if ((opt_border > 0) ||
1591 (hmultiline && (format != &pg_asciiformat_old)))
1598 unsigned int swidth = hwidth + opt_border;
1600 if ((opt_border < 2) &&
1602 (format == &pg_asciiformat_old))
1605 if ((opt_border == 0) &&
1606 (format != &pg_asciiformat_old) &&
1610 fprintf(fout,
"%*s", swidth,
" ");
1618 else if (dline == 0)
1627 int target_width = dwidth,
1634 fputs(offset == 0 ?
" " : format->
wrap_left, fout);
1640 &target_width, encoding);
1641 fputnbytes(fout, (
char *) (dlineptr[dline].ptr + offset),
1644 chars_to_output -= target_width;
1645 offset += bytes_to_output;
1648 swidth -= target_width;
1650 if (chars_to_output)
1653 if ((opt_border > 1) ||
1654 (dmultiline && (format != &pg_asciiformat_old)))
1657 fprintf(fout,
"%*s", swidth,
" ");
1661 else if (dlineptr[dline + 1].ptr)
1664 if ((opt_border > 1) ||
1665 (dmultiline && (format != &pg_asciiformat_old)))
1668 fprintf(fout,
"%*s", swidth,
" ");
1673 chars_to_output = dlineptr[dline].
width;
1681 fprintf(fout,
"%*s", swidth,
" ");
1688 if (opt_border == 2)
1748 for (p = str; *p; p++)
1773 if (strchr(str, sep) != NULL ||
1774 strcspn(str,
"\r\n\"") != strlen(str) ||
1775 strcmp(str,
"\\.") == 0 ||
1776 sep ==
'\\' || sep ==
'.')
1785 const char *
const *ptr;
1802 for (ptr = cont->
headers; *ptr; ptr++)
1812 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
1825 const char *
const *ptr;
1829 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
1858 bool leading_space =
true;
1860 for (p = in; *p; p++)
1865 fputs(
"&", fout);
1868 fputs(
"<", fout);
1871 fputs(
">", fout);
1874 fputs(
"<br />\n", fout);
1877 fputs(
""", fout);
1882 fputs(
" ", fout);
1890 leading_space =
false;
1899 unsigned short opt_border = cont->
opt->
border;
1902 const char *
const *ptr;
1909 fprintf(fout,
"<table border=\"%d\"", opt_border);
1911 fprintf(fout,
" %s", opt_table_attr);
1915 if (!opt_tuples_only && cont->
title)
1917 fputs(
" <caption>", fout);
1919 fputs(
"</caption>\n", fout);
1923 if (!opt_tuples_only)
1925 fputs(
" <tr>\n", fout);
1926 for (ptr = cont->
headers; *ptr; ptr++)
1928 fputs(
" <th align=\"center\">", fout);
1930 fputs(
"</th>\n", fout);
1932 fputs(
" </tr>\n", fout);
1937 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
1943 fputs(
" <tr valign=\"top\">\n", fout);
1948 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
1949 fputs(
" ", fout);
1953 fputs(
"</td>\n", fout);
1956 fputs(
" </tr>\n", fout);
1963 fputs(
"</table>\n", fout);
1971 for (f = footers; f; f = f->
next)
1974 fputs(
"<br />\n", fout);
1976 fputs(
"</p>", fout);
1988 unsigned short opt_border = cont->
opt->
border;
1992 const char *
const *ptr;
1999 fprintf(fout,
"<table border=\"%d\"", opt_border);
2001 fprintf(fout,
" %s", opt_table_attr);
2005 if (!opt_tuples_only && cont->
title)
2007 fputs(
" <caption>", fout);
2009 fputs(
"</caption>\n", fout);
2014 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
2020 if (!opt_tuples_only)
2022 "\n <tr><td colspan=\"2\" align=\"center\">Record %lu</td></tr>\n",
2025 fputs(
"\n <tr><td colspan=\"2\"> </td></tr>\n", fout);
2027 fputs(
" <tr valign=\"top\">\n" 2030 fputs(
"</th>\n", fout);
2034 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2035 fputs(
" ", fout);
2039 fputs(
"</td>\n </tr>\n", fout);
2044 fputs(
"</table>\n", fout);
2055 fputs(
"<br />\n", fout);
2057 fputs(
"</p>", fout);
2075 for (p = in; *p; p++)
2092 unsigned short opt_border = cont->
opt->
border;
2094 const char *
const *ptr;
2105 if (!opt_tuples_only && cont->
title)
2108 fputs(cont->
title, fout);
2113 fprintf(fout,
"[%scols=\"", !opt_tuples_only ?
"options=\"header\"," :
"");
2114 for (i = 0; i < cont->
ncolumns; i++)
2124 fputs(
",frame=\"none\",grid=\"none\"", fout);
2127 fputs(
",frame=\"none\"", fout);
2130 fputs(
",frame=\"all\",grid=\"all\"", fout);
2134 fputs(
"|====\n", fout);
2137 if (!opt_tuples_only)
2139 for (ptr = cont->
headers; *ptr; ptr++)
2151 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
2164 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2176 fputs(
"|====\n", fout);
2187 fputs(
"\n....\n", fout);
2188 for (f = footers; f; f = f->
next)
2190 fputs(f->
data, fout);
2193 fputs(
"....\n", fout);
2202 unsigned short opt_border = cont->
opt->
border;
2205 const char *
const *ptr;
2216 if (!opt_tuples_only && cont->
title)
2219 fputs(cont->
title, fout);
2224 fputs(
"[cols=\"h,l\"", fout);
2228 fputs(
",frame=\"none\",grid=\"none\"", fout);
2231 fputs(
",frame=\"none\"", fout);
2234 fputs(
",frame=\"all\",grid=\"all\"", fout);
2238 fputs(
"|====\n", fout);
2242 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
2248 if (!opt_tuples_only)
2253 fputs(
"2+|\n", fout);
2261 if ((*ptr)[strspn(*ptr,
" \t")] ==
'\0')
2268 fputs(
"|====\n", fout);
2277 fputs(
"\n....\n", fout);
2280 fputs(f->
data, fout);
2283 fputs(
"....\n", fout);
2299 for (p = in; *p; p++)
2320 fputs(
"\\textless{}", fout);
2323 fputs(
"\\textgreater{}", fout);
2326 fputs(
"\\textbackslash{}", fout);
2329 fputs(
"\\^{}", fout);
2338 fputs(
"\\textbar{}", fout);
2344 fputs(
"\\~{}", fout);
2348 fputs(
"\\\\", fout);
2360 unsigned short opt_border = cont->
opt->
border;
2362 const char *
const *ptr;
2373 if (!opt_tuples_only && cont->
title)
2375 fputs(
"\\begin{center}\n", fout);
2377 fputs(
"\n\\end{center}\n\n", fout);
2381 fputs(
"\\begin{tabular}{", fout);
2383 if (opt_border >= 2)
2385 for (i = 0; i < cont->
ncolumns; i++)
2387 fputc(*(cont->
aligns + i), fout);
2388 if (opt_border != 0 && i < cont->ncolumns - 1)
2391 if (opt_border >= 2)
2396 if (!opt_tuples_only && opt_border >= 2)
2397 fputs(
"\\hline\n", fout);
2400 if (!opt_tuples_only)
2402 for (i = 0, ptr = cont->
headers; i < cont->ncolumns; i++, ptr++)
2406 fputs(
"\\textit{", fout);
2410 fputs(
" \\\\\n", fout);
2411 fputs(
"\\hline\n", fout);
2416 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
2422 fputs(
" \\\\\n", fout);
2423 if (opt_border == 3)
2424 fputs(
"\\hline\n", fout);
2436 if (opt_border == 2)
2437 fputs(
"\\hline\n", fout);
2439 fputs(
"\\end{tabular}\n\n\\noindent ", fout);
2446 for (f = footers; f; f = f->
next)
2449 fputs(
" \\\\\n", fout);
2467 unsigned short opt_border = cont->
opt->
border;
2470 const char *next_opt_table_attr_char = opt_table_attr;
2471 const char *last_opt_table_attr_char = NULL;
2472 const char *
const *ptr;
2483 fputs(
"\\begin{longtable}{", fout);
2485 if (opt_border >= 2)
2488 for (i = 0; i < cont->
ncolumns; i++)
2492 if (*(cont->
aligns + i) ==
'l' && opt_table_attr)
2494 #define LONGTABLE_WHITESPACE " \t\n" 2497 next_opt_table_attr_char += strspn(next_opt_table_attr_char,
2500 if (next_opt_table_attr_char[0] !=
'\0')
2503 fwrite(next_opt_table_attr_char, strcspn(next_opt_table_attr_char,
2505 last_opt_table_attr_char = next_opt_table_attr_char;
2506 next_opt_table_attr_char += strcspn(next_opt_table_attr_char,
2508 fputs(
"\\textwidth}", fout);
2511 else if (last_opt_table_attr_char != NULL)
2514 fwrite(last_opt_table_attr_char, strcspn(last_opt_table_attr_char,
2516 fputs(
"\\textwidth}", fout);
2522 fputc(*(cont->
aligns + i), fout);
2524 if (opt_border != 0 && i < cont->ncolumns - 1)
2528 if (opt_border >= 2)
2534 if (!opt_tuples_only)
2537 if (opt_border >= 2)
2538 fputs(
"\\toprule\n", fout);
2539 for (i = 0, ptr = cont->
headers; i < cont->ncolumns; i++, ptr++)
2543 fputs(
"\\small\\textbf{\\textit{", fout);
2547 fputs(
" \\\\\n", fout);
2548 fputs(
"\\midrule\n\\endfirsthead\n", fout);
2551 if (opt_border >= 2)
2552 fputs(
"\\toprule\n", fout);
2553 for (i = 0, ptr = cont->
headers; i < cont->ncolumns; i++, ptr++)
2557 fputs(
"\\small\\textbf{\\textit{", fout);
2561 fputs(
" \\\\\n", fout);
2563 if (opt_border != 3)
2564 fputs(
"\\midrule\n", fout);
2565 fputs(
"\\endhead\n", fout);
2568 if (!opt_tuples_only && cont->
title)
2571 if (opt_border == 2)
2572 fputs(
"\\bottomrule\n", fout);
2573 fputs(
"\\caption[", fout);
2575 fputs(
" (Continued)]{", fout);
2577 fputs(
"}\n\\endfoot\n", fout);
2578 if (opt_border == 2)
2579 fputs(
"\\bottomrule\n", fout);
2580 fputs(
"\\caption[", fout);
2584 fputs(
"}\n\\endlastfoot\n", fout);
2587 else if (opt_border >= 2)
2589 fputs(
"\\bottomrule\n\\endfoot\n", fout);
2590 fputs(
"\\bottomrule\n\\endlastfoot\n", fout);
2596 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
2599 if (i != 0 && i % cont->
ncolumns != 0)
2600 fputs(
"\n&\n", fout);
2601 fputs(
"\\raggedright{", fout);
2606 fputs(
" \\tabularnewline\n", fout);
2607 if (opt_border == 3)
2608 fputs(
" \\hline\n", fout);
2615 fputs(
"\\end{longtable}\n", fout);
2623 unsigned short opt_border = cont->
opt->
border;
2626 const char *
const *ptr;
2637 if (!opt_tuples_only && cont->
title)
2639 fputs(
"\\begin{center}\n", fout);
2641 fputs(
"\n\\end{center}\n\n", fout);
2645 fputs(
"\\begin{tabular}{", fout);
2646 if (opt_border == 0)
2648 else if (opt_border == 1)
2650 else if (opt_border == 2)
2651 fputs(
"|c|l|", fout);
2656 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
2663 if (!opt_tuples_only)
2665 if (opt_border == 2)
2667 fputs(
"\\hline\n", fout);
2668 fprintf(fout,
"\\multicolumn{2}{|c|}{\\textit{Record %lu}} \\\\\n", record++);
2671 fprintf(fout,
"\\multicolumn{2}{c}{\\textit{Record %lu}} \\\\\n", record++);
2673 if (opt_border >= 1)
2674 fputs(
"\\hline\n", fout);
2680 fputs(
" \\\\\n", fout);
2685 if (opt_border == 2)
2686 fputs(
"\\hline\n", fout);
2688 fputs(
"\\end{tabular}\n\n\\noindent ", fout);
2698 fputs(
" \\\\\n", fout);
2717 for (p = in; *p; p++)
2721 fputs(
"\\(rs", fout);
2733 unsigned short opt_border = cont->
opt->
border;
2735 const char *
const *ptr;
2746 if (!opt_tuples_only && cont->
title)
2748 fputs(
".LP\n.DS C\n", fout);
2750 fputs(
"\n.DE\n", fout);
2754 fputs(
".LP\n.TS\n", fout);
2755 if (opt_border == 2)
2756 fputs(
"center box;\n", fout);
2758 fputs(
"center;\n", fout);
2760 for (i = 0; i < cont->
ncolumns; i++)
2762 fputc(*(cont->
aligns + i), fout);
2763 if (opt_border > 0 && i < cont->ncolumns - 1)
2769 if (!opt_tuples_only)
2771 for (i = 0, ptr = cont->
headers; i < cont->ncolumns; i++, ptr++)
2775 fputs(
"\\fI", fout);
2777 fputs(
"\\fP", fout);
2779 fputs(
"\n_\n", fout);
2784 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
2802 fputs(
".TE\n.DS L\n", fout);
2809 for (f = footers; f; f = f->
next)
2816 fputs(
".DE\n", fout);
2825 unsigned short opt_border = cont->
opt->
border;
2828 const char *
const *ptr;
2829 unsigned short current_format = 0;
2840 if (!opt_tuples_only && cont->
title)
2842 fputs(
".LP\n.DS C\n", fout);
2844 fputs(
"\n.DE\n", fout);
2848 fputs(
".LP\n.TS\n", fout);
2849 if (opt_border == 2)
2850 fputs(
"center box;\n", fout);
2852 fputs(
"center;\n", fout);
2855 if (opt_tuples_only)
2856 fputs(
"c l;\n", fout);
2862 for (i = 0, ptr = cont->
cells; *ptr; i++, ptr++)
2869 if (!opt_tuples_only)
2871 if (current_format != 1)
2873 if (opt_border == 2 && record > 1)
2875 if (current_format != 0)
2876 fputs(
".T&\n", fout);
2877 fputs(
"c s.\n", fout);
2880 fprintf(fout,
"\\fIRecord %lu\\fP\n", record++);
2882 if (opt_border >= 1)
2886 if (!opt_tuples_only)
2888 if (current_format != 2)
2890 if (current_format != 0)
2891 fputs(
".T&\n", fout);
2892 if (opt_border != 1)
2893 fputs(
"c l.\n", fout);
2895 fputs(
"c | l.\n", fout);
2909 fputs(
".TE\n.DS L\n", fout);
2923 fputs(
".DE\n", fout);
2995 if (topt && topt->
pager && isatty(fileno(stdin)) && isatty(fileno(
stdout)))
2998 unsigned short int pager = topt->
pager;
3001 struct winsize screen_size;
3003 result = ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size);
3007 || (lines >= screen_size.ws_row && lines >= min_lines)
3011 const char *pagerprog;
3014 pagerprog = getenv(
"PSQL_PAGER");
3016 pagerprog = getenv(
"PAGER");
3022 if (strspn(pagerprog,
" \t\r\n") == strlen(pagerprog))
3026 pagerpipe = popen(pagerprog,
"w");
3045 if (pagerpipe && pagerpipe !=
stdout)
3056 fprintf(pagerpipe,
_(
"Interrupted\n"));
3075 const char *title,
const int ncolumns,
const int nrows)
3078 content->
title = title;
3080 content->
nrows = nrows;
3120 fprintf(stderr,
_(
"Cannot add header to table content: " 3121 "column count of %d exceeded.\n"),
3134 *content->
align = align;
3152 const bool translate,
const bool mustfree)
3160 fprintf(stderr,
_(
"Cannot add cell to table content: " 3161 "total cell count of %d exceeded.\n"),
3260 content->
opt = NULL;
3261 content->
title = NULL;
3263 content->
cells = NULL;
3266 content->
cell = NULL;
3267 content->
align = NULL;
3292 FILE **fout,
bool *is_pager)
3301 lines = cont->
nrows + 1;
3316 *is_pager = (*fout !=
stdout);
3332 FILE *fout,
bool is_pager, FILE *flog)
3334 bool is_local_pager =
false;
3348 is_local_pager = is_pager;
3415 fprintf(stderr,
_(
"invalid output format (internal error): %d"),
3435 FILE *fout,
bool is_pager, FILE *flog)
3452 for (i = 0; i < cont.
ncolumns; i++)
3460 for (r = 0; r < cont.
nrows; r++)
3462 for (c = 0; c < cont.
ncolumns; c++)
3465 bool mustfree =
false;
3490 for (footer = opt->
footers; *footer; footer++)
3527 struct lconv *extlconv;
3529 extlconv = localeconv();
3532 if (*extlconv->decimal_point)
3545 if (groupdigits <= 0 || groupdigits > 6)
3550 if (*extlconv->thousands_sep)
3583 popt->
name =
"unicode";
3632 unsigned char *start =
str;
3633 unsigned char *end = str + strlen((
char *) str);
3638 int char_width =
PQdsplen((
char *) str, encoding);
3646 if (*target_width < curr_width + char_width && curr_width != 0)
3649 curr_width += char_width;
3651 str +=
PQmblen((
char *) str, encoding);
3654 *target_width = curr_width;
static void print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
void printTableSetFooter(printTableContent *const content, const char *footer)
int PQnfields(const PGresult *res)
static void print_unaligned_vertical(const printTableContent *cont, FILE *fout)
static void latex_escaped_print(const char *in, FILE *fout)
static void asciidoc_escaped_print(const char *in, FILE *fout)
void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, struct lineptr *lines, int count)
static void print_separator(struct separator sep, FILE *fout)
const printTextFormat * line_style
void printTableCleanup(printTableContent *const content)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
struct unicodeStyleBorderFormat unicodeStyleBorderFormat
struct unicodeStyleRowFormat unicodeStyleRowFormat
char * PQfname(const PGresult *res, int field_num)
void * pg_malloc(size_t size)
const char * midvrule_wrap
static const unicodeStyleFormat unicode_style
static void print_csv_vertical(const printTableContent *cont, FILE *fout)
static printTableFooter * footers_with_default(const printTableContent *cont)
void disable_sigpipe_trap(void)
const char * header_nl_left
printTextFormat pg_utf8format
static void print_aligned_vertical_line(const printTextFormat *format, const unsigned short opt_border, unsigned long record, unsigned int hwidth, unsigned int dwidth, printTextRule pos, FILE *fout)
void ClosePager(FILE *pagerpipe)
const printTextFormat pg_asciiformat_old
int PQdsplen(const char *s, int encoding)
static void print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager)
static int integer_digits(const char *my_str)
static void print_aligned_vertical(const printTableContent *cont, FILE *fout, bool is_pager)
void set_sigpipe_trap_state(bool ignore)
unicode_linestyle unicode_header_linestyle
static void print_troff_ms_text(const printTableContent *cont, FILE *fout)
printTextLineFormat lrule[4]
static void print_csv_text(const printTableContent *cont, FILE *fout)
const printTableOpt * opt
int PQntuples(const PGresult *res)
unsigned long prior_records
const char * midvrule_blank
unicode_linestyle unicode_border_linestyle
Datum translate(PG_FUNCTION_ARGS)
const char * header_nl_right
void pg_wcssize(const unsigned char *pwcs, size_t len, int encoding, int *result_width, int *result_height, int *result_format_size)
volatile bool cancel_pressed
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
static void IsPagerNeeded(const printTableContent *cont, int extra_lines, bool expanded, FILE **fout, bool *is_pager)
unsigned short int border
unsigned short int expanded
static void csv_escaped_print(const char *str, FILE *fout)
static void print_html_text(const printTableContent *cont, FILE *fout)
FILE * PageOutput(int lines, const printTableOpt *topt)
static void print_latex_text(const printTableContent *cont, FILE *fout)
void * pg_malloc0(size_t size)
static void print_unaligned_text(const printTableContent *cont, FILE *fout)
unicode_linestyle unicode_column_linestyle
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
unsigned char * mbvalidate(unsigned char *pwcs, int encoding)
Oid PQftype(const PGresult *res, int field_num)
static void print_asciidoc_vertical(const printTableContent *cont, FILE *fout)
struct unicodeStyleColumnFormat unicodeStyleColumnFormat
static void print_html_vertical(const printTableContent *cont, FILE *fout)
static void csv_print_field(const char *str, FILE *fout, char sep)
char * pg_strdup(const char *in)
#define LONGTABLE_WHITESPACE
static void _print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths, unsigned short border, printTextRule pos, const printTextFormat *format, FILE *fout)
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
void restore_sigpipe_trap(void)
#define unconstify(underlying_type, expr)
char column_type_alignment(Oid ftype)
static bool always_ignore_sigpipe
struct unicodeStyleFormat unicodeStyleFormat
#define ngettext(s, p, n)
static void troff_ms_escaped_print(const char *in, FILE *fout)
void printTableAddFooter(printTableContent *const content, const char *footer)
static void cleanup(void)
static void print_latex_longtable_text(const printTableContent *cont, FILE *fout)
printTableFooter * footer
static printTableFooter default_footer_cell
static void print_asciidoc_text(const printTableContent *cont, FILE *fout)
pqsigfunc pqsignal(int signum, pqsigfunc handler)
struct separator fieldSep
const printTextFormat * get_line_style(const printTableOpt *opt)
static char * format_numeric_locale(const char *my_str)
#define Assert(condition)
void setDecimalLocale(void)
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
static void header(const char *fmt,...) pg_attribute_printf(1
printTableFooter * footers
static int strlen_max_width(unsigned char *str, int *target_width, int encoding)
static void fputnbytes(FILE *f, const char *str, size_t n)
static char * decimal_point
static void print_latex_vertical(const printTableContent *cont, FILE *fout)
void html_escaped_print(const char *in, FILE *fout)
void refresh_utf8format(const printTableOpt *opt)
static char * thousands_sep
const printTextFormat pg_asciiformat
struct separator recordSep
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
const bool * translate_columns
int PQmblen(const char *s, int encoding)
static int additional_numeric_locale_len(const char *my_str)
static char default_footer[100]