PostgreSQL Source Code git master
Loading...
Searching...
No Matches
print.c File Reference
#include "postgres_fe.h"
#include <limits.h>
#include <math.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include "catalog/pg_type_d.h"
#include "fe_utils/mbprint.h"
#include "fe_utils/print.h"
Include dependency graph for print.c:

Go to the source code of this file.

Data Structures

struct  unicodeStyleRowFormat
 
struct  unicodeStyleColumnFormat
 
struct  unicodeStyleBorderFormat
 
struct  unicodeStyleFormat
 

Macros

#define LONGTABLE_WHITESPACE   " \t\n"
 

Typedefs

typedef struct unicodeStyleRowFormat unicodeStyleRowFormat
 
typedef struct unicodeStyleColumnFormat unicodeStyleColumnFormat
 
typedef struct unicodeStyleBorderFormat unicodeStyleBorderFormat
 
typedef struct unicodeStyleFormat unicodeStyleFormat
 

Functions

static int strlen_max_width (unsigned char *str, int *target_width, int encoding)
 
static FILEPageOutputInternal (int lines, const printTableOpt *topt, const printTableContent *cont, const unsigned int *width_wrap, bool vertical)
 
static void IsPagerNeeded (const printTableContent *cont, const unsigned int *width_wrap, bool vertical, FILE **fout, bool *is_pager)
 
static void print_aligned_vertical (const printTableContent *cont, FILE *fout, bool is_pager)
 
static int integer_digits (const char *my_str)
 
static int additional_numeric_locale_len (const char *my_str)
 
static charformat_numeric_locale (const char *my_str)
 
static void print_separator (struct separator sep, FILE *fout)
 
static printTableFooterfooters_with_default (const printTableContent *cont)
 
static void print_unaligned_text (const printTableContent *cont, FILE *fout)
 
static void print_unaligned_vertical (const printTableContent *cont, FILE *fout)
 
static void _print_horizontal_line (const unsigned int ncolumns, const unsigned int *widths, unsigned short border, printTextRule pos, const printTextFormat *format, FILE *fout)
 
static void print_aligned_text (const printTableContent *cont, FILE *fout, bool is_pager)
 
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)
 
static void csv_escaped_print (const char *str, FILE *fout)
 
static void csv_print_field (const char *str, FILE *fout, char sep)
 
static void print_csv_text (const printTableContent *cont, FILE *fout)
 
static void print_csv_vertical (const printTableContent *cont, FILE *fout)
 
void html_escaped_print (const char *in, FILE *fout)
 
static void print_html_text (const printTableContent *cont, FILE *fout)
 
static void print_html_vertical (const printTableContent *cont, FILE *fout)
 
static void asciidoc_escaped_print (const char *in, FILE *fout)
 
static void print_asciidoc_text (const printTableContent *cont, FILE *fout)
 
static void print_asciidoc_vertical (const printTableContent *cont, FILE *fout)
 
static void latex_escaped_print (const char *in, FILE *fout)
 
static void print_latex_text (const printTableContent *cont, FILE *fout)
 
static void print_latex_longtable_text (const printTableContent *cont, FILE *fout)
 
static void print_latex_vertical (const printTableContent *cont, FILE *fout)
 
static void troff_ms_escaped_print (const char *in, FILE *fout)
 
static void print_troff_ms_text (const printTableContent *cont, FILE *fout)
 
static void print_troff_ms_vertical (const printTableContent *cont, FILE *fout)
 
void disable_sigpipe_trap (void)
 
void restore_sigpipe_trap (void)
 
void set_sigpipe_trap_state (bool ignore)
 
FILEPageOutput (int lines, const printTableOpt *topt)
 
void ClosePager (FILE *pagerpipe)
 
void printTableInit (printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
 
void printTableAddHeader (printTableContent *const content, char *header, const bool translate, const char align)
 
void printTableAddCell (printTableContent *const content, char *cell, const bool translate, const bool mustfree)
 
void printTableAddFooter (printTableContent *const content, const char *footer)
 
void printTableSetFooter (printTableContent *const content, const char *footer)
 
void printTableCleanup (printTableContent *const content)
 
void printTable (const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
 
void printQuery (const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
 
char column_type_alignment (Oid ftype)
 
void setDecimalLocale (void)
 
const printTextFormatget_line_style (const printTableOpt *opt)
 
void refresh_utf8format (const printTableOpt *opt)
 

Variables

volatile sig_atomic_t cancel_pressed = false
 
static bool always_ignore_sigpipe = false
 
static chardecimal_point
 
static int groupdigits
 
static charthousands_sep
 
static char default_footer [100]
 
static printTableFooter default_footer_cell = {default_footer, NULL}
 
const printTextFormat pg_asciiformat
 
const printTextFormat pg_asciiformat_old
 
printTextFormat pg_utf8format
 
static const unicodeStyleFormat unicode_style
 

Macro Definition Documentation

◆ LONGTABLE_WHITESPACE

#define LONGTABLE_WHITESPACE   " \t\n"

Typedef Documentation

◆ unicodeStyleBorderFormat

◆ unicodeStyleColumnFormat

◆ unicodeStyleFormat

◆ unicodeStyleRowFormat

Function Documentation

◆ _print_horizontal_line()

static void _print_horizontal_line ( const unsigned int  ncolumns,
const unsigned int widths,
unsigned short  border,
printTextRule  pos,
const printTextFormat format,
FILE fout 
)
static

Definition at line 609 of file print.c.

613{
614 const printTextLineFormat *lformat = &format->lrule[pos];
615 unsigned int i,
616 j;
617
618 if (border == 1)
619 fputs(lformat->hrule, fout);
620 else if (border == 2)
621 fprintf(fout, "%s%s", lformat->leftvrule, lformat->hrule);
622
623 for (i = 0; i < ncolumns; i++)
624 {
625 for (j = 0; j < widths[i]; j++)
626 fputs(lformat->hrule, fout);
627
628 if (i < ncolumns - 1)
629 {
630 if (border == 0)
631 fputc(' ', fout);
632 else
633 fprintf(fout, "%s%s%s", lformat->hrule,
634 lformat->midvrule, lformat->hrule);
635 }
636 }
637
638 if (border == 2)
639 fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
640 else if (border == 1)
641 fputs(lformat->hrule, fout);
642
643 fputc('\n', fout);
644}
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
int j
Definition isn.c:78
int i
Definition isn.c:77
static char format
static int fb(int x)

References fb(), format, fprintf, i, and j.

Referenced by print_aligned_text().

◆ additional_numeric_locale_len()

static int additional_numeric_locale_len ( const char my_str)
static

Definition at line 305 of file print.c.

306{
308 len = 0;
309
310 /* Account for added thousands_sep instances */
311 if (int_len > groupdigits)
313
314 /* Account for possible additional length of decimal_point */
315 if (strchr(my_str, '.') != NULL)
316 len += strlen(decimal_point) - 1;
317
318 return len;
319}
static char * thousands_sep
Definition print.c:55
static char * decimal_point
Definition print.c:53
static int integer_digits(const char *my_str)
Definition print.c:294
static int groupdigits
Definition print.c:54
const void size_t len

References decimal_point, fb(), groupdigits, integer_digits(), len, and thousands_sep.

Referenced by format_numeric_locale().

◆ asciidoc_escaped_print()

static void asciidoc_escaped_print ( const char in,
FILE fout 
)
static

Definition at line 2171 of file print.c.

2172{
2173 const char *p;
2174
2175 for (p = in; *p; p++)
2176 {
2177 switch (*p)
2178 {
2179 case '|':
2180 fputs("\\|", fout);
2181 break;
2182 default:
2183 fputc(*p, fout);
2184 }
2185 }
2186}

References fb().

Referenced by print_asciidoc_text(), and print_asciidoc_vertical().

◆ ClosePager()

void ClosePager ( FILE pagerpipe)

Definition at line 3178 of file print.c.

3179{
3180 if (pagerpipe && pagerpipe != stdout)
3181 {
3182 /*
3183 * If printing was canceled midstream, warn about it.
3184 *
3185 * Some pagers like less use Ctrl-C as part of their command set. Even
3186 * so, we abort our processing and warn the user what we did. If the
3187 * pager quit as a result of the SIGINT, this message won't go
3188 * anywhere ...
3189 */
3190 if (cancel_pressed)
3191 fprintf(pagerpipe, _("Interrupted\n"));
3192
3195 }
3196}
#define _(x)
Definition elog.c:96
void restore_sigpipe_trap(void)
Definition print.c:3065
volatile sig_atomic_t cancel_pressed
Definition print.c:48

References _, cancel_pressed, fb(), fprintf, and restore_sigpipe_trap().

Referenced by exec_command_sf_sv(), ExecQueryAndProcessResults(), helpSQL(), helpVariables(), print_aligned_text(), print_aligned_vertical(), printHistory(), printTable(), slashUsage(), and usage().

◆ column_type_alignment()

char column_type_alignment ( Oid  ftype)

Definition at line 3829 of file print.c.

3830{
3831 char align;
3832
3833 switch (ftype)
3834 {
3835 case INT2OID:
3836 case INT4OID:
3837 case INT8OID:
3838 case FLOAT4OID:
3839 case FLOAT8OID:
3840 case NUMERICOID:
3841 case OIDOID:
3842 case OID8OID:
3843 case XIDOID:
3844 case XID8OID:
3845 case CIDOID:
3846 case MONEYOID:
3847 align = 'r';
3848 break;
3849 default:
3850 align = 'l';
3851 break;
3852 }
3853 return align;
3854}

References fb().

Referenced by printCrosstab(), and printQuery().

◆ csv_escaped_print()

static void csv_escaped_print ( const char str,
FILE fout 
)
static

Definition at line 1843 of file print.c.

1844{
1845 const char *p;
1846
1847 fputc('"', fout);
1848 for (p = str; *p; p++)
1849 {
1850 if (*p == '"')
1851 fputc('"', fout); /* double quotes are doubled */
1852 fputc(*p, fout);
1853 }
1854 fputc('"', fout);
1855}
const char * str

References fb(), and str.

Referenced by csv_print_field().

◆ csv_print_field()

static void csv_print_field ( const char str,
FILE fout,
char  sep 
)
static

Definition at line 1858 of file print.c.

1859{
1860 /*----------------
1861 * Enclose and escape field contents when one of these conditions is met:
1862 * - the field separator is found in the contents.
1863 * - the field contains a CR or LF.
1864 * - the field contains a double quote.
1865 * - the field is exactly "\.".
1866 * - the field separator is either "\" or ".".
1867 * The last two cases prevent producing a line that the server's COPY
1868 * command would interpret as an end-of-data marker. We only really
1869 * need to ensure that the complete line isn't exactly "\.", but for
1870 * simplicity we apply stronger restrictions here.
1871 *----------------
1872 */
1873 if (strchr(str, sep) != NULL ||
1874 strcspn(str, "\r\n\"") != strlen(str) ||
1875 strcmp(str, "\\.") == 0 ||
1876 sep == '\\' || sep == '.')
1878 else
1879 fputs(str, fout);
1880}
static void csv_escaped_print(const char *str, FILE *fout)
Definition print.c:1843

References csv_escaped_print(), fb(), and str.

Referenced by print_csv_text(), and print_csv_vertical().

◆ disable_sigpipe_trap()

void disable_sigpipe_trap ( void  )

Definition at line 3042 of file print.c.

3043{
3044#ifndef WIN32
3046#endif
3047}
#define pqsignal
Definition port.h:548
#define PG_SIG_IGN
Definition port.h:552
#define SIGPIPE
Definition win32_port.h:163

References PG_SIG_IGN, pqsignal, and SIGPIPE.

Referenced by do_copy(), do_watch(), exec_command_write(), PageOutputInternal(), and SetupGOutput().

◆ footers_with_default()

static printTableFooter * footers_with_default ( const printTableContent cont)
static

Definition at line 414 of file print.c.

415{
416 if (cont->footers == NULL && cont->opt->default_footer)
417 {
418 unsigned long total_records;
419
420 total_records = cont->opt->prior_records + cont->nrows;
422 ngettext("(%lu row)", "(%lu rows)", total_records),
424
425 return &default_footer_cell;
426 }
427 else
428 return cont->footers;
429}
#define ngettext(s, p, n)
Definition c.h:1310
static char default_footer[100]
Definition print.c:57
static printTableFooter default_footer_cell
Definition print.c:58
#define snprintf
Definition port.h:261

References default_footer, default_footer_cell, fb(), ngettext, and snprintf.

Referenced by print_aligned_text(), print_aligned_vertical(), print_asciidoc_text(), print_html_text(), print_latex_text(), print_troff_ms_text(), and print_unaligned_text().

◆ format_numeric_locale()

static char * format_numeric_locale ( const char my_str)
static

Definition at line 330 of file print.c.

331{
332 char *new_str;
333 int new_len,
334 int_len,
336 i,
338
339 /*
340 * If the string doesn't look like a number, return it unchanged. This
341 * check is essential to avoid mangling already-localized "money" values.
342 */
343 if (strspn(my_str, "0123456789+-.eE") != strlen(my_str))
344 return pg_strdup(my_str);
345
347 new_str = pg_malloc_array(char, (new_len + 1));
348 new_str_pos = 0;
350
351 /* number of digits in first thousands group */
353 if (leading_digits == 0)
355
356 /* process sign */
357 if (my_str[0] == '-' || my_str[0] == '+')
358 {
359 new_str[new_str_pos++] = my_str[0];
360 my_str++;
361 }
362
363 /* process integer part of number */
364 for (i = 0; i < int_len; i++)
365 {
366 /* Time to insert separator? */
367 if (i > 0 && --leading_digits == 0)
368 {
372 }
374 }
375
376 /* handle decimal point if any */
377 if (my_str[i] == '.')
378 {
381 i++;
382 }
383
384 /* copy the rest (fractional digits and/or exponent, and \0 terminator) */
386
387 /* assert we didn't underestimate new_len (an overestimate is OK) */
389
390 return new_str;
391}
#define Assert(condition)
Definition c.h:1002
char * pg_strdup(const char *in)
Definition fe_memutils.c:91
#define pg_malloc_array(type, count)
Definition fe_memutils.h:66
static int additional_numeric_locale_len(const char *my_str)
Definition print.c:305

References additional_numeric_locale_len(), Assert, decimal_point, fb(), groupdigits, i, integer_digits(), pg_malloc_array, pg_strdup(), and thousands_sep.

Referenced by printQuery().

◆ get_line_style()

const printTextFormat * get_line_style ( const printTableOpt opt)

Definition at line 3893 of file print.c.

3894{
3895 /*
3896 * Note: this function mainly exists to preserve the convention that a
3897 * printTableOpt struct can be initialized to zeroes to get default
3898 * behavior.
3899 */
3900 if (opt->line_style != NULL)
3901 return opt->line_style;
3902 else
3903 return &pg_asciiformat;
3904}
const printTextFormat pg_asciiformat
Definition print.c:61
const printTextFormat * line_style
Definition print.h:131

References fb(), printTableOpt::line_style, and pg_asciiformat.

Referenced by print_aligned_text(), print_aligned_vertical(), print_aligned_vertical_line(), printPsetInfo(), and pset_value_string().

◆ html_escaped_print()

void html_escaped_print ( const char in,
FILE fout 
)

Definition at line 1955 of file print.c.

1956{
1957 const char *p;
1958 bool leading_space = true;
1959
1960 for (p = in; *p; p++)
1961 {
1962 switch (*p)
1963 {
1964 case '&':
1965 fputs("&amp;", fout);
1966 break;
1967 case '<':
1968 fputs("&lt;", fout);
1969 break;
1970 case '>':
1971 fputs("&gt;", fout);
1972 break;
1973 case '\n':
1974 fputs("<br />\n", fout);
1975 break;
1976 case '"':
1977 fputs("&quot;", fout);
1978 break;
1979 case ' ':
1980 /* protect leading space, for EXPLAIN output */
1981 if (leading_space)
1982 fputs("&nbsp;", fout);
1983 else
1984 fputs(" ", fout);
1985 break;
1986 default:
1987 fputc(*p, fout);
1988 }
1989 if (*p != ' ')
1990 leading_space = false;
1991 }
1992}

References fb().

Referenced by print_html_text(), print_html_vertical(), and PrintQueryStatus().

◆ integer_digits()

static int integer_digits ( const char my_str)
static

Definition at line 294 of file print.c.

295{
296 /* ignoring any sign ... */
297 if (my_str[0] == '-' || my_str[0] == '+')
298 my_str++;
299 /* ... count initial integral digits */
300 return strspn(my_str, "0123456789");
301}

References fb().

Referenced by additional_numeric_locale_len(), and format_numeric_locale().

◆ IsPagerNeeded()

static void IsPagerNeeded ( const printTableContent cont,
const unsigned int width_wrap,
bool  vertical,
FILE **  fout,
bool is_pager 
)
static

Definition at line 3448 of file print.c.

3451{
3452 if (*fout == stdout)
3453 {
3454 *fout = PageOutputInternal(0, cont->opt, cont, width_wrap, vertical);
3455 *is_pager = (*fout != stdout);
3456 }
3457 else
3458 *is_pager = false;
3459}
static FILE * PageOutputInternal(int lines, const printTableOpt *topt, const printTableContent *cont, const unsigned int *width_wrap, bool vertical)
Definition print.c:3108

References fb(), and PageOutputInternal().

Referenced by print_aligned_text(), print_aligned_vertical(), and printTable().

◆ latex_escaped_print()

static void latex_escaped_print ( const char in,
FILE fout 
)
static

Definition at line 2395 of file print.c.

2396{
2397 const char *p;
2398
2399 for (p = in; *p; p++)
2400 switch (*p)
2401 {
2402 /*
2403 * We convert ASCII characters per the recommendations in
2404 * Scott Pakin's "The Comprehensive LATEX Symbol List",
2405 * available from CTAN. For non-ASCII, you're on your own.
2406 */
2407 case '#':
2408 fputs("\\#", fout);
2409 break;
2410 case '$':
2411 fputs("\\$", fout);
2412 break;
2413 case '%':
2414 fputs("\\%", fout);
2415 break;
2416 case '&':
2417 fputs("\\&", fout);
2418 break;
2419 case '<':
2420 fputs("\\textless{}", fout);
2421 break;
2422 case '>':
2423 fputs("\\textgreater{}", fout);
2424 break;
2425 case '\\':
2426 fputs("\\textbackslash{}", fout);
2427 break;
2428 case '^':
2429 fputs("\\^{}", fout);
2430 break;
2431 case '_':
2432 fputs("\\_", fout);
2433 break;
2434 case '{':
2435 fputs("\\{", fout);
2436 break;
2437 case '|':
2438 fputs("\\textbar{}", fout);
2439 break;
2440 case '}':
2441 fputs("\\}", fout);
2442 break;
2443 case '~':
2444 fputs("\\~{}", fout);
2445 break;
2446 case '\n':
2447 /* This is not right, but doing it right seems too hard */
2448 fputs("\\\\", fout);
2449 break;
2450 default:
2451 fputc(*p, fout);
2452 }
2453}

References fb().

Referenced by print_latex_longtable_text(), print_latex_text(), and print_latex_vertical().

◆ PageOutput()

FILE * PageOutput ( int  lines,
const printTableOpt topt 
)

Definition at line 3096 of file print.c.

3097{
3098 return PageOutputInternal(lines, topt, NULL, NULL, false);
3099}

References fb(), and PageOutputInternal().

Referenced by exec_command_sf_sv(), ExecQueryAndProcessResults(), helpSQL(), helpVariables(), print_aligned_text(), printHistory(), slashUsage(), and usage().

◆ PageOutputInternal()

static FILE * PageOutputInternal ( int  lines,
const printTableOpt topt,
const printTableContent cont,
const unsigned int width_wrap,
bool  vertical 
)
static

Definition at line 3108 of file print.c.

3112{
3113 /* check whether we need / can / are supposed to use pager */
3114 if (topt && topt->pager && isatty(fileno(stdin)) && isatty(fileno(stdout)))
3115 {
3116 /* without TIOCGWINSZ, pager == 1 acts the same as pager > 1 */
3117#ifdef TIOCGWINSZ
3118 unsigned short int pager = topt->pager;
3119 int min_lines = topt->pager_min_lines;
3120
3121 if (pager == 1)
3122 {
3123 int result;
3124 struct winsize screen_size;
3125
3126 result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size);
3127 if (result < 0)
3128 pager = 2; /* force use of pager */
3129 else
3130 {
3131 int threshold = Max(screen_size.ws_row, min_lines);
3132
3133 if (cont) /* caller wants us to calculate lines */
3134 lines = count_table_lines(cont, width_wrap, vertical,
3135 threshold);
3136 /* >= accounts for a one-line prompt */
3137 if (lines >= threshold)
3138 pager = 2;
3139 }
3140 }
3141
3142 if (pager > 1)
3143#endif
3144 {
3145 const char *pagerprog;
3146 FILE *pagerpipe;
3147
3148 pagerprog = getenv("PSQL_PAGER");
3149 if (!pagerprog)
3150 pagerprog = getenv("PAGER");
3151 if (!pagerprog)
3153 else
3154 {
3155 /* if PAGER is empty or all-white-space, don't use pager */
3156 if (strspn(pagerprog, " \t\r\n") == strlen(pagerprog))
3157 return stdout;
3158 }
3159 fflush(NULL);
3161 pagerpipe = popen(pagerprog, "w");
3162 if (pagerpipe)
3163 return pagerpipe;
3164 /* if popen fails, silently proceed without pager */
3166 }
3167 }
3168
3169 return stdout;
3170}
#define Max(x, y)
Definition c.h:1125
uint32 result
void disable_sigpipe_trap(void)
Definition print.c:3042
#define DEFAULT_PAGER
Definition print.h:23
int pager_min_lines
Definition print.h:124
unsigned short int pager
Definition print.h:122

References DEFAULT_PAGER, disable_sigpipe_trap(), fb(), Max, printTableOpt::pager, printTableOpt::pager_min_lines, restore_sigpipe_trap(), and result.

Referenced by IsPagerNeeded(), and PageOutput().

◆ print_aligned_text()

static void print_aligned_text ( const printTableContent cont,
FILE fout,
bool  is_pager 
)
static

Definition at line 651 of file print.c.

652{
653 bool opt_tuples_only = cont->opt->tuples_only;
654 int encoding = cont->opt->encoding;
655 unsigned short opt_border = cont->opt->border;
658
659 unsigned int col_count = 0,
660 cell_count = 0;
661
662 unsigned int i,
663 j;
664
665 unsigned int *width_header,
666 *max_width,
667 *width_wrap,
669 unsigned int *max_nl_lines, /* value split by newlines */
671 *max_bytes;
672 unsigned char **format_buf;
673 unsigned int width_total;
674 unsigned int total_header_width;
675
676 const char *const *ptr;
677
678 struct lineptr **col_lineptrs; /* pointers to line pointer per column */
679
680 bool *header_done; /* Have all header lines been output? */
681 int *bytes_output; /* Bytes output for column value */
682 printTextLineWrap *wrap; /* Wrap status for each column */
683 int output_columns = 0; /* Width of interactive console */
684 bool is_local_pager = false;
685
686 if (cancel_pressed)
687 return;
688
689 if (opt_border > 2)
690 opt_border = 2;
691
692 if (cont->ncolumns > 0)
693 {
694 col_count = cont->ncolumns;
695 width_header = pg_malloc0_array(unsigned int, col_count);
697 max_width = pg_malloc0_array(unsigned int, col_count);
698 width_wrap = pg_malloc0_array(unsigned int, col_count);
699 max_nl_lines = pg_malloc0_array(unsigned int, col_count);
700 curr_nl_line = pg_malloc0_array(unsigned int, col_count);
702 max_bytes = pg_malloc0_array(unsigned int, col_count);
703 format_buf = pg_malloc0_array(unsigned char *, col_count);
707 }
708 else
709 {
712 max_width = NULL;
717 max_bytes = NULL;
721 wrap = NULL;
722 }
723
724 /* scan all column headers, find maximum width and max max_nl_lines */
725 for (i = 0; i < col_count; i++)
726 {
727 int width,
728 nl_lines,
730
731 pg_wcssize((const unsigned char *) cont->headers[i], strlen(cont->headers[i]),
733 if (width > max_width[i])
734 max_width[i] = width;
735 if (nl_lines > max_nl_lines[i])
737 if (bytes_required > max_bytes[i])
738 max_bytes[i] = bytes_required;
739
741 }
742
743 /* scan all cells, find maximum width, compute cell_count */
744 for (i = 0, ptr = cont->cells; *ptr; ptr++, cell_count++)
745 {
746 int width,
747 nl_lines,
749
750 pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding,
752
753 if (width > max_width[i])
754 max_width[i] = width;
755 if (nl_lines > max_nl_lines[i])
757 if (bytes_required > max_bytes[i])
758 max_bytes[i] = bytes_required;
759
761
762 /* i is the current column number: increment with wrap */
763 if (++i >= col_count)
764 i = 0;
765 }
766
767 /* If we have rows, compute average */
768 if (col_count != 0 && cell_count != 0)
769 {
770 int rows = cell_count / col_count;
771
772 for (i = 0; i < col_count; i++)
773 width_average[i] /= rows;
774 }
775
776 /* adjust the total display width based on border style */
777 if (opt_border == 0)
779 else if (opt_border == 1)
780 width_total = col_count * 3 - ((col_count > 0) ? 1 : 0);
781 else
782 width_total = col_count * 3 + 1;
784
785 for (i = 0; i < col_count; i++)
786 {
789 }
790
791 /*
792 * At this point: max_width[] contains the max width of each column,
793 * max_nl_lines[] contains the max number of lines in each column,
794 * max_bytes[] contains the maximum storage space for formatting strings,
795 * width_total contains the giant width sum. Now we allocate some memory
796 * for line pointers.
797 */
798 for (i = 0; i < col_count; i++)
799 {
800 /* Add entry for ptr == NULL array termination */
802 (max_nl_lines[i] + 1));
803
804 format_buf[i] = pg_malloc_array(unsigned char, (max_bytes[i] + 1));
805
806 col_lineptrs[i]->ptr = format_buf[i];
807 }
808
809 /* Default word wrap to the full width, i.e. no word wrap */
810 for (i = 0; i < col_count; i++)
812
813 /*
814 * Choose target output width: \pset columns, or $COLUMNS, or ioctl
815 */
816 if (cont->opt->columns > 0)
817 output_columns = cont->opt->columns;
818 else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
819 {
820 if (cont->opt->env_columns > 0)
821 output_columns = cont->opt->env_columns;
822#ifdef TIOCGWINSZ
823 else
824 {
825 struct winsize screen_size;
826
827 if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1)
829 }
830#endif
831 }
832
833 if (cont->opt->format == PRINT_WRAPPED)
834 {
835 /*
836 * Optional optimized word wrap. Shrink columns with a high max/avg
837 * ratio. Slightly bias against wider columns. (Increases chance a
838 * narrow column will fit in its cell.) If available columns is
839 * positive... and greater than the width of the unshrinkable column
840 * headers
841 */
843 {
844 /* While there is still excess width... */
846 {
847 double max_ratio = 0;
848 int worst_col = -1;
849
850 /*
851 * Find column that has the highest ratio of its maximum width
852 * compared to its average width. This tells us which column
853 * will produce the fewest wrapped values if shortened.
854 * width_wrap starts as equal to max_width.
855 */
856 for (i = 0; i < col_count; i++)
857 {
859 {
860 /* Penalize wide columns by 1% of their width */
861 double ratio;
862
863 ratio = (double) width_wrap[i] / width_average[i] +
864 max_width[i] * 0.01;
865 if (ratio > max_ratio)
866 {
867 max_ratio = ratio;
868 worst_col = i;
869 }
870 }
871 }
872
873 /* Exit loop if we can't squeeze any more. */
874 if (worst_col == -1)
875 break;
876
877 /* Decrease width of target column by one. */
879 width_total--;
880 }
881 }
882 }
883
884 /*
885 * If in expanded auto mode, we have now calculated the expected width, so
886 * we can now escape to vertical mode if necessary. If the output has
887 * only one column, the expanded format would be wider than the regular
888 * format, so don't use it in that case.
889 */
890 if (cont->opt->expanded == 2 && output_columns > 0 && cont->ncolumns > 1 &&
892 {
894 goto cleanup;
895 }
896
897 /* If we wrapped beyond the display width, use the pager */
898 if (!is_pager && fout == stdout && output_columns > 0 &&
900 {
901 fout = PageOutput(INT_MAX, cont->opt); /* force pager */
902 is_pager = is_local_pager = true;
903 }
904
905 /* Check if there are enough lines to require the pager */
906 if (!is_pager)
907 {
910 }
911
912 /* time to output */
913 if (cont->opt->start_table)
914 {
915 /* print title */
916 if (cont->title && !opt_tuples_only)
917 {
918 int width,
919 height;
920
921 pg_wcssize((const unsigned char *) cont->title, strlen(cont->title),
922 encoding, &width, &height, NULL);
923 if (width >= width_total)
924 /* Aligned */
925 fprintf(fout, "%s\n", cont->title);
926 else
927 /* Centered */
928 fprintf(fout, "%-*s%s\n", (width_total - width) / 2, "",
929 cont->title);
930 }
931
932 /* print headers */
933 if (!opt_tuples_only)
934 {
936 int curr_nl_line;
937
938 if (opt_border == 2)
941
942 for (i = 0; i < col_count; i++)
943 pg_wcsformat((const unsigned char *) cont->headers[i],
944 strlen(cont->headers[i]), encoding,
946
948 curr_nl_line = 0;
949 if (col_count > 0)
950 memset(header_done, false, col_count * sizeof(bool));
951 while (more_col_wrapping)
952 {
953 if (opt_border == 2)
954 fputs(dformat->leftvrule, fout);
955
956 for (i = 0; i < cont->ncolumns; i++)
957 {
959 unsigned int nbspace;
960
961 if (opt_border != 0 ||
962 (!format->wrap_right_border && i > 0))
963 fputs(curr_nl_line ? format->header_nl_left : " ",
964 fout);
965
966 if (!header_done[i])
967 {
969
970 /* centered */
971 fprintf(fout, "%-*s%s%-*s",
972 nbspace / 2, "", this_line->ptr, (nbspace + 1) / 2, "");
973
974 if (!(this_line + 1)->ptr)
975 {
977 header_done[i] = 1;
978 }
979 }
980 else
981 fprintf(fout, "%*s", width_wrap[i], "");
982
983 if (opt_border != 0 || format->wrap_right_border)
984 fputs(!header_done[i] ? format->header_nl_right : " ",
985 fout);
986
987 if (opt_border != 0 && col_count > 0 && i < col_count - 1)
988 fputs(dformat->midvrule, fout);
989 }
990 curr_nl_line++;
991
992 if (opt_border == 2)
993 fputs(dformat->rightvrule, fout);
994 fputc('\n', fout);
995 }
996
999 }
1000 }
1001
1002 /* print cells, one loop per row */
1003 for (i = 0, ptr = cont->cells; *ptr; i += col_count, ptr += col_count)
1004 {
1005 bool more_lines;
1006
1007 if (cancel_pressed)
1008 break;
1009
1010 /*
1011 * Format each cell.
1012 */
1013 for (j = 0; j < col_count; j++)
1014 {
1015 pg_wcsformat((const unsigned char *) ptr[j], strlen(ptr[j]), encoding,
1017 curr_nl_line[j] = 0;
1018 }
1019
1020 memset(bytes_output, 0, col_count * sizeof(int));
1021
1022 /*
1023 * Each time through this loop, one display line is output. It can
1024 * either be a full value or a partial value if embedded newlines
1025 * exist or if 'format=wrapping' mode is enabled.
1026 */
1027 do
1028 {
1029 more_lines = false;
1030
1031 /* left border */
1032 if (opt_border == 2)
1033 fputs(dformat->leftvrule, fout);
1034
1035 /* for each column */
1036 for (j = 0; j < col_count; j++)
1037 {
1038 /* We have a valid array element, so index it */
1040 int bytes_to_output;
1042 bool finalspaces = (opt_border == 2 ||
1043 (col_count > 0 && j < col_count - 1));
1044
1045 /* Print left-hand wrap or newline mark */
1046 if (opt_border != 0)
1047 {
1048 if (wrap[j] == PRINT_LINE_WRAP_WRAP)
1049 fputs(format->wrap_left, fout);
1050 else if (wrap[j] == PRINT_LINE_WRAP_NEWLINE)
1051 fputs(format->nl_left, fout);
1052 else
1053 fputc(' ', fout);
1054 }
1055
1056 if (!this_line->ptr)
1057 {
1058 /* Past newline lines so just pad for other columns */
1059 if (finalspaces)
1060 fprintf(fout, "%*s", chars_to_output, "");
1061 }
1062 else
1063 {
1064 /* Get strlen() of the characters up to width_wrap */
1068
1069 /*
1070 * If we exceeded width_wrap, it means the display width
1071 * of a single character was wider than our target width.
1072 * In that case, we have to pretend we are only printing
1073 * the target display width and make the best of it.
1074 */
1077
1078 if (cont->aligns[j] == 'r') /* Right aligned cell */
1079 {
1080 /* spaces first */
1081 fprintf(fout, "%*s", width_wrap[j] - chars_to_output, "");
1082 fwrite((char *) (this_line->ptr + bytes_output[j]),
1083 1, bytes_to_output, fout);
1084 }
1085 else /* Left aligned cell */
1086 {
1087 /* spaces second */
1088 fwrite((char *) (this_line->ptr + bytes_output[j]),
1089 1, bytes_to_output, fout);
1090 }
1091
1093
1094 /* Do we have more text to wrap? */
1095 if (*(this_line->ptr + bytes_output[j]) != '\0')
1096 more_lines = true;
1097 else
1098 {
1099 /* Advance to next newline line */
1100 curr_nl_line[j]++;
1101 if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
1102 more_lines = true;
1103 bytes_output[j] = 0;
1104 }
1105 }
1106
1107 /* Determine next line's wrap status for this column */
1109 if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
1110 {
1111 if (bytes_output[j] != 0)
1113 else if (curr_nl_line[j] != 0)
1115 }
1116
1117 /*
1118 * If left-aligned, pad out remaining space if needed (not
1119 * last column, and/or wrap marks required).
1120 */
1121 if (cont->aligns[j] != 'r') /* Left aligned cell */
1122 {
1123 if (finalspaces ||
1126 fprintf(fout, "%*s",
1128 }
1129
1130 /* Print right-hand wrap or newline mark */
1131 if (wrap[j] == PRINT_LINE_WRAP_WRAP)
1132 fputs(format->wrap_right, fout);
1133 else if (wrap[j] == PRINT_LINE_WRAP_NEWLINE)
1134 fputs(format->nl_right, fout);
1135 else if (opt_border == 2 || (col_count > 0 && j < col_count - 1))
1136 fputc(' ', fout);
1137
1138 /* Print column divider, if not the last column */
1139 if (opt_border != 0 && (col_count > 0 && j < col_count - 1))
1140 {
1141 if (wrap[j + 1] == PRINT_LINE_WRAP_WRAP)
1142 fputs(format->midvrule_wrap, fout);
1143 else if (wrap[j + 1] == PRINT_LINE_WRAP_NEWLINE)
1144 fputs(format->midvrule_nl, fout);
1145 else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL)
1146 fputs(format->midvrule_blank, fout);
1147 else
1148 fputs(dformat->midvrule, fout);
1149 }
1150 }
1151
1152 /* end-of-row border */
1153 if (opt_border == 2)
1154 fputs(dformat->rightvrule, fout);
1155 fputc('\n', fout);
1156 } while (more_lines);
1157 }
1158
1159 if (cont->opt->stop_table)
1160 {
1162
1163 if (opt_border == 2 && !cancel_pressed)
1166
1167 /* print footers */
1168 if (footers && !opt_tuples_only && !cancel_pressed)
1169 {
1171
1172 for (f = footers; f; f = f->next)
1173 fprintf(fout, "%s\n", f->data);
1174 }
1175
1176 fputc('\n', fout);
1177 }
1178
1179cleanup:
1180 /* clean up */
1181 for (i = 0; i < col_count; i++)
1182 {
1185 }
1193 pg_free(max_bytes);
1197 pg_free(wrap);
1198
1199 if (is_local_pager)
1201}
static void cleanup(void)
Definition bootstrap.c:886
void pg_free(void *ptr)
#define pg_malloc0_array(type, count)
Definition fe_memutils.h:67
const printTextFormat * get_line_style(const printTableOpt *opt)
Definition print.c:3893
static printTableFooter * footers_with_default(const printTableContent *cont)
Definition print.c:414
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition print.c:3096
static void IsPagerNeeded(const printTableContent *cont, const unsigned int *width_wrap, bool vertical, FILE **fout, bool *is_pager)
Definition print.c:3448
void ClosePager(FILE *pagerpipe)
Definition print.c:3178
static int strlen_max_width(unsigned char *str, int *target_width, int encoding)
Definition print.c:3962
static void print_aligned_vertical(const printTableContent *cont, FILE *fout, bool is_pager)
Definition print.c:1304
static void _print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths, unsigned short border, printTextRule pos, const printTextFormat *format, FILE *fout)
Definition print.c:609
@ PRINT_RULE_MIDDLE
Definition print.h:56
@ PRINT_RULE_BOTTOM
Definition print.h:57
@ PRINT_RULE_DATA
Definition print.h:58
@ PRINT_RULE_TOP
Definition print.h:55
printTextLineWrap
Definition print.h:62
@ PRINT_LINE_WRAP_WRAP
Definition print.h:65
@ PRINT_LINE_WRAP_NEWLINE
Definition print.h:66
@ PRINT_LINE_WRAP_NONE
Definition print.h:64
@ PRINT_WRAPPED
Definition print.h:39
static char * encoding
Definition initdb.c:139
void pg_wcssize(const unsigned char *pwcs, size_t len, int encoding, int *result_width, int *result_height, int *result_format_size)
Definition mbprint.c:211
void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, struct lineptr *lines, int count)
Definition mbprint.c:294
int width
Definition mbprint.h:19
unsigned char * ptr
Definition mbprint.h:18
char * data
Definition print.h:155
struct printTableFooter * next
Definition print.h:156

References _print_horizontal_line(), cancel_pressed, cleanup(), ClosePager(), printTableFooter::data, encoding, fb(), footers_with_default(), format, fprintf, get_line_style(), i, IsPagerNeeded(), j, printTableFooter::next, PageOutput(), pg_free(), pg_malloc0_array, pg_malloc_array, pg_wcsformat(), pg_wcssize(), print_aligned_vertical(), PRINT_LINE_WRAP_NEWLINE, PRINT_LINE_WRAP_NONE, PRINT_LINE_WRAP_WRAP, PRINT_RULE_BOTTOM, PRINT_RULE_DATA, PRINT_RULE_MIDDLE, PRINT_RULE_TOP, PRINT_WRAPPED, lineptr::ptr, strlen_max_width(), and lineptr::width.

Referenced by printTable().

◆ print_aligned_vertical()

static void print_aligned_vertical ( const printTableContent cont,
FILE fout,
bool  is_pager 
)
static

Definition at line 1304 of file print.c.

1306{
1307 bool opt_tuples_only = cont->opt->tuples_only;
1308 unsigned short opt_border = cont->opt->border;
1311 int encoding = cont->opt->encoding;
1312 unsigned long record = cont->opt->prior_records + 1;
1313 const char *const *ptr;
1314 unsigned int i,
1315 hwidth = 0,
1316 dwidth = 0,
1317 hheight = 1,
1318 dheight = 1,
1319 hformatsize = 0,
1320 dformatsize = 0;
1321 struct lineptr *hlineptr,
1322 *dlineptr;
1323 bool is_local_pager = false,
1324 hmultiline = false,
1325 dmultiline = false;
1326 int output_columns = 0; /* Width of interactive console */
1327
1328 if (cancel_pressed)
1329 return;
1330
1331 if (opt_border > 2)
1332 opt_border = 2;
1333
1334 /*
1335 * Kluge for totally empty table: use the default footer even though
1336 * vertical modes normally don't. Otherwise we'd print nothing at all,
1337 * which isn't terribly friendly. Assume pager will not be needed.
1338 */
1339 if (cont->cells[0] == NULL && cont->opt->start_table &&
1340 cont->opt->stop_table)
1341 {
1343
1344 if (!opt_tuples_only && !cancel_pressed && footers)
1345 {
1347
1348 for (f = footers; f; f = f->next)
1349 fprintf(fout, "%s\n", f->data);
1350 }
1351
1352 fputc('\n', fout);
1353
1354 return;
1355 }
1356
1357 /* Find the maximum dimensions for the headers */
1358 for (i = 0; i < cont->ncolumns; i++)
1359 {
1360 int width,
1361 height,
1362 fs;
1363
1364 pg_wcssize((const unsigned char *) cont->headers[i], strlen(cont->headers[i]),
1365 encoding, &width, &height, &fs);
1366 if (width > hwidth)
1367 hwidth = width;
1368 if (height > hheight)
1369 {
1370 hheight = height;
1371 hmultiline = true;
1372 }
1373 if (fs > hformatsize)
1374 hformatsize = fs;
1375 }
1376
1377 /* find longest data cell */
1378 for (ptr = cont->cells; *ptr; ptr++)
1379 {
1380 int width,
1381 height,
1382 fs;
1383
1384 pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding,
1385 &width, &height, &fs);
1386 if (width > dwidth)
1387 dwidth = width;
1388 if (height > dheight)
1389 {
1390 dheight = height;
1391 dmultiline = true;
1392 }
1393 if (fs > dformatsize)
1394 dformatsize = fs;
1395 }
1396
1397 /*
1398 * We now have all the information we need to setup the formatting
1399 * structures
1400 */
1401 dlineptr = pg_malloc_array(struct lineptr, (dheight + 1));
1402 hlineptr = pg_malloc_array(struct lineptr, (hheight + 1));
1403
1406
1407 /*
1408 * Choose target output width: \pset columns, or $COLUMNS, or ioctl
1409 */
1410 if (cont->opt->columns > 0)
1411 output_columns = cont->opt->columns;
1412 else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
1413 {
1414 if (cont->opt->env_columns > 0)
1415 output_columns = cont->opt->env_columns;
1416#ifdef TIOCGWINSZ
1417 else
1418 {
1419 struct winsize screen_size;
1420
1421 if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1)
1422 output_columns = screen_size.ws_col;
1423 }
1424#endif
1425 }
1426
1427 /*
1428 * Determine data column width: fit output width in wrapped mode, or
1429 * ensure alignment with the record header line in aligned mode.
1430 */
1431 if (cont->opt->format == PRINT_WRAPPED || cont->opt->format == PRINT_ALIGNED)
1432 {
1433 unsigned int swidth,
1434 rwidth = 0,
1435 newdwidth;
1436
1437 if (opt_border == 0)
1438 {
1439 /*
1440 * For border = 0, one space in the middle. (If we discover we
1441 * need to wrap, the spacer column will be replaced by a wrap
1442 * marker, and we'll make room below for another wrap marker at
1443 * the end of the line. But for now, assume no wrap is needed.)
1444 */
1445 swidth = 1;
1446
1447 /* We might need a column for header newline markers, too */
1448 if (hmultiline)
1449 swidth++;
1450 }
1451 else if (opt_border == 1)
1452 {
1453 /*
1454 * For border = 1, two spaces and a vrule in the middle. (As
1455 * above, we might need one more column for a wrap marker.)
1456 */
1457 swidth = 3;
1458
1459 /* We might need a column for left header newline markers, too */
1461 swidth++;
1462 }
1463 else
1464 {
1465 /*
1466 * For border = 2, two more for the vrules at the beginning and
1467 * end of the lines, plus spacer columns adjacent to these. (We
1468 * won't need extra columns for wrap/newline markers, we'll just
1469 * repurpose the spacers.)
1470 */
1471 swidth = 7;
1472 }
1473
1474 /* Reserve a column for data newline indicators, too, if needed */
1475 if (dmultiline &&
1477 swidth++;
1478
1479 /* Determine width required for record header lines */
1480 if (!opt_tuples_only)
1481 {
1482 if (cont->nrows > 0)
1483 rwidth = 1 + (int) log10(cont->nrows);
1484 if (opt_border == 0)
1485 rwidth += 9; /* "* RECORD " */
1486 else if (opt_border == 1)
1487 rwidth += 12; /* "-[ RECORD ]" */
1488 else
1489 rwidth += 15; /* "+-[ RECORD ]-+" */
1490 }
1491
1492 /* We might need to do the rest of the calculation twice */
1493 for (;;)
1494 {
1495 unsigned int width;
1496
1497 /* Total width required to not wrap data */
1498 width = hwidth + swidth + dwidth;
1499 /* ... and not the header lines, either */
1500 if (width < rwidth)
1501 width = rwidth;
1502
1503 if (cont->opt->format == PRINT_WRAPPED && output_columns > 0)
1504 {
1505 unsigned int min_width;
1506
1507 /* Minimum acceptable width: room for just 3 columns of data */
1508 min_width = hwidth + swidth + 3;
1509 /* ... but not less than what the record header lines need */
1510 if (min_width < rwidth)
1511 min_width = rwidth;
1512
1513 if (output_columns >= width)
1514 {
1515 /* Plenty of room, use native data width */
1516 /* (but at least enough for the record header lines) */
1517 newdwidth = width - hwidth - swidth;
1518 }
1519 else if (output_columns < min_width)
1520 {
1521 /* Set data width to match min_width */
1523 }
1524 else
1525 {
1526 /* Set data width to match output_columns */
1528 }
1529 }
1530 else
1531 {
1532 /* Don't know the wrap limit, so use native data width */
1533 /* (but at least enough for the record header lines) */
1534 newdwidth = width - hwidth - swidth;
1535 }
1536
1537 /*
1538 * If we will need to wrap data and didn't already allocate a data
1539 * newline/wrap marker column, do so and recompute.
1540 */
1541 if (newdwidth < dwidth && !dmultiline &&
1543 {
1544 dmultiline = true;
1545 swidth++;
1546 }
1547 else
1548 break;
1549 }
1550
1551 dwidth = newdwidth;
1552 }
1553
1554 /*
1555 * Deal with the pager here instead of in printTable(), because we could
1556 * get here via print_aligned_text() in expanded auto mode, and so we have
1557 * to recalculate the pager requirement based on vertical output.
1558 */
1559 if (!is_pager)
1560 {
1561 unsigned int *width_wrap = NULL;
1562
1563 /*
1564 * Wrapping can add extra output lines, which count_table_lines() can
1565 * only account for if it has wrap widths. But vertical output uses
1566 * the same data width for every field, so that's easy: use dwidth for
1567 * every column.
1568 */
1569 if (cont->opt->format == PRINT_WRAPPED && cont->ncolumns > 0)
1570 {
1571 width_wrap = pg_malloc_array(unsigned int, cont->ncolumns);
1572 for (int j = 0; j < cont->ncolumns; j++)
1573 width_wrap[j] = dwidth;
1574 }
1575
1578
1580 }
1581
1582 if (cont->opt->start_table)
1583 {
1584 /* print title */
1585 if (!opt_tuples_only && cont->title)
1586 fprintf(fout, "%s\n", cont->title);
1587 }
1588
1589 /* print records */
1590 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1591 {
1592 printTextRule pos;
1593 int dline,
1594 hline,
1595 dcomplete,
1596 hcomplete,
1597 offset,
1599
1600 if (cancel_pressed)
1601 break;
1602
1603 if (i == 0)
1604 pos = PRINT_RULE_TOP;
1605 else
1606 pos = PRINT_RULE_MIDDLE;
1607
1608 /* Print record header (e.g. "[ RECORD N ]") above each record */
1609 if (i % cont->ncolumns == 0)
1610 {
1611 unsigned int lhwidth = hwidth;
1612
1613 if ((opt_border < 2) &&
1614 (hmultiline) &&
1616 lhwidth++; /* for newline indicators */
1617
1618 if (!opt_tuples_only)
1619 print_aligned_vertical_line(cont->opt, record++,
1621 pos, fout);
1622 else if (i != 0 || !cont->opt->start_table || opt_border == 2)
1624 dwidth, output_columns, pos, fout);
1625 }
1626
1627 /* Format the header */
1628 pg_wcsformat((const unsigned char *) cont->headers[i % cont->ncolumns],
1629 strlen(cont->headers[i % cont->ncolumns]),
1631 /* Format the data */
1632 pg_wcsformat((const unsigned char *) *ptr, strlen(*ptr), encoding,
1633 dlineptr, dheight);
1634
1635 /*
1636 * Loop through header and data in parallel dealing with newlines and
1637 * wrapped lines until they're both exhausted
1638 */
1639 dline = hline = 0;
1640 dcomplete = hcomplete = 0;
1641 offset = 0;
1643 while (!dcomplete || !hcomplete)
1644 {
1645 /* Left border */
1646 if (opt_border == 2)
1647 fprintf(fout, "%s", dformat->leftvrule);
1648
1649 /* Header (never wrapped so just need to deal with newlines) */
1650 if (!hcomplete)
1651 {
1652 int swidth = hwidth,
1654
1655 /*
1656 * Left spacer or new line indicator
1657 */
1658 if ((opt_border == 2) ||
1660 fputs(hline ? format->header_nl_left : " ", fout);
1661
1662 /*
1663 * Header text
1664 */
1666 encoding);
1667 fprintf(fout, "%-s", hlineptr[hline].ptr);
1668
1669 /*
1670 * Spacer
1671 */
1673 if (swidth > 0)
1674 fprintf(fout, "%*s", swidth, " ");
1675
1676 /*
1677 * New line indicator or separator's space
1678 */
1679 if (hlineptr[hline + 1].ptr)
1680 {
1681 /* More lines after this one due to a newline */
1682 if ((opt_border > 0) ||
1684 fputs(format->header_nl_right, fout);
1685 hline++;
1686 }
1687 else
1688 {
1689 /* This was the last line of the header */
1690 if ((opt_border > 0) ||
1692 fputs(" ", fout);
1693 hcomplete = 1;
1694 }
1695 }
1696 else
1697 {
1698 unsigned int swidth = hwidth + opt_border;
1699
1700 if ((opt_border < 2) &&
1701 (hmultiline) &&
1703 swidth++;
1704
1705 if ((opt_border == 0) &&
1706 (format != &pg_asciiformat_old) &&
1707 (hmultiline))
1708 swidth++;
1709
1710 fprintf(fout, "%*s", swidth, " ");
1711 }
1712
1713 /* Separator */
1714 if (opt_border > 0)
1715 {
1716 if (offset)
1717 fputs(format->midvrule_wrap, fout);
1718 else if (dline == 0)
1719 fputs(dformat->midvrule, fout);
1720 else
1721 fputs(format->midvrule_nl, fout);
1722 }
1723
1724 /* Data */
1725 if (!dcomplete)
1726 {
1727 int target_width = dwidth,
1729 swidth = dwidth;
1730
1731 /*
1732 * Left spacer or wrap indicator
1733 */
1734 fputs(offset == 0 ? " " : format->wrap_left, fout);
1735
1736 /*
1737 * Data text
1738 */
1741 fwrite((char *) (dlineptr[dline].ptr + offset),
1742 1, bytes_to_output, fout);
1743
1745 offset += bytes_to_output;
1746
1747 /* Spacer */
1749
1750 if (chars_to_output)
1751 {
1752 /* continuing a wrapped column */
1753 if ((opt_border > 1) ||
1755 {
1756 if (swidth > 0)
1757 fprintf(fout, "%*s", swidth, " ");
1758 fputs(format->wrap_right, fout);
1759 }
1760 }
1761 else if (dlineptr[dline + 1].ptr)
1762 {
1763 /* reached a newline in the column */
1764 if ((opt_border > 1) ||
1766 {
1767 if (swidth > 0)
1768 fprintf(fout, "%*s", swidth, " ");
1769 fputs(format->nl_right, fout);
1770 }
1771 dline++;
1772 offset = 0;
1774 }
1775 else
1776 {
1777 /* reached the end of the cell */
1778 if (opt_border > 1)
1779 {
1780 if (swidth > 0)
1781 fprintf(fout, "%*s", swidth, " ");
1782 fputs(" ", fout);
1783 }
1784 dcomplete = 1;
1785 }
1786
1787 /* Right border */
1788 if (opt_border == 2)
1789 fputs(dformat->rightvrule, fout);
1790
1791 fputs("\n", fout);
1792 }
1793 else
1794 {
1795 /*
1796 * data exhausted (this can occur if header is longer than the
1797 * data due to newlines in the header)
1798 */
1799 if (opt_border < 2)
1800 fputs("\n", fout);
1801 else
1802 fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule);
1803 }
1804 }
1805 }
1806
1807 if (cont->opt->stop_table)
1808 {
1809 if (opt_border == 2 && !cancel_pressed)
1812
1813 /* print footers */
1814 if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
1815 {
1817
1818 if (opt_border < 2)
1819 fputc('\n', fout);
1820 for (f = cont->footers; f; f = f->next)
1821 fprintf(fout, "%s\n", f->data);
1822 }
1823
1824 fputc('\n', fout);
1825 }
1826
1827 pg_free(hlineptr->ptr);
1828 pg_free(dlineptr->ptr);
1831
1832 if (is_local_pager)
1834}
void * pg_malloc(size_t size)
Definition fe_memutils.c:53
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)
Definition print.c:1205
const printTextFormat pg_asciiformat_old
Definition print.c:82
printTextRule
Definition print.h:53
@ PRINT_ALIGNED
Definition print.h:31
#define free(a)

References cancel_pressed, ClosePager(), printTableFooter::data, encoding, fb(), footers_with_default(), format, fprintf, free, get_line_style(), i, IsPagerNeeded(), j, printTableFooter::next, pg_asciiformat_old, pg_free(), pg_malloc(), pg_malloc_array, pg_wcsformat(), pg_wcssize(), PRINT_ALIGNED, print_aligned_vertical_line(), PRINT_RULE_BOTTOM, PRINT_RULE_DATA, PRINT_RULE_MIDDLE, PRINT_RULE_TOP, PRINT_WRAPPED, lineptr::ptr, strlen_max_width(), and lineptr::width.

Referenced by print_aligned_text(), and printTable().

◆ print_aligned_vertical_line()

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 
)
static

Definition at line 1205 of file print.c.

1212{
1213 const printTextLineFormat *lformat = &get_line_style(topt)->lrule[pos];
1214 const unsigned short opt_border = topt->border;
1215 unsigned int i;
1216 int reclen = 0;
1217
1218 if (opt_border == 2)
1219 fprintf(fout, "%s%s", lformat->leftvrule, lformat->hrule);
1220 else if (opt_border == 1)
1221 fputs(lformat->hrule, fout);
1222
1223 if (record)
1224 {
1225 if (opt_border == 0)
1226 reclen = fprintf(fout, "* Record %lu", record);
1227 else
1228 reclen = fprintf(fout, "[ RECORD %lu ]", record);
1229 }
1230 if (opt_border != 2)
1231 reclen++;
1232 if (reclen < 0)
1233 reclen = 0;
1234 for (i = reclen; i < hwidth; i++)
1235 fputs(opt_border > 0 ? lformat->hrule : " ", fout);
1236 reclen -= hwidth;
1237
1238 if (opt_border > 0)
1239 {
1240 if (reclen-- <= 0)
1241 fputs(lformat->hrule, fout);
1242 if (reclen-- <= 0)
1243 {
1245 {
1246 fputs(lformat->rightvrule, fout);
1247 }
1248 else
1249 {
1250 fputs(lformat->midvrule, fout);
1251 }
1252 }
1253 if (reclen-- <= 0
1255 fputs(lformat->hrule, fout);
1256 }
1257 else
1258 {
1259 if (reclen-- <= 0)
1260 fputc(' ', fout);
1261 }
1262
1264 {
1267 {
1269 {
1271 }
1272 if (output_columns > 0)
1273 {
1274 if (opt_border == 0)
1275 dwidth = Min(dwidth, Max(0, (int) (output_columns - hwidth)));
1276 if (opt_border == 1)
1277 dwidth = Min(dwidth, Max(0, (int) (output_columns - hwidth - 3)));
1278
1279 /*
1280 * Handling the xheader width for border=2 doesn't make much
1281 * sense because this format has an additional right border,
1282 * but keep this for consistency.
1283 */
1284 if (opt_border == 2)
1285 dwidth = Min(dwidth, Max(0, (int) (output_columns - hwidth - 7)));
1286 }
1287 }
1288
1289 if (reclen < 0)
1290 reclen = 0;
1291 if (dwidth < reclen)
1292 dwidth = reclen;
1293
1294 for (i = reclen; i < dwidth; i++)
1295 fputs(opt_border > 0 ? lformat->hrule : " ", fout);
1296 if (opt_border == 2)
1297 fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
1298 }
1299
1300 fputc('\n', fout);
1301}
#define Min(x, y)
Definition c.h:1131
@ PRINT_XHEADER_EXACT_WIDTH
Definition print.h:78
@ PRINT_XHEADER_PAGE
Definition print.h:76
@ PRINT_XHEADER_COLUMN
Definition print.h:74
int expanded_header_exact_width
Definition print.h:118
printXheaderWidthType expanded_header_width_type
Definition print.h:116
unsigned short int border
Definition print.h:120
printTextLineFormat lrule[4]
Definition print.h:85

References printTableOpt::border, printTableOpt::expanded_header_exact_width, printTableOpt::expanded_header_width_type, fb(), fprintf, get_line_style(), i, printTextFormat::lrule, Max, Min, PRINT_XHEADER_COLUMN, PRINT_XHEADER_EXACT_WIDTH, and PRINT_XHEADER_PAGE.

Referenced by print_aligned_vertical().

◆ print_asciidoc_text()

static void print_asciidoc_text ( const printTableContent cont,
FILE fout 
)
static

Definition at line 2189 of file print.c.

2190{
2191 bool opt_tuples_only = cont->opt->tuples_only;
2192 unsigned short opt_border = cont->opt->border;
2193 unsigned int i;
2194 const char *const *ptr;
2195
2196 if (cancel_pressed)
2197 return;
2198
2199 if (cont->opt->start_table)
2200 {
2201 /* print table in new paragraph - enforce preliminary new line */
2202 fputs("\n", fout);
2203
2204 /* print title */
2205 if (!opt_tuples_only && cont->title)
2206 {
2207 fputs(".", fout);
2208 fputs(cont->title, fout);
2209 fputs("\n", fout);
2210 }
2211
2212 /* print table [] header definition */
2213 fprintf(fout, "[%scols=\"", !opt_tuples_only ? "options=\"header\"," : "");
2214 for (i = 0; i < cont->ncolumns; i++)
2215 {
2216 if (i != 0)
2217 fputs(",", fout);
2218 fprintf(fout, "%s", cont->aligns[(i) % cont->ncolumns] == 'r' ? ">l" : "<l");
2219 }
2220 fputs("\"", fout);
2221 switch (opt_border)
2222 {
2223 case 0:
2224 fputs(",frame=\"none\",grid=\"none\"", fout);
2225 break;
2226 case 1:
2227 fputs(",frame=\"none\"", fout);
2228 break;
2229 case 2:
2230 fputs(",frame=\"all\",grid=\"all\"", fout);
2231 break;
2232 }
2233 fputs("]\n", fout);
2234 fputs("|====\n", fout);
2235
2236 /* print headers */
2237 if (!opt_tuples_only)
2238 {
2239 for (ptr = cont->headers; *ptr; ptr++)
2240 {
2241 if (ptr != cont->headers)
2242 fputs(" ", fout);
2243 fputs("^l|", fout);
2245 }
2246 fputs("\n", fout);
2247 }
2248 }
2249
2250 /* print cells */
2251 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2252 {
2253 if (i % cont->ncolumns == 0)
2254 {
2255 if (cancel_pressed)
2256 break;
2257 }
2258
2259 if (i % cont->ncolumns != 0)
2260 fputs(" ", fout);
2261 fputs("|", fout);
2262
2263 /* protect against needless spaces */
2264 if ((*ptr)[strspn(*ptr, " \t")] == '\0')
2265 {
2266 if ((i + 1) % cont->ncolumns != 0)
2267 fputs(" ", fout);
2268 }
2269 else
2271
2272 if ((i + 1) % cont->ncolumns == 0)
2273 fputs("\n", fout);
2274 }
2275
2276 fputs("|====\n", fout);
2277
2278 if (cont->opt->stop_table)
2279 {
2281
2282 /* print footers */
2283 if (!opt_tuples_only && footers != NULL && !cancel_pressed)
2284 {
2286
2287 fputs("\n....\n", fout);
2288 for (f = footers; f; f = f->next)
2289 {
2290 fputs(f->data, fout);
2291 fputs("\n", fout);
2292 }
2293 fputs("....\n", fout);
2294 }
2295 }
2296}
static void asciidoc_escaped_print(const char *in, FILE *fout)
Definition print.c:2171

References asciidoc_escaped_print(), cancel_pressed, printTableFooter::data, fb(), footers_with_default(), fprintf, i, and printTableFooter::next.

Referenced by printTable().

◆ print_asciidoc_vertical()

static void print_asciidoc_vertical ( const printTableContent cont,
FILE fout 
)
static

Definition at line 2299 of file print.c.

2300{
2301 bool opt_tuples_only = cont->opt->tuples_only;
2302 unsigned short opt_border = cont->opt->border;
2303 unsigned long record = cont->opt->prior_records + 1;
2304 unsigned int i;
2305 const char *const *ptr;
2306
2307 if (cancel_pressed)
2308 return;
2309
2310 if (cont->opt->start_table)
2311 {
2312 /* print table in new paragraph - enforce preliminary new line */
2313 fputs("\n", fout);
2314
2315 /* print title */
2316 if (!opt_tuples_only && cont->title)
2317 {
2318 fputs(".", fout);
2319 fputs(cont->title, fout);
2320 fputs("\n", fout);
2321 }
2322
2323 /* print table [] header definition */
2324 fputs("[cols=\"h,l\"", fout);
2325 switch (opt_border)
2326 {
2327 case 0:
2328 fputs(",frame=\"none\",grid=\"none\"", fout);
2329 break;
2330 case 1:
2331 fputs(",frame=\"none\"", fout);
2332 break;
2333 case 2:
2334 fputs(",frame=\"all\",grid=\"all\"", fout);
2335 break;
2336 }
2337 fputs("]\n", fout);
2338 fputs("|====\n", fout);
2339 }
2340
2341 /* print records */
2342 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2343 {
2344 if (i % cont->ncolumns == 0)
2345 {
2346 if (cancel_pressed)
2347 break;
2348 if (!opt_tuples_only)
2349 fprintf(fout,
2350 "2+^|Record %lu\n",
2351 record++);
2352 else
2353 fputs("2+|\n", fout);
2354 }
2355
2356 fputs("<l|", fout);
2357 asciidoc_escaped_print(cont->headers[i % cont->ncolumns], fout);
2358
2359 fprintf(fout, " %s|", cont->aligns[i % cont->ncolumns] == 'r' ? ">l" : "<l");
2360 /* is string only whitespace? */
2361 if ((*ptr)[strspn(*ptr, " \t")] == '\0')
2362 fputs(" ", fout);
2363 else
2365 fputs("\n", fout);
2366 }
2367
2368 fputs("|====\n", fout);
2369
2370 if (cont->opt->stop_table)
2371 {
2372 /* print footers */
2373 if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
2374 {
2376
2377 fputs("\n....\n", fout);
2378 for (f = cont->footers; f; f = f->next)
2379 {
2380 fputs(f->data, fout);
2381 fputs("\n", fout);
2382 }
2383 fputs("....\n", fout);
2384 }
2385 }
2386}

References asciidoc_escaped_print(), cancel_pressed, printTableFooter::data, fb(), fprintf, i, and printTableFooter::next.

Referenced by printTable().

◆ print_csv_text()

static void print_csv_text ( const printTableContent cont,
FILE fout 
)
static

Definition at line 1883 of file print.c.

1884{
1885 const char *const *ptr;
1886 int i;
1887
1888 if (cancel_pressed)
1889 return;
1890
1891 /*
1892 * The title and footer are never printed in csv format. The header is
1893 * printed if opt_tuples_only is false.
1894 *
1895 * Despite RFC 4180 saying that end of lines are CRLF, terminate lines
1896 * with '\n', which prints out as the system-dependent EOL string in text
1897 * mode (typically LF on Unix and CRLF on Windows).
1898 */
1899 if (cont->opt->start_table && !cont->opt->tuples_only)
1900 {
1901 /* print headers */
1902 for (ptr = cont->headers; *ptr; ptr++)
1903 {
1904 if (ptr != cont->headers)
1905 fputc(cont->opt->csvFieldSep[0], fout);
1906 csv_print_field(*ptr, fout, cont->opt->csvFieldSep[0]);
1907 }
1908 fputc('\n', fout);
1909 }
1910
1911 /* print cells */
1912 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1913 {
1914 csv_print_field(*ptr, fout, cont->opt->csvFieldSep[0]);
1915 if ((i + 1) % cont->ncolumns)
1916 fputc(cont->opt->csvFieldSep[0], fout);
1917 else
1918 fputc('\n', fout);
1919 }
1920}
static void csv_print_field(const char *str, FILE *fout, char sep)
Definition print.c:1858

References cancel_pressed, csv_print_field(), fb(), and i.

Referenced by printTable().

◆ print_csv_vertical()

static void print_csv_vertical ( const printTableContent cont,
FILE fout 
)
static

Definition at line 1923 of file print.c.

1924{
1925 const char *const *ptr;
1926 int i;
1927
1928 /* print records */
1929 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1930 {
1931 if (cancel_pressed)
1932 return;
1933
1934 /* print name of column */
1935 csv_print_field(cont->headers[i % cont->ncolumns], fout,
1936 cont->opt->csvFieldSep[0]);
1937
1938 /* print field separator */
1939 fputc(cont->opt->csvFieldSep[0], fout);
1940
1941 /* print field value */
1942 csv_print_field(*ptr, fout, cont->opt->csvFieldSep[0]);
1943
1944 fputc('\n', fout);
1945 }
1946}

References cancel_pressed, csv_print_field(), fb(), and i.

Referenced by printTable().

◆ print_html_text()

static void print_html_text ( const printTableContent cont,
FILE fout 
)
static

Definition at line 1996 of file print.c.

1997{
1998 bool opt_tuples_only = cont->opt->tuples_only;
1999 unsigned short opt_border = cont->opt->border;
2000 const char *opt_table_attr = cont->opt->tableAttr;
2001 unsigned int i;
2002 const char *const *ptr;
2003
2004 if (cancel_pressed)
2005 return;
2006
2007 if (cont->opt->start_table)
2008 {
2009 fprintf(fout, "<table border=\"%d\"", opt_border);
2010 if (opt_table_attr)
2011 fprintf(fout, " %s", opt_table_attr);
2012 fputs(">\n", fout);
2013
2014 /* print title */
2015 if (!opt_tuples_only && cont->title)
2016 {
2017 fputs(" <caption>", fout);
2018 html_escaped_print(cont->title, fout);
2019 fputs("</caption>\n", fout);
2020 }
2021
2022 /* print headers */
2023 if (!opt_tuples_only)
2024 {
2025 fputs(" <tr>\n", fout);
2026 for (ptr = cont->headers; *ptr; ptr++)
2027 {
2028 fputs(" <th align=\"center\">", fout);
2029 html_escaped_print(*ptr, fout);
2030 fputs("</th>\n", fout);
2031 }
2032 fputs(" </tr>\n", fout);
2033 }
2034 }
2035
2036 /* print cells */
2037 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2038 {
2039 if (i % cont->ncolumns == 0)
2040 {
2041 if (cancel_pressed)
2042 break;
2043 fputs(" <tr valign=\"top\">\n", fout);
2044 }
2045
2046 fprintf(fout, " <td align=\"%s\">", cont->aligns[(i) % cont->ncolumns] == 'r' ? "right" : "left");
2047 /* is string only whitespace? */
2048 if ((*ptr)[strspn(*ptr, " \t")] == '\0')
2049 fputs("&nbsp; ", fout);
2050 else
2051 html_escaped_print(*ptr, fout);
2052
2053 fputs("</td>\n", fout);
2054
2055 if ((i + 1) % cont->ncolumns == 0)
2056 fputs(" </tr>\n", fout);
2057 }
2058
2059 if (cont->opt->stop_table)
2060 {
2062
2063 fputs("</table>\n", fout);
2064
2065 /* print footers */
2066 if (!opt_tuples_only && footers != NULL && !cancel_pressed)
2067 {
2069
2070 fputs("<p>", fout);
2071 for (f = footers; f; f = f->next)
2072 {
2074 fputs("<br />\n", fout);
2075 }
2076 fputs("</p>", fout);
2077 }
2078
2079 fputc('\n', fout);
2080 }
2081}
void html_escaped_print(const char *in, FILE *fout)
Definition print.c:1955

References cancel_pressed, printTableFooter::data, fb(), footers_with_default(), fprintf, html_escaped_print(), i, and printTableFooter::next.

Referenced by printTable().

◆ print_html_vertical()

static void print_html_vertical ( const printTableContent cont,
FILE fout 
)
static

Definition at line 2085 of file print.c.

2086{
2087 bool opt_tuples_only = cont->opt->tuples_only;
2088 unsigned short opt_border = cont->opt->border;
2089 const char *opt_table_attr = cont->opt->tableAttr;
2090 unsigned long record = cont->opt->prior_records + 1;
2091 unsigned int i;
2092 const char *const *ptr;
2093
2094 if (cancel_pressed)
2095 return;
2096
2097 if (cont->opt->start_table)
2098 {
2099 fprintf(fout, "<table border=\"%d\"", opt_border);
2100 if (opt_table_attr)
2101 fprintf(fout, " %s", opt_table_attr);
2102 fputs(">\n", fout);
2103
2104 /* print title */
2105 if (!opt_tuples_only && cont->title)
2106 {
2107 fputs(" <caption>", fout);
2108 html_escaped_print(cont->title, fout);
2109 fputs("</caption>\n", fout);
2110 }
2111 }
2112
2113 /* print records */
2114 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2115 {
2116 if (i % cont->ncolumns == 0)
2117 {
2118 if (cancel_pressed)
2119 break;
2120 if (!opt_tuples_only)
2121 fprintf(fout,
2122 "\n <tr><td colspan=\"2\" align=\"center\">Record %lu</td></tr>\n",
2123 record++);
2124 else
2125 fputs("\n <tr><td colspan=\"2\">&nbsp;</td></tr>\n", fout);
2126 }
2127 fputs(" <tr valign=\"top\">\n"
2128 " <th>", fout);
2129 html_escaped_print(cont->headers[i % cont->ncolumns], fout);
2130 fputs("</th>\n", fout);
2131
2132 fprintf(fout, " <td align=\"%s\">", cont->aligns[i % cont->ncolumns] == 'r' ? "right" : "left");
2133 /* is string only whitespace? */
2134 if ((*ptr)[strspn(*ptr, " \t")] == '\0')
2135 fputs("&nbsp; ", fout);
2136 else
2137 html_escaped_print(*ptr, fout);
2138
2139 fputs("</td>\n </tr>\n", fout);
2140 }
2141
2142 if (cont->opt->stop_table)
2143 {
2144 fputs("</table>\n", fout);
2145
2146 /* print footers */
2147 if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
2148 {
2150
2151 fputs("<p>", fout);
2152 for (f = cont->footers; f; f = f->next)
2153 {
2155 fputs("<br />\n", fout);
2156 }
2157 fputs("</p>", fout);
2158 }
2159
2160 fputc('\n', fout);
2161 }
2162}

References cancel_pressed, printTableFooter::data, fb(), fprintf, html_escaped_print(), i, and printTableFooter::next.

Referenced by printTable().

◆ print_latex_longtable_text()

static void print_latex_longtable_text ( const printTableContent cont,
FILE fout 
)
static

Definition at line 2564 of file print.c.

2565{
2566 bool opt_tuples_only = cont->opt->tuples_only;
2567 unsigned short opt_border = cont->opt->border;
2568 unsigned int i;
2569 const char *opt_table_attr = cont->opt->tableAttr;
2571 const char *last_opt_table_attr_char = NULL;
2572 const char *const *ptr;
2573
2574 if (cancel_pressed)
2575 return;
2576
2577 if (opt_border > 3)
2578 opt_border = 3;
2579
2580 if (cont->opt->start_table)
2581 {
2582 /* begin environment and set alignments and borders */
2583 fputs("\\begin{longtable}{", fout);
2584
2585 if (opt_border >= 2)
2586 fputs("| ", fout);
2587
2588 for (i = 0; i < cont->ncolumns; i++)
2589 {
2590 /* longtable supports either a width (p) or an alignment (l/r) */
2591 /* Are we left-justified and was a proportional width specified? */
2592 if (*(cont->aligns + i) == 'l' && opt_table_attr)
2593 {
2594#define LONGTABLE_WHITESPACE " \t\n"
2595
2596 /* advance over whitespace */
2599 /* We have a value? */
2600 if (next_opt_table_attr_char[0] != '\0')
2601 {
2602 fputs("p{", fout);
2608 fputs("\\textwidth}", fout);
2609 }
2610 /* use previous value */
2611 else if (last_opt_table_attr_char != NULL)
2612 {
2613 fputs("p{", fout);
2616 fputs("\\textwidth}", fout);
2617 }
2618 else
2619 fputc('l', fout);
2620 }
2621 else
2622 fputc(*(cont->aligns + i), fout);
2623
2624 if (opt_border != 0 && i < cont->ncolumns - 1)
2625 fputs(" | ", fout);
2626 }
2627
2628 if (opt_border >= 2)
2629 fputs(" |", fout);
2630
2631 fputs("}\n", fout);
2632
2633 /* print headers */
2634 if (!opt_tuples_only)
2635 {
2636 /* firsthead */
2637 if (opt_border >= 2)
2638 fputs("\\toprule\n", fout);
2639 for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2640 {
2641 if (i != 0)
2642 fputs(" & ", fout);
2643 fputs("\\small\\textbf{\\textit{", fout);
2645 fputs("}}", fout);
2646 }
2647 fputs(" \\\\\n", fout);
2648 fputs("\\midrule\n\\endfirsthead\n", fout);
2649
2650 /* secondary heads */
2651 if (opt_border >= 2)
2652 fputs("\\toprule\n", fout);
2653 for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2654 {
2655 if (i != 0)
2656 fputs(" & ", fout);
2657 fputs("\\small\\textbf{\\textit{", fout);
2659 fputs("}}", fout);
2660 }
2661 fputs(" \\\\\n", fout);
2662 /* If the line under the row already appeared, don't do another */
2663 if (opt_border != 3)
2664 fputs("\\midrule\n", fout);
2665 fputs("\\endhead\n", fout);
2666
2667 /* table name, caption? */
2668 if (!opt_tuples_only && cont->title)
2669 {
2670 /* Don't output if we are printing a line under each row */
2671 if (opt_border == 2)
2672 fputs("\\bottomrule\n", fout);
2673 fputs("\\caption[", fout);
2674 latex_escaped_print(cont->title, fout);
2675 fputs(" (Continued)]{", fout);
2676 latex_escaped_print(cont->title, fout);
2677 fputs("}\n\\endfoot\n", fout);
2678 if (opt_border == 2)
2679 fputs("\\bottomrule\n", fout);
2680 fputs("\\caption[", fout);
2681 latex_escaped_print(cont->title, fout);
2682 fputs("]{", fout);
2683 latex_escaped_print(cont->title, fout);
2684 fputs("}\n\\endlastfoot\n", fout);
2685 }
2686 /* output bottom table line? */
2687 else if (opt_border >= 2)
2688 {
2689 fputs("\\bottomrule\n\\endfoot\n", fout);
2690 fputs("\\bottomrule\n\\endlastfoot\n", fout);
2691 }
2692 }
2693 }
2694
2695 /* print cells */
2696 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2697 {
2698 /* Add a line under each row? */
2699 if (i != 0 && i % cont->ncolumns != 0)
2700 fputs("\n&\n", fout);
2701 fputs("\\raggedright{", fout);
2703 fputc('}', fout);
2704 if ((i + 1) % cont->ncolumns == 0)
2705 {
2706 fputs(" \\tabularnewline\n", fout);
2707 if (opt_border == 3)
2708 fputs(" \\hline\n", fout);
2709 }
2710 if (cancel_pressed)
2711 break;
2712 }
2713
2714 if (cont->opt->stop_table)
2715 fputs("\\end{longtable}\n", fout);
2716}
#define LONGTABLE_WHITESPACE
static void latex_escaped_print(const char *in, FILE *fout)
Definition print.c:2395

References cancel_pressed, fb(), i, latex_escaped_print(), and LONGTABLE_WHITESPACE.

Referenced by printTable().

◆ print_latex_text()

static void print_latex_text ( const printTableContent cont,
FILE fout 
)
static

Definition at line 2457 of file print.c.

2458{
2459 bool opt_tuples_only = cont->opt->tuples_only;
2460 unsigned short opt_border = cont->opt->border;
2461 unsigned int i;
2462 const char *const *ptr;
2463
2464 if (cancel_pressed)
2465 return;
2466
2467 if (opt_border > 3)
2468 opt_border = 3;
2469
2470 if (cont->opt->start_table)
2471 {
2472 /* print title */
2473 if (!opt_tuples_only && cont->title)
2474 {
2475 fputs("\\begin{center}\n", fout);
2476 latex_escaped_print(cont->title, fout);
2477 fputs("\n\\end{center}\n\n", fout);
2478 }
2479
2480 /* begin environment and set alignments and borders */
2481 fputs("\\begin{tabular}{", fout);
2482
2483 if (opt_border >= 2)
2484 fputs("| ", fout);
2485 for (i = 0; i < cont->ncolumns; i++)
2486 {
2487 fputc(*(cont->aligns + i), fout);
2488 if (opt_border != 0 && i < cont->ncolumns - 1)
2489 fputs(" | ", fout);
2490 }
2491 if (opt_border >= 2)
2492 fputs(" |", fout);
2493
2494 fputs("}\n", fout);
2495
2496 if (!opt_tuples_only && opt_border >= 2)
2497 fputs("\\hline\n", fout);
2498
2499 /* print headers */
2500 if (!opt_tuples_only)
2501 {
2502 for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2503 {
2504 if (i != 0)
2505 fputs(" & ", fout);
2506 fputs("\\textit{", fout);
2508 fputc('}', fout);
2509 }
2510 fputs(" \\\\\n", fout);
2511 fputs("\\hline\n", fout);
2512 }
2513 }
2514
2515 /* print cells */
2516 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2517 {
2519
2520 if ((i + 1) % cont->ncolumns == 0)
2521 {
2522 fputs(" \\\\\n", fout);
2523 if (opt_border == 3)
2524 fputs("\\hline\n", fout);
2525 if (cancel_pressed)
2526 break;
2527 }
2528 else
2529 fputs(" & ", fout);
2530 }
2531
2532 if (cont->opt->stop_table)
2533 {
2535
2536 if (opt_border == 2)
2537 fputs("\\hline\n", fout);
2538
2539 fputs("\\end{tabular}\n\n\\noindent ", fout);
2540
2541 /* print footers */
2542 if (footers && !opt_tuples_only && !cancel_pressed)
2543 {
2545
2546 for (f = footers; f; f = f->next)
2547 {
2549 fputs(" \\\\\n", fout);
2550 }
2551 }
2552
2553 fputc('\n', fout);
2554 }
2555}

References cancel_pressed, printTableFooter::data, fb(), footers_with_default(), i, latex_escaped_print(), and printTableFooter::next.

Referenced by printTable().

◆ print_latex_vertical()

static void print_latex_vertical ( const printTableContent cont,
FILE fout 
)
static

Definition at line 2720 of file print.c.

2721{
2722 bool opt_tuples_only = cont->opt->tuples_only;
2723 unsigned short opt_border = cont->opt->border;
2724 unsigned long record = cont->opt->prior_records + 1;
2725 unsigned int i;
2726 const char *const *ptr;
2727
2728 if (cancel_pressed)
2729 return;
2730
2731 if (opt_border > 2)
2732 opt_border = 2;
2733
2734 if (cont->opt->start_table)
2735 {
2736 /* print title */
2737 if (!opt_tuples_only && cont->title)
2738 {
2739 fputs("\\begin{center}\n", fout);
2740 latex_escaped_print(cont->title, fout);
2741 fputs("\n\\end{center}\n\n", fout);
2742 }
2743
2744 /* begin environment and set alignments and borders */
2745 fputs("\\begin{tabular}{", fout);
2746 if (opt_border == 0)
2747 fputs("cl", fout);
2748 else if (opt_border == 1)
2749 fputs("c|l", fout);
2750 else if (opt_border == 2)
2751 fputs("|c|l|", fout);
2752 fputs("}\n", fout);
2753 }
2754
2755 /* print records */
2756 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2757 {
2758 /* new record */
2759 if (i % cont->ncolumns == 0)
2760 {
2761 if (cancel_pressed)
2762 break;
2763 if (!opt_tuples_only)
2764 {
2765 if (opt_border == 2)
2766 {
2767 fputs("\\hline\n", fout);
2768 fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %lu}} \\\\\n", record++);
2769 }
2770 else
2771 fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %lu}} \\\\\n", record++);
2772 }
2773 if (opt_border >= 1)
2774 fputs("\\hline\n", fout);
2775 }
2776
2777 latex_escaped_print(cont->headers[i % cont->ncolumns], fout);
2778 fputs(" & ", fout);
2780 fputs(" \\\\\n", fout);
2781 }
2782
2783 if (cont->opt->stop_table)
2784 {
2785 if (opt_border == 2)
2786 fputs("\\hline\n", fout);
2787
2788 fputs("\\end{tabular}\n\n\\noindent ", fout);
2789
2790 /* print footers */
2791 if (cont->footers && !opt_tuples_only && !cancel_pressed)
2792 {
2794
2795 for (f = cont->footers; f; f = f->next)
2796 {
2798 fputs(" \\\\\n", fout);
2799 }
2800 }
2801
2802 fputc('\n', fout);
2803 }
2804}

References cancel_pressed, printTableFooter::data, fb(), fprintf, i, latex_escaped_print(), and printTableFooter::next.

Referenced by printTable().

◆ print_separator()

static void print_separator ( struct separator  sep,
FILE fout 
)
static

Definition at line 395 of file print.c.

396{
397 if (sep.separator_zero)
398 fputc('\000', fout);
399 else if (sep.separator)
400 fputs(sep.separator, fout);
401}

References fb().

Referenced by print_unaligned_text(), and print_unaligned_vertical().

◆ print_troff_ms_text()

static void print_troff_ms_text ( const printTableContent cont,
FILE fout 
)
static

Definition at line 2830 of file print.c.

2831{
2832 bool opt_tuples_only = cont->opt->tuples_only;
2833 unsigned short opt_border = cont->opt->border;
2834 unsigned int i;
2835 const char *const *ptr;
2836
2837 if (cancel_pressed)
2838 return;
2839
2840 if (opt_border > 2)
2841 opt_border = 2;
2842
2843 if (cont->opt->start_table)
2844 {
2845 /* print title */
2846 if (!opt_tuples_only && cont->title)
2847 {
2848 fputs(".LP\n.DS C\n", fout);
2850 fputs("\n.DE\n", fout);
2851 }
2852
2853 /* begin environment and set alignments and borders */
2854 fputs(".LP\n.TS\n", fout);
2855 if (opt_border == 2)
2856 fputs("center box;\n", fout);
2857 else
2858 fputs("center;\n", fout);
2859
2860 for (i = 0; i < cont->ncolumns; i++)
2861 {
2862 fputc(*(cont->aligns + i), fout);
2863 if (opt_border > 0 && i < cont->ncolumns - 1)
2864 fputs(" | ", fout);
2865 }
2866 fputs(".\n", fout);
2867
2868 /* print headers */
2869 if (!opt_tuples_only)
2870 {
2871 for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2872 {
2873 if (i != 0)
2874 fputc('\t', fout);
2875 fputs("\\fI", fout);
2877 fputs("\\fP", fout);
2878 }
2879 fputs("\n_\n", fout);
2880 }
2881 }
2882
2883 /* print cells */
2884 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2885 {
2887
2888 if ((i + 1) % cont->ncolumns == 0)
2889 {
2890 fputc('\n', fout);
2891 if (cancel_pressed)
2892 break;
2893 }
2894 else
2895 fputc('\t', fout);
2896 }
2897
2898 if (cont->opt->stop_table)
2899 {
2901
2902 fputs(".TE\n.DS L\n", fout);
2903
2904 /* print footers */
2905 if (footers && !opt_tuples_only && !cancel_pressed)
2906 {
2908
2909 for (f = footers; f; f = f->next)
2910 {
2912 fputc('\n', fout);
2913 }
2914 }
2915
2916 fputs(".DE\n", fout);
2917 }
2918}
static void troff_ms_escaped_print(const char *in, FILE *fout)
Definition print.c:2813

References cancel_pressed, printTableFooter::data, fb(), footers_with_default(), i, printTableFooter::next, and troff_ms_escaped_print().

Referenced by printTable().

◆ print_troff_ms_vertical()

static void print_troff_ms_vertical ( const printTableContent cont,
FILE fout 
)
static

Definition at line 2922 of file print.c.

2923{
2924 bool opt_tuples_only = cont->opt->tuples_only;
2925 unsigned short opt_border = cont->opt->border;
2926 unsigned long record = cont->opt->prior_records + 1;
2927 unsigned int i;
2928 const char *const *ptr;
2929 unsigned short current_format = 0; /* 0=none, 1=header, 2=body */
2930
2931 if (cancel_pressed)
2932 return;
2933
2934 if (opt_border > 2)
2935 opt_border = 2;
2936
2937 if (cont->opt->start_table)
2938 {
2939 /* print title */
2940 if (!opt_tuples_only && cont->title)
2941 {
2942 fputs(".LP\n.DS C\n", fout);
2944 fputs("\n.DE\n", fout);
2945 }
2946
2947 /* begin environment and set alignments and borders */
2948 fputs(".LP\n.TS\n", fout);
2949 if (opt_border == 2)
2950 fputs("center box;\n", fout);
2951 else
2952 fputs("center;\n", fout);
2953
2954 /* basic format */
2955 if (opt_tuples_only)
2956 fputs("c l;\n", fout);
2957 }
2958 else
2959 current_format = 2; /* assume tuples printed already */
2960
2961 /* print records */
2962 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2963 {
2964 /* new record */
2965 if (i % cont->ncolumns == 0)
2966 {
2967 if (cancel_pressed)
2968 break;
2969 if (!opt_tuples_only)
2970 {
2971 if (current_format != 1)
2972 {
2973 if (opt_border == 2 && record > 1)
2974 fputs("_\n", fout);
2975 if (current_format != 0)
2976 fputs(".T&\n", fout);
2977 fputs("c s.\n", fout);
2978 current_format = 1;
2979 }
2980 fprintf(fout, "\\fIRecord %lu\\fP\n", record++);
2981 }
2982 if (opt_border >= 1)
2983 fputs("_\n", fout);
2984 }
2985
2986 if (!opt_tuples_only)
2987 {
2988 if (current_format != 2)
2989 {
2990 if (current_format != 0)
2991 fputs(".T&\n", fout);
2992 if (opt_border != 1)
2993 fputs("c l.\n", fout);
2994 else
2995 fputs("c | l.\n", fout);
2996 current_format = 2;
2997 }
2998 }
2999
3000 troff_ms_escaped_print(cont->headers[i % cont->ncolumns], fout);
3001 fputc('\t', fout);
3003
3004 fputc('\n', fout);
3005 }
3006
3007 if (cont->opt->stop_table)
3008 {
3009 fputs(".TE\n.DS L\n", fout);
3010
3011 /* print footers */
3012 if (cont->footers && !opt_tuples_only && !cancel_pressed)
3013 {
3015
3016 for (f = cont->footers; f; f = f->next)
3017 {
3019 fputc('\n', fout);
3020 }
3021 }
3022
3023 fputs(".DE\n", fout);
3024 }
3025}

References cancel_pressed, printTableFooter::data, fb(), fprintf, i, printTableFooter::next, and troff_ms_escaped_print().

Referenced by printTable().

◆ print_unaligned_text()

static void print_unaligned_text ( const printTableContent cont,
FILE fout 
)
static

Definition at line 438 of file print.c.

439{
440 bool opt_tuples_only = cont->opt->tuples_only;
441 unsigned int i;
442 const char *const *ptr;
443 bool need_recordsep = false;
444
445 if (cancel_pressed)
446 return;
447
448 if (cont->opt->start_table)
449 {
450 /* print title */
451 if (!opt_tuples_only && cont->title)
452 {
453 fputs(cont->title, fout);
454 print_separator(cont->opt->recordSep, fout);
455 }
456
457 /* print headers */
458 if (!opt_tuples_only)
459 {
460 for (ptr = cont->headers; *ptr; ptr++)
461 {
462 if (ptr != cont->headers)
463 print_separator(cont->opt->fieldSep, fout);
464 fputs(*ptr, fout);
465 }
466 need_recordsep = true;
467 }
468 }
469 else
470 /* assume continuing printout */
471 need_recordsep = true;
472
473 /* print cells */
474 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
475 {
476 if (need_recordsep)
477 {
478 print_separator(cont->opt->recordSep, fout);
479 need_recordsep = false;
480 if (cancel_pressed)
481 break;
482 }
483 fputs(*ptr, fout);
484
485 if ((i + 1) % cont->ncolumns)
486 print_separator(cont->opt->fieldSep, fout);
487 else
488 need_recordsep = true;
489 }
490
491 /* print footers */
492 if (cont->opt->stop_table)
493 {
495
496 if (!opt_tuples_only && footers != NULL && !cancel_pressed)
497 {
499
500 for (f = footers; f; f = f->next)
501 {
502 if (need_recordsep)
503 {
504 print_separator(cont->opt->recordSep, fout);
505 need_recordsep = false;
506 }
507 fputs(f->data, fout);
508 need_recordsep = true;
509 }
510 }
511
512 /*
513 * The last record is terminated by a newline, independent of the set
514 * record separator. But when the record separator is a zero byte, we
515 * use that (compatible with find -print0 and xargs).
516 */
517 if (need_recordsep)
518 {
519 if (cont->opt->recordSep.separator_zero)
520 print_separator(cont->opt->recordSep, fout);
521 else
522 fputc('\n', fout);
523 }
524 }
525}
static void print_separator(struct separator sep, FILE *fout)
Definition print.c:395

References cancel_pressed, printTableFooter::data, fb(), footers_with_default(), i, printTableFooter::next, and print_separator().

Referenced by printTable().

◆ print_unaligned_vertical()

static void print_unaligned_vertical ( const printTableContent cont,
FILE fout 
)
static

Definition at line 529 of file print.c.

530{
531 bool opt_tuples_only = cont->opt->tuples_only;
532 unsigned int i;
533 const char *const *ptr;
534 bool need_recordsep = false;
535
536 if (cancel_pressed)
537 return;
538
539 if (cont->opt->start_table)
540 {
541 /* print title */
542 if (!opt_tuples_only && cont->title)
543 {
544 fputs(cont->title, fout);
545 need_recordsep = true;
546 }
547 }
548 else
549 /* assume continuing printout */
550 need_recordsep = true;
551
552 /* print records */
553 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
554 {
555 if (need_recordsep)
556 {
557 /* record separator is 2 occurrences of recordsep in this mode */
558 print_separator(cont->opt->recordSep, fout);
559 print_separator(cont->opt->recordSep, fout);
560 need_recordsep = false;
561 if (cancel_pressed)
562 break;
563 }
564
565 fputs(cont->headers[i % cont->ncolumns], fout);
566 print_separator(cont->opt->fieldSep, fout);
567 fputs(*ptr, fout);
568
569 if ((i + 1) % cont->ncolumns)
570 print_separator(cont->opt->recordSep, fout);
571 else
572 need_recordsep = true;
573 }
574
575 if (cont->opt->stop_table)
576 {
577 /* print footers */
578 if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
579 {
581
582 print_separator(cont->opt->recordSep, fout);
583 for (f = cont->footers; f; f = f->next)
584 {
585 print_separator(cont->opt->recordSep, fout);
586 fputs(f->data, fout);
587 }
588 }
589
590 /* see above in print_unaligned_text() */
591 if (need_recordsep)
592 {
593 if (cont->opt->recordSep.separator_zero)
594 print_separator(cont->opt->recordSep, fout);
595 else
596 fputc('\n', fout);
597 }
598 }
599}

References cancel_pressed, printTableFooter::data, fb(), i, printTableFooter::next, and print_separator().

Referenced by printTable().

◆ printQuery()

void printQuery ( const PGresult result,
const printQueryOpt opt,
FILE fout,
bool  is_pager,
FILE flog 
)

Definition at line 3760 of file print.c.

3762{
3764 int i,
3765 r,
3766 c;
3767
3768 if (cancel_pressed)
3769 return;
3770
3771 printTableInit(&cont, &opt->topt, opt->title,
3773
3774 /* Assert caller supplied enough translate_columns[] entries */
3775 Assert(opt->translate_columns == NULL ||
3776 opt->n_translate_columns >= cont.ncolumns);
3777
3778 for (i = 0; i < cont.ncolumns; i++)
3779 {
3781 opt->translate_header,
3783 }
3784
3785 /* set cells */
3786 for (r = 0; r < cont.nrows; r++)
3787 {
3788 for (c = 0; c < cont.ncolumns; c++)
3789 {
3790 char *cell;
3791 bool mustfree = false;
3792 bool translate;
3793
3794 if (PQgetisnull(result, r, c))
3795 cell = opt->nullPrint ? opt->nullPrint : "";
3796 else if (PQftype(result, c) == BOOLOID)
3797 cell = (PQgetvalue(result, r, c)[0] == 't' ?
3798 (opt->truePrint ? opt->truePrint : "t") :
3799 (opt->falsePrint ? opt->falsePrint : "f"));
3800 else
3801 {
3802 cell = PQgetvalue(result, r, c);
3803 if (cont.aligns[c] == 'r' && opt->topt.numericLocale)
3804 {
3805 cell = format_numeric_locale(cell);
3806 mustfree = true;
3807 }
3808 }
3809
3812 }
3813 }
3814
3815 /* set footers */
3816 if (opt->footers)
3817 {
3818 char **footer;
3819
3820 for (footer = opt->footers; *footer; footer++)
3821 printTableAddFooter(&cont, *footer);
3822 }
3823
3826}
Oid PQftype(const PGresult *res, int field_num)
Definition fe-exec.c:3750
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
Definition print.c:3209
void printTableCleanup(printTableContent *const content)
Definition print.c:3390
char column_type_alignment(Oid ftype)
Definition print.c:3829
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition print.c:3297
static char * format_numeric_locale(const char *my_str)
Definition print.c:330
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition print.c:3654
void printTableAddFooter(printTableContent *const content, const char *footer)
Definition print.c:3347
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition print.c:3257
#define PQgetvalue
#define PQnfields
#define PQgetisnull
#define PQfname
#define PQntuples
Datum translate(PG_FUNCTION_ARGS)
char * c
const bool * translate_columns
Definition print.h:192
printTableOpt topt
Definition print.h:185
char * nullPrint
Definition print.h:186
char * title
Definition print.h:189
char ** footers
Definition print.h:190
bool translate_header
Definition print.h:191
int n_translate_columns
Definition print.h:194
char * truePrint
Definition print.h:187
bool numericLocale
Definition print.h:135

References Assert, cancel_pressed, column_type_alignment(), printQueryOpt::falsePrint, fb(), printQueryOpt::footers, format_numeric_locale(), i, printQueryOpt::n_translate_columns, printQueryOpt::nullPrint, printTableOpt::numericLocale, PQfname, PQftype(), PQgetisnull, PQgetvalue, PQnfields, PQntuples, printTable(), printTableAddCell(), printTableAddFooter(), printTableAddHeader(), printTableCleanup(), printTableInit(), result, printQueryOpt::title, printQueryOpt::topt, translate(), printQueryOpt::translate_columns, printQueryOpt::translate_header, and printQueryOpt::truePrint.

Referenced by describeAccessMethods(), describeAggregates(), describeConfigurationParameters(), describeFunctions(), describeOneTableDetails(), describeOneTSConfig(), describeOneTSParser(), describeOperators(), describeRoleGrants(), describeSubscriptions(), describeTablespaces(), describeTypes(), ExecQueryAndProcessResults(), listAllDbs(), listCasts(), listCollations(), listConversions(), listDbRoleSettings(), listDefaultACLs(), listDomains(), listEventTriggers(), listExtendedStats(), listExtensions(), listForeignDataWrappers(), listForeignServers(), listForeignTables(), listLanguages(), listLargeObjects(), listOneExtensionContents(), listOperatorClasses(), listOperatorFamilies(), listOpFamilyFunctions(), listOpFamilyOperators(), listPartitionedTables(), listPublications(), listSchemas(), listTables(), listTSConfigs(), listTSDictionaries(), listTSParsers(), listTSTemplates(), listUserMappings(), objectDescription(), permissionsList(), and PrintQueryTuples().

◆ printTable()

void printTable ( const printTableContent cont,
FILE fout,
bool  is_pager,
FILE flog 
)

Definition at line 3654 of file print.c.

3656{
3657 bool is_local_pager = false;
3658
3659 if (cancel_pressed)
3660 return;
3661
3662 if (cont->opt->format == PRINT_NOTHING)
3663 return;
3664
3665 /* print_aligned_*() handle the pager themselves */
3666 if (!is_pager &&
3667 cont->opt->format != PRINT_ALIGNED &&
3668 cont->opt->format != PRINT_WRAPPED)
3669 {
3670 IsPagerNeeded(cont, NULL, (cont->opt->expanded == 1), &fout, &is_pager);
3672 }
3673
3674 /* clear any pre-existing error indication on the output stream */
3675 clearerr(fout);
3676
3677 /* print the stuff */
3678 switch (cont->opt->format)
3679 {
3680 case PRINT_UNALIGNED:
3681 if (cont->opt->expanded == 1)
3683 else
3685 break;
3686 case PRINT_ALIGNED:
3687 case PRINT_WRAPPED:
3688
3689 /*
3690 * In expanded-auto mode, force vertical if a pager is passed in;
3691 * else we may make different decisions for different hunks of the
3692 * query result.
3693 */
3694 if (cont->opt->expanded == 1 ||
3695 (cont->opt->expanded == 2 && is_pager))
3697 else
3699 break;
3700 case PRINT_CSV:
3701 if (cont->opt->expanded == 1)
3703 else
3705 break;
3706 case PRINT_HTML:
3707 if (cont->opt->expanded == 1)
3709 else
3711 break;
3712 case PRINT_ASCIIDOC:
3713 if (cont->opt->expanded == 1)
3715 else
3717 break;
3718 case PRINT_LATEX:
3719 if (cont->opt->expanded == 1)
3721 else
3723 break;
3725 if (cont->opt->expanded == 1)
3727 else
3729 break;
3730 case PRINT_TROFF_MS:
3731 if (cont->opt->expanded == 1)
3733 else
3735 break;
3736 default:
3737 fprintf(stderr, _("invalid output format (internal error): %d"),
3738 cont->opt->format);
3740 }
3741
3742 if (is_local_pager)
3744
3745 /* also produce log output if wanted */
3746 if (flog)
3747 print_aligned_text(cont, flog, false);
3748}
static void print_asciidoc_text(const printTableContent *cont, FILE *fout)
Definition print.c:2189
static void print_unaligned_vertical(const printTableContent *cont, FILE *fout)
Definition print.c:529
static void print_latex_text(const printTableContent *cont, FILE *fout)
Definition print.c:2457
static void print_troff_ms_text(const printTableContent *cont, FILE *fout)
Definition print.c:2830
static void print_html_text(const printTableContent *cont, FILE *fout)
Definition print.c:1996
static void print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
Definition print.c:2922
static void print_csv_text(const printTableContent *cont, FILE *fout)
Definition print.c:1883
static void print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager)
Definition print.c:651
static void print_csv_vertical(const printTableContent *cont, FILE *fout)
Definition print.c:1923
static void print_html_vertical(const printTableContent *cont, FILE *fout)
Definition print.c:2085
static void print_asciidoc_vertical(const printTableContent *cont, FILE *fout)
Definition print.c:2299
static void print_unaligned_text(const printTableContent *cont, FILE *fout)
Definition print.c:438
static void print_latex_vertical(const printTableContent *cont, FILE *fout)
Definition print.c:2720
static void print_latex_longtable_text(const printTableContent *cont, FILE *fout)
Definition print.c:2564
@ PRINT_LATEX_LONGTABLE
Definition print.h:36
@ PRINT_CSV
Definition print.h:33
@ PRINT_UNALIGNED
Definition print.h:38
@ PRINT_TROFF_MS
Definition print.h:37
@ PRINT_ASCIIDOC
Definition print.h:32
@ PRINT_NOTHING
Definition print.h:30
@ PRINT_LATEX
Definition print.h:35
@ PRINT_HTML
Definition print.h:34
#define EXIT_FAILURE
Definition settings.h:197

References _, cancel_pressed, ClosePager(), EXIT_FAILURE, fb(), fprintf, IsPagerNeeded(), PRINT_ALIGNED, print_aligned_text(), print_aligned_vertical(), PRINT_ASCIIDOC, print_asciidoc_text(), print_asciidoc_vertical(), PRINT_CSV, print_csv_text(), print_csv_vertical(), PRINT_HTML, print_html_text(), print_html_vertical(), PRINT_LATEX, PRINT_LATEX_LONGTABLE, print_latex_longtable_text(), print_latex_text(), print_latex_vertical(), PRINT_NOTHING, PRINT_TROFF_MS, print_troff_ms_text(), print_troff_ms_vertical(), PRINT_UNALIGNED, print_unaligned_text(), print_unaligned_vertical(), and PRINT_WRAPPED.

Referenced by describeOneTableDetails(), describePublications(), describeRoles(), exec_command_conninfo(), printCrosstab(), and printQuery().

◆ printTableAddCell()

void printTableAddCell ( printTableContent *const  content,
char cell,
const bool  translate,
const bool  mustfree 
)

Definition at line 3297 of file print.c.

3299{
3301
3302#ifndef ENABLE_NLS
3303 (void) translate; /* unused parameter */
3304#endif
3305
3306 total_cells = (uint64) content->ncolumns * content->nrows;
3307 if (content->cellsadded >= total_cells)
3308 {
3309 fprintf(stderr, _("Cannot add cell to table content: total cell count of %" PRIu64 " exceeded.\n"),
3310 total_cells);
3312 }
3313
3314 *content->cell = (char *) mbvalidate((unsigned char *) cell,
3315 content->opt->encoding);
3316
3317#ifdef ENABLE_NLS
3318 if (translate)
3319 *content->cell = _(*content->cell);
3320#endif
3321
3322 if (mustfree)
3323 {
3324 if (content->cellmustfree == NULL)
3325 content->cellmustfree =
3326 pg_malloc0_array(bool, (total_cells + 1));
3327
3328 content->cellmustfree[content->cellsadded] = true;
3329 }
3330 content->cell++;
3331 content->cellsadded++;
3332}
uint64_t uint64
Definition c.h:684
unsigned char * mbvalidate(unsigned char *pwcs, int encoding)
Definition mbprint.c:392
const printTableOpt * opt
Definition print.h:165
uint64 cellsadded
Definition print.h:174
bool * cellmustfree
Definition print.h:175
const char ** cell
Definition print.h:173
int encoding
Definition print.h:138

References _, printTableContent::cell, printTableContent::cellmustfree, printTableContent::cellsadded, printTableOpt::encoding, EXIT_FAILURE, fb(), fprintf, mbvalidate(), printTableContent::ncolumns, printTableContent::nrows, printTableContent::opt, pg_malloc0_array, and translate().

Referenced by describeOneTableDetails(), describePublications(), describeRoles(), exec_command_conninfo(), and printQuery().

◆ printTableAddFooter()

void printTableAddFooter ( printTableContent *const  content,
const char footer 
)

Definition at line 3347 of file print.c.

3348{
3350
3352 f->data = pg_strdup(footer);
3353
3354 if (content->footers == NULL)
3355 content->footers = f;
3356 else
3357 content->footer->next = f;
3358
3359 content->footer = f;
3360}
#define pg_malloc0_object(type)
Definition fe_memutils.h:61
printTableFooter * footers
Definition print.h:176
printTableFooter * footer
Definition print.h:177

References printTableFooter::data, fb(), printTableContent::footer, printTableContent::footers, printTableFooter::next, pg_malloc0_object, and pg_strdup().

Referenced by add_tablespace_footer(), addFooterToPublicationDesc(), describeOneTableDetails(), printQuery(), and printTableSetFooter().

◆ printTableAddHeader()

void printTableAddHeader ( printTableContent *const  content,
char header,
const bool  translate,
const char  align 
)

Definition at line 3257 of file print.c.

3259{
3260#ifndef ENABLE_NLS
3261 (void) translate; /* unused parameter */
3262#endif
3263
3264 if (content->header >= content->headers + content->ncolumns)
3265 {
3266 fprintf(stderr, _("Cannot add header to table content: "
3267 "column count of %d exceeded.\n"),
3268 content->ncolumns);
3270 }
3271
3272 *content->header = (char *) mbvalidate((unsigned char *) header,
3273 content->opt->encoding);
3274#ifdef ENABLE_NLS
3275 if (translate)
3276 *content->header = _(*content->header);
3277#endif
3278 content->header++;
3279
3280 *content->align = align;
3281 content->align++;
3282}
const char ** header
Definition print.h:170
const char ** headers
Definition print.h:169

References _, printTableContent::align, printTableOpt::encoding, EXIT_FAILURE, fb(), fprintf, printTableContent::header, printTableContent::headers, mbvalidate(), printTableContent::ncolumns, printTableContent::opt, and translate().

Referenced by describeOneTableDetails(), describePublications(), describeRoles(), exec_command_conninfo(), printCrosstab(), and printQuery().

◆ printTableCleanup()

void printTableCleanup ( printTableContent *const  content)

Definition at line 3390 of file print.c.

3391{
3392 if (content->cellmustfree)
3393 {
3395
3396 total_cells = (uint64) content->ncolumns * content->nrows;
3397 for (uint64 i = 0; i < total_cells; i++)
3398 {
3399 if (content->cellmustfree[i])
3400 free(unconstify(char *, content->cells[i]));
3401 }
3402 free(content->cellmustfree);
3403 content->cellmustfree = NULL;
3404 }
3405 free(content->headers);
3406 free(content->cells);
3407 free(content->aligns);
3408
3409 content->opt = NULL;
3410 content->title = NULL;
3411 content->headers = NULL;
3412 content->cells = NULL;
3413 content->aligns = NULL;
3414 content->header = NULL;
3415 content->cell = NULL;
3416 content->align = NULL;
3417
3418 if (content->footers)
3419 {
3420 for (content->footer = content->footers; content->footer;)
3421 {
3423
3424 f = content->footer;
3425 content->footer = f->next;
3426 free(f->data);
3427 free(f);
3428 }
3429 }
3430 content->footers = NULL;
3431 content->footer = NULL;
3432}
#define unconstify(underlying_type, expr)
Definition c.h:1370
char * aligns
Definition print.h:178
const char * title
Definition print.h:166
const char ** cells
Definition print.h:171

References printTableContent::align, printTableContent::aligns, printTableContent::cell, printTableContent::cellmustfree, printTableContent::cells, printTableFooter::data, fb(), printTableContent::footer, printTableContent::footers, free, printTableContent::header, printTableContent::headers, i, printTableContent::ncolumns, printTableFooter::next, printTableContent::nrows, printTableContent::opt, printTableContent::title, and unconstify.

Referenced by describeOneTableDetails(), describePublications(), describeRoles(), exec_command_conninfo(), printCrosstab(), and printQuery().

◆ printTableInit()

void printTableInit ( printTableContent *const  content,
const printTableOpt opt,
const char title,
const int  ncolumns,
const int  nrows 
)

Definition at line 3209 of file print.c.

3211{
3213
3214 content->opt = opt;
3215 content->title = title;
3216 content->ncolumns = ncolumns;
3217 content->nrows = nrows;
3218
3219 content->headers = pg_malloc0_array(const char *, (ncolumns + 1));
3220
3221 total_cells = (uint64) ncolumns * nrows;
3222 /* Catch possible overflow. Using >= here allows adding 1 below */
3223 if (total_cells >= SIZE_MAX / sizeof(*content->cells))
3224 {
3225 fprintf(stderr, _("Cannot print table contents: number of cells %" PRIu64 " is equal to or exceeds maximum %zu.\n"),
3227 SIZE_MAX / sizeof(*content->cells));
3229 }
3230 content->cells = pg_malloc0_array(const char *, (total_cells + 1));
3231
3232 content->cellmustfree = NULL;
3233 content->footers = NULL;
3234
3235 content->aligns = pg_malloc0_array(char, (ncolumns + 1));
3236
3237 content->header = content->headers;
3238 content->cell = content->cells;
3239 content->footer = content->footers;
3240 content->align = content->aligns;
3241 content->cellsadded = 0;
3242}

References _, printTableContent::align, printTableContent::aligns, printTableContent::cell, printTableContent::cellmustfree, printTableContent::cells, printTableContent::cellsadded, EXIT_FAILURE, fb(), printTableContent::footer, printTableContent::footers, fprintf, printTableContent::header, printTableContent::headers, printTableContent::ncolumns, printTableContent::nrows, printTableContent::opt, pg_malloc0_array, and printTableContent::title.

Referenced by describeOneTableDetails(), describePublications(), describeRoles(), exec_command_conninfo(), printCrosstab(), and printQuery().

◆ printTableSetFooter()

void printTableSetFooter ( printTableContent *const  content,
const char footer 
)

Definition at line 3372 of file print.c.

3373{
3374 if (content->footers != NULL)
3375 {
3376 free(content->footer->data);
3377 content->footer->data = pg_strdup(footer);
3378 }
3379 else
3380 printTableAddFooter(content, footer);
3381}

References printTableFooter::data, fb(), printTableContent::footer, printTableContent::footers, free, pg_strdup(), and printTableAddFooter().

Referenced by add_tablespace_footer().

◆ refresh_utf8format()

void refresh_utf8format ( const printTableOpt opt)

Definition at line 3907 of file print.c.

3908{
3910
3911 const unicodeStyleBorderFormat *border;
3912 const unicodeStyleRowFormat *header;
3914
3915 popt->name = "unicode";
3916
3920
3921 popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
3923 popt->lrule[PRINT_RULE_TOP].midvrule = column->down_and_horizontal[opt->unicode_border_linestyle];
3925
3926 popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
3928 popt->lrule[PRINT_RULE_MIDDLE].midvrule = column->vertical_and_horizontal[opt->unicode_header_linestyle];
3930
3931 popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
3933 popt->lrule[PRINT_RULE_BOTTOM].midvrule = column->up_and_horizontal[opt->unicode_border_linestyle];
3935
3936 /* N/A */
3937 popt->lrule[PRINT_RULE_DATA].hrule = "";
3938 popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
3939 popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
3940 popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
3941
3942 popt->midvrule_nl = column->vertical;
3943 popt->midvrule_wrap = column->vertical;
3944 popt->midvrule_blank = column->vertical;
3945
3946 /* Same for all unicode today */
3954}
static const unicodeStyleFormat unicode_style
Definition print.c:145
printTextFormat pg_utf8format
Definition print.c:104
unicode_linestyle unicode_border_linestyle
Definition print.h:141
unicode_linestyle unicode_header_linestyle
Definition print.h:143
unicode_linestyle unicode_column_linestyle
Definition print.h:142
bool wrap_right_border
Definition print.h:95
const char * nl_right
Definition print.h:92
const char * wrap_left
Definition print.h:93
const char * midvrule_blank
Definition print.h:88
const char * header_nl_left
Definition print.h:89
const char * nl_left
Definition print.h:91
const char * midvrule_nl
Definition print.h:86
const char * wrap_right
Definition print.h:94
const char * midvrule_wrap
Definition print.h:87
const char * name
Definition print.h:84
const char * header_nl_right
Definition print.h:90
const char * hrule
Definition print.h:46
const char * rightvrule
Definition print.h:49
const char * midvrule
Definition print.h:48
const char * leftvrule
Definition print.h:47
const char * up_and_right
Definition print.c:123
const char * left_and_right
Definition print.c:128
const char * vertical
Definition print.c:124
const char * down_and_left
Definition print.c:127
const char * horizontal
Definition print.c:126
const char * down_and_right
Definition print.c:125
unicodeStyleRowFormat row_style[2]
Definition print.c:133
unicodeStyleColumnFormat column_style[2]
Definition print.c:134
const char * nl_right
Definition print.c:139
const char * wrap_right
Definition print.c:141
const char * header_nl_left
Definition print.c:136
const char * header_nl_right
Definition print.c:137
unicodeStyleBorderFormat border_style[2]
Definition print.c:135
const char * nl_left
Definition print.c:138
const char * wrap_left
Definition print.c:140
bool wrap_right_border
Definition print.c:142
const char * vertical_and_right[2]
Definition print.c:109
const char * vertical_and_left[2]
Definition print.c:110
const char * horizontal
Definition print.c:108

References unicodeStyleFormat::border_style, unicodeStyleFormat::column_style, unicodeStyleBorderFormat::down_and_left, unicodeStyleBorderFormat::down_and_right, fb(), unicodeStyleFormat::header_nl_left, printTextFormat::header_nl_left, unicodeStyleFormat::header_nl_right, printTextFormat::header_nl_right, unicodeStyleRowFormat::horizontal, unicodeStyleBorderFormat::horizontal, printTextLineFormat::hrule, unicodeStyleBorderFormat::left_and_right, printTextLineFormat::leftvrule, printTextFormat::lrule, printTextLineFormat::midvrule, printTextFormat::midvrule_blank, printTextFormat::midvrule_nl, printTextFormat::midvrule_wrap, printTextFormat::name, unicodeStyleFormat::nl_left, printTextFormat::nl_left, unicodeStyleFormat::nl_right, printTextFormat::nl_right, pg_utf8format, PRINT_RULE_BOTTOM, PRINT_RULE_DATA, PRINT_RULE_MIDDLE, PRINT_RULE_TOP, printTextLineFormat::rightvrule, unicodeStyleFormat::row_style, printTableOpt::unicode_border_linestyle, printTableOpt::unicode_column_linestyle, printTableOpt::unicode_header_linestyle, unicode_style, unicodeStyleBorderFormat::up_and_right, unicodeStyleBorderFormat::vertical, unicodeStyleRowFormat::vertical_and_left, unicodeStyleRowFormat::vertical_and_right, unicodeStyleFormat::wrap_left, printTextFormat::wrap_left, unicodeStyleFormat::wrap_right, printTextFormat::wrap_right, unicodeStyleFormat::wrap_right_border, and printTextFormat::wrap_right_border.

Referenced by do_pset(), and main().

◆ restore_sigpipe_trap()

void restore_sigpipe_trap ( void  )

Definition at line 3065 of file print.c.

3066{
3067#ifndef WIN32
3069#endif
3070}
static bool always_ignore_sigpipe
Definition print.c:50
#define PG_SIG_DFL
Definition port.h:551

References always_ignore_sigpipe, PG_SIG_DFL, PG_SIG_IGN, pqsignal, and SIGPIPE.

Referenced by CloseGOutput(), ClosePager(), do_copy(), do_watch(), exec_command_write(), PageOutputInternal(), and setQFout().

◆ set_sigpipe_trap_state()

void set_sigpipe_trap_state ( bool  ignore)

Definition at line 3078 of file print.c.

3079{
3080 always_ignore_sigpipe = ignore;
3081}

References always_ignore_sigpipe.

Referenced by setQFout().

◆ setDecimalLocale()

void setDecimalLocale ( void  )

Definition at line 3857 of file print.c.

3858{
3859 struct lconv *extlconv;
3860
3861 extlconv = localeconv();
3862
3863 /* Don't accept an empty decimal_point string */
3864 if (*extlconv->decimal_point)
3865 decimal_point = pg_strdup(extlconv->decimal_point);
3866 else
3867 decimal_point = "."; /* SQL output standard */
3868
3869 /*
3870 * Although the Open Group standard allows locales to supply more than one
3871 * group width, we consider only the first one, and we ignore any attempt
3872 * to suppress grouping by specifying CHAR_MAX. As in the backend's
3873 * cash.c, we must apply a range check to avoid being fooled by variant
3874 * CHAR_MAX values.
3875 */
3876 groupdigits = *extlconv->grouping;
3878 groupdigits = 3; /* most common */
3879
3880 /* Don't accept an empty thousands_sep string, either */
3881 /* similar code exists in formatting.c */
3882 if (*extlconv->thousands_sep)
3883 thousands_sep = pg_strdup(extlconv->thousands_sep);
3884 /* Make sure thousands separator doesn't match decimal point symbol. */
3885 else if (strcmp(decimal_point, ",") != 0)
3886 thousands_sep = ",";
3887 else
3888 thousands_sep = ".";
3889}

References decimal_point, fb(), groupdigits, pg_strdup(), and thousands_sep.

Referenced by main().

◆ strlen_max_width()

static int strlen_max_width ( unsigned char str,
int target_width,
int  encoding 
)
static

Definition at line 3962 of file print.c.

3963{
3964 unsigned char *start = str;
3965 unsigned char *end = str + strlen((char *) str);
3966 int curr_width = 0;
3967
3968 while (str < end)
3969 {
3970 int char_width = PQdsplen((char *) str, encoding);
3971
3972 /*
3973 * If the display width of the new character causes the string to
3974 * exceed its target width, skip it and return. However, if this is
3975 * the first character of the string (curr_width == 0), we have to
3976 * accept it.
3977 */
3979 break;
3980
3982
3983 str += PQmblen((char *) str, encoding);
3984
3985 if (str > end) /* Don't overrun invalid string */
3986 str = end;
3987 }
3988
3990
3991 return str - start;
3992}
int PQmblen(const char *s, int encoding)
Definition fe-misc.c:1399
int PQdsplen(const char *s, int encoding)
Definition fe-misc.c:1420
return str start

References encoding, fb(), PQdsplen(), PQmblen(), start, and str.

Referenced by print_aligned_text(), and print_aligned_vertical().

◆ troff_ms_escaped_print()

static void troff_ms_escaped_print ( const char in,
FILE fout 
)
static

Definition at line 2813 of file print.c.

2814{
2815 const char *p;
2816
2817 for (p = in; *p; p++)
2818 switch (*p)
2819 {
2820 case '\\':
2821 fputs("\\(rs", fout);
2822 break;
2823 default:
2824 fputc(*p, fout);
2825 }
2826}

References fb().

Referenced by print_troff_ms_text(), and print_troff_ms_vertical().

Variable Documentation

◆ always_ignore_sigpipe

bool always_ignore_sigpipe = false
static

Definition at line 50 of file print.c.

Referenced by restore_sigpipe_trap(), and set_sigpipe_trap_state().

◆ cancel_pressed

◆ decimal_point

char* decimal_point
static

Definition at line 53 of file print.c.

Referenced by additional_numeric_locale_len(), format_numeric_locale(), and setDecimalLocale().

◆ default_footer

char default_footer[100]
static

Definition at line 57 of file print.c.

Referenced by footers_with_default().

◆ default_footer_cell

printTableFooter default_footer_cell = {default_footer, NULL}
static

Definition at line 58 of file print.c.

Referenced by footers_with_default().

◆ groupdigits

int groupdigits
static

Definition at line 54 of file print.c.

Referenced by additional_numeric_locale_len(), format_numeric_locale(), and setDecimalLocale().

◆ pg_asciiformat

const printTextFormat pg_asciiformat
Initial value:
=
{
"ascii",
{
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
{"", "|", "|", "|"}
},
"|",
"|",
"|",
" ",
"+",
" ",
"+",
".",
".",
true
}

Definition at line 61 of file print.c.

62{
63 "ascii",
64 {
65 {"-", "+", "+", "+"},
66 {"-", "+", "+", "+"},
67 {"-", "+", "+", "+"},
68 {"", "|", "|", "|"}
69 },
70 "|",
71 "|",
72 "|",
73 " ",
74 "+",
75 " ",
76 "+",
77 ".",
78 ".",
79 true
80};

Referenced by do_pset(), and get_line_style().

◆ pg_asciiformat_old

const printTextFormat pg_asciiformat_old
Initial value:
=
{
"old-ascii",
{
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
{"-", "+", "+", "+"},
{"", "|", "|", "|"}
},
":",
";",
" ",
"+",
" ",
" ",
" ",
" ",
" ",
false
}

Definition at line 82 of file print.c.

83{
84 "old-ascii",
85 {
86 {"-", "+", "+", "+"},
87 {"-", "+", "+", "+"},
88 {"-", "+", "+", "+"},
89 {"", "|", "|", "|"}
90 },
91 ":",
92 ";",
93 " ",
94 "+",
95 " ",
96 " ",
97 " ",
98 " ",
99 " ",
100 false
101};

Referenced by do_pset(), and print_aligned_vertical().

◆ pg_utf8format

printTextFormat pg_utf8format

Definition at line 104 of file print.c.

Referenced by do_pset(), and refresh_utf8format().

◆ thousands_sep

char* thousands_sep
static

Definition at line 55 of file print.c.

Referenced by additional_numeric_locale_len(), format_numeric_locale(), and setDecimalLocale().

◆ unicode_style

const unicodeStyleFormat unicode_style
static

Definition at line 145 of file print.c.

145 {
146 {
147 {
148 /* U+2500 Box Drawings Light Horizontal */
149 "\342\224\200",
150
151 /*--
152 * U+251C Box Drawings Light Vertical and Right,
153 * U+255F Box Drawings Vertical Double and Right Single
154 *--
155 */
156 {"\342\224\234", "\342\225\237"},
157
158 /*--
159 * U+2524 Box Drawings Light Vertical and Left,
160 * U+2562 Box Drawings Vertical Double and Left Single
161 *--
162 */
163 {"\342\224\244", "\342\225\242"},
164 },
165 {
166 /* U+2550 Box Drawings Double Horizontal */
167 "\342\225\220",
168
169 /*--
170 * U+255E Box Drawings Vertical Single and Right Double,
171 * U+2560 Box Drawings Double Vertical and Right
172 *--
173 */
174 {"\342\225\236", "\342\225\240"},
175
176 /*--
177 * U+2561 Box Drawings Vertical Single and Left Double,
178 * U+2563 Box Drawings Double Vertical and Left
179 *--
180 */
181 {"\342\225\241", "\342\225\243"},
182 },
183 },
184 {
185 {
186 /* U+2502 Box Drawings Light Vertical */
187 "\342\224\202",
188
189 /*--
190 * U+253C Box Drawings Light Vertical and Horizontal,
191 * U+256A Box Drawings Vertical Single and Horizontal Double
192 *--
193 */
194 {"\342\224\274", "\342\225\252"},
195
196 /*--
197 * U+2534 Box Drawings Light Up and Horizontal,
198 * U+2567 Box Drawings Up Single and Horizontal Double
199 *--
200 */
201 {"\342\224\264", "\342\225\247"},
202
203 /*--
204 * U+252C Box Drawings Light Down and Horizontal,
205 * U+2564 Box Drawings Down Single and Horizontal Double
206 *--
207 */
208 {"\342\224\254", "\342\225\244"},
209 },
210 {
211 /* U+2551 Box Drawings Double Vertical */
212 "\342\225\221",
213
214 /*--
215 * U+256B Box Drawings Vertical Double and Horizontal Single,
216 * U+256C Box Drawings Double Vertical and Horizontal
217 *--
218 */
219 {"\342\225\253", "\342\225\254"},
220
221 /*--
222 * U+2568 Box Drawings Up Double and Horizontal Single,
223 * U+2569 Box Drawings Double Up and Horizontal
224 *--
225 */
226 {"\342\225\250", "\342\225\251"},
227
228 /*--
229 * U+2565 Box Drawings Down Double and Horizontal Single,
230 * U+2566 Box Drawings Double Down and Horizontal
231 *--
232 */
233 {"\342\225\245", "\342\225\246"},
234 },
235 },
236 {
237 /*--
238 * U+2514 Box Drawings Light Up and Right,
239 * U+2502 Box Drawings Light Vertical,
240 * U+250C Box Drawings Light Down and Right,
241 * U+2500 Box Drawings Light Horizontal,
242 * U+2510 Box Drawings Light Down and Left,
243 * U+2518 Box Drawings Light Up and Left
244 *--
245 */
246 {"\342\224\224", "\342\224\202", "\342\224\214", "\342\224\200", "\342\224\220", "\342\224\230"},
247
248 /*--
249 * U+255A Box Drawings Double Up and Right,
250 * U+2551 Box Drawings Double Vertical,
251 * U+2554 Box Drawings Double Down and Right,
252 * U+2550 Box Drawings Double Horizontal,
253 * U+2557 Box Drawings Double Down and Left,
254 * U+255D Box Drawings Double Up and Left
255 *--
256 */
257 {"\342\225\232", "\342\225\221", "\342\225\224", "\342\225\220", "\342\225\227", "\342\225\235"},
258 },
259 " ",
260 /* U+21B5 Downwards Arrow with Corner Leftwards */
261 "\342\206\265",
262 " ",
263 /* U+21B5 Downwards Arrow with Corner Leftwards */
264 "\342\206\265",
265 /* U+2026 Horizontal Ellipsis */
266 "\342\200\246",
267 "\342\200\246",
268 true
269};

Referenced by refresh_utf8format().