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 Archive * fout
Definition pg_dumpall.c:139
static int fb(int x)

References fb(), format, fout, 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 2154 of file print.c.

2155{
2156 const char *p;
2157
2158 for (p = in; *p; p++)
2159 {
2160 switch (*p)
2161 {
2162 case '|':
2163 fputs("\\|", fout);
2164 break;
2165 default:
2166 fputc(*p, fout);
2167 }
2168 }
2169}

References fb(), and fout.

Referenced by print_asciidoc_text(), and print_asciidoc_vertical().

◆ ClosePager()

void ClosePager ( FILE pagerpipe)

Definition at line 3161 of file print.c.

3162{
3163 if (pagerpipe && pagerpipe != stdout)
3164 {
3165 /*
3166 * If printing was canceled midstream, warn about it.
3167 *
3168 * Some pagers like less use Ctrl-C as part of their command set. Even
3169 * so, we abort our processing and warn the user what we did. If the
3170 * pager quit as a result of the SIGINT, this message won't go
3171 * anywhere ...
3172 */
3173 if (cancel_pressed)
3174 fprintf(pagerpipe, _("Interrupted\n"));
3175
3178 }
3179}
#define _(x)
Definition elog.c:96
void restore_sigpipe_trap(void)
Definition print.c:3048
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 3812 of file print.c.

3813{
3814 char align;
3815
3816 switch (ftype)
3817 {
3818 case INT2OID:
3819 case INT4OID:
3820 case INT8OID:
3821 case FLOAT4OID:
3822 case FLOAT8OID:
3823 case NUMERICOID:
3824 case OIDOID:
3825 case OID8OID:
3826 case XIDOID:
3827 case XID8OID:
3828 case CIDOID:
3829 case MONEYOID:
3830 align = 'r';
3831 break;
3832 default:
3833 align = 'l';
3834 break;
3835 }
3836 return align;
3837}

References fb().

Referenced by printCrosstab(), and printQuery().

◆ csv_escaped_print()

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

Definition at line 1826 of file print.c.

1827{
1828 const char *p;
1829
1830 fputc('"', fout);
1831 for (p = str; *p; p++)
1832 {
1833 if (*p == '"')
1834 fputc('"', fout); /* double quotes are doubled */
1835 fputc(*p, fout);
1836 }
1837 fputc('"', fout);
1838}
const char * str

References fb(), fout, 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 1841 of file print.c.

1842{
1843 /*----------------
1844 * Enclose and escape field contents when one of these conditions is met:
1845 * - the field separator is found in the contents.
1846 * - the field contains a CR or LF.
1847 * - the field contains a double quote.
1848 * - the field is exactly "\.".
1849 * - the field separator is either "\" or ".".
1850 * The last two cases prevent producing a line that the server's COPY
1851 * command would interpret as an end-of-data marker. We only really
1852 * need to ensure that the complete line isn't exactly "\.", but for
1853 * simplicity we apply stronger restrictions here.
1854 *----------------
1855 */
1856 if (strchr(str, sep) != NULL ||
1857 strcspn(str, "\r\n\"") != strlen(str) ||
1858 strcmp(str, "\\.") == 0 ||
1859 sep == '\\' || sep == '.')
1861 else
1862 fputs(str, fout);
1863}
static void csv_escaped_print(const char *str, FILE *fout)
Definition print.c:1826

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

Referenced by print_csv_text(), and print_csv_vertical().

◆ disable_sigpipe_trap()

void disable_sigpipe_trap ( void  )

Definition at line 3025 of file print.c.

3026{
3027#ifndef WIN32
3029#endif
3030}
#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:1270
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:943
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 3876 of file print.c.

3877{
3878 /*
3879 * Note: this function mainly exists to preserve the convention that a
3880 * printTableOpt struct can be initialized to zeroes to get default
3881 * behavior.
3882 */
3883 if (opt->line_style != NULL)
3884 return opt->line_style;
3885 else
3886 return &pg_asciiformat;
3887}
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 1938 of file print.c.

1939{
1940 const char *p;
1941 bool leading_space = true;
1942
1943 for (p = in; *p; p++)
1944 {
1945 switch (*p)
1946 {
1947 case '&':
1948 fputs("&amp;", fout);
1949 break;
1950 case '<':
1951 fputs("&lt;", fout);
1952 break;
1953 case '>':
1954 fputs("&gt;", fout);
1955 break;
1956 case '\n':
1957 fputs("<br />\n", fout);
1958 break;
1959 case '"':
1960 fputs("&quot;", fout);
1961 break;
1962 case ' ':
1963 /* protect leading space, for EXPLAIN output */
1964 if (leading_space)
1965 fputs("&nbsp;", fout);
1966 else
1967 fputs(" ", fout);
1968 break;
1969 default:
1970 fputc(*p, fout);
1971 }
1972 if (*p != ' ')
1973 leading_space = false;
1974 }
1975}

References fb(), and fout.

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 3431 of file print.c.

3434{
3435 if (*fout == stdout)
3436 {
3437 *fout = PageOutputInternal(0, cont->opt, cont, width_wrap, vertical);
3438 *is_pager = (*fout != stdout);
3439 }
3440 else
3441 *is_pager = false;
3442}
static FILE * PageOutputInternal(int lines, const printTableOpt *topt, const printTableContent *cont, const unsigned int *width_wrap, bool vertical)
Definition print.c:3091

References fb(), fout, 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 2378 of file print.c.

2379{
2380 const char *p;
2381
2382 for (p = in; *p; p++)
2383 switch (*p)
2384 {
2385 /*
2386 * We convert ASCII characters per the recommendations in
2387 * Scott Pakin's "The Comprehensive LATEX Symbol List",
2388 * available from CTAN. For non-ASCII, you're on your own.
2389 */
2390 case '#':
2391 fputs("\\#", fout);
2392 break;
2393 case '$':
2394 fputs("\\$", fout);
2395 break;
2396 case '%':
2397 fputs("\\%", fout);
2398 break;
2399 case '&':
2400 fputs("\\&", fout);
2401 break;
2402 case '<':
2403 fputs("\\textless{}", fout);
2404 break;
2405 case '>':
2406 fputs("\\textgreater{}", fout);
2407 break;
2408 case '\\':
2409 fputs("\\textbackslash{}", fout);
2410 break;
2411 case '^':
2412 fputs("\\^{}", fout);
2413 break;
2414 case '_':
2415 fputs("\\_", fout);
2416 break;
2417 case '{':
2418 fputs("\\{", fout);
2419 break;
2420 case '|':
2421 fputs("\\textbar{}", fout);
2422 break;
2423 case '}':
2424 fputs("\\}", fout);
2425 break;
2426 case '~':
2427 fputs("\\~{}", fout);
2428 break;
2429 case '\n':
2430 /* This is not right, but doing it right seems too hard */
2431 fputs("\\\\", fout);
2432 break;
2433 default:
2434 fputc(*p, fout);
2435 }
2436}

References fb(), and fout.

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

◆ PageOutput()

FILE * PageOutput ( int  lines,
const printTableOpt topt 
)

Definition at line 3079 of file print.c.

3080{
3081 return PageOutputInternal(lines, topt, NULL, NULL, false);
3082}

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 3091 of file print.c.

3095{
3096 /* check whether we need / can / are supposed to use pager */
3097 if (topt && topt->pager && isatty(fileno(stdin)) && isatty(fileno(stdout)))
3098 {
3099 /* without TIOCGWINSZ, pager == 1 acts the same as pager > 1 */
3100#ifdef TIOCGWINSZ
3101 unsigned short int pager = topt->pager;
3102 int min_lines = topt->pager_min_lines;
3103
3104 if (pager == 1)
3105 {
3106 int result;
3107 struct winsize screen_size;
3108
3109 result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size);
3110 if (result < 0)
3111 pager = 2; /* force use of pager */
3112 else
3113 {
3114 int threshold = Max(screen_size.ws_row, min_lines);
3115
3116 if (cont) /* caller wants us to calculate lines */
3117 lines = count_table_lines(cont, width_wrap, vertical,
3118 threshold);
3119 /* >= accounts for a one-line prompt */
3120 if (lines >= threshold)
3121 pager = 2;
3122 }
3123 }
3124
3125 if (pager > 1)
3126#endif
3127 {
3128 const char *pagerprog;
3129 FILE *pagerpipe;
3130
3131 pagerprog = getenv("PSQL_PAGER");
3132 if (!pagerprog)
3133 pagerprog = getenv("PAGER");
3134 if (!pagerprog)
3136 else
3137 {
3138 /* if PAGER is empty or all-white-space, don't use pager */
3139 if (strspn(pagerprog, " \t\r\n") == strlen(pagerprog))
3140 return stdout;
3141 }
3142 fflush(NULL);
3144 pagerpipe = popen(pagerprog, "w");
3145 if (pagerpipe)
3146 return pagerpipe;
3147 /* if popen fails, silently proceed without pager */
3149 }
3150 }
3151
3152 return stdout;
3153}
#define Max(x, y)
Definition c.h:1085
uint32 result
void disable_sigpipe_trap(void)
Definition print.c:3025
#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 {
1184 free(format_buf[i]);
1185 }
1188 free(max_width);
1193 free(max_bytes);
1197 free(wrap);
1198
1199 if (is_local_pager)
1201}
static void cleanup(void)
Definition bootstrap.c:886
#define pg_malloc0_array(type, count)
Definition fe_memutils.h:67
const printTextFormat * get_line_style(const printTableOpt *opt)
Definition print.c:3876
static printTableFooter * footers_with_default(const printTableContent *cont)
Definition print.c:414
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition print.c:3079
static void IsPagerNeeded(const printTableContent *cont, const unsigned int *width_wrap, bool vertical, FILE **fout, bool *is_pager)
Definition print.c:3431
void ClosePager(FILE *pagerpipe)
Definition print.c:3161
static int strlen_max_width(unsigned char *str, int *target_width, int encoding)
Definition print.c:3945
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
#define free(a)
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, fout, fprintf, free, get_line_style(), i, IsPagerNeeded(), j, printTableFooter::next, PageOutput(), 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 /*
1358 * Deal with the pager here instead of in printTable(), because we could
1359 * get here via print_aligned_text() in expanded auto mode, and so we have
1360 * to recalculate the pager requirement based on vertical output.
1361 */
1362 if (!is_pager)
1363 {
1364 IsPagerNeeded(cont, NULL, true, &fout, &is_pager);
1366 }
1367
1368 /* Find the maximum dimensions for the headers */
1369 for (i = 0; i < cont->ncolumns; i++)
1370 {
1371 int width,
1372 height,
1373 fs;
1374
1375 pg_wcssize((const unsigned char *) cont->headers[i], strlen(cont->headers[i]),
1376 encoding, &width, &height, &fs);
1377 if (width > hwidth)
1378 hwidth = width;
1379 if (height > hheight)
1380 {
1381 hheight = height;
1382 hmultiline = true;
1383 }
1384 if (fs > hformatsize)
1385 hformatsize = fs;
1386 }
1387
1388 /* find longest data cell */
1389 for (ptr = cont->cells; *ptr; ptr++)
1390 {
1391 int width,
1392 height,
1393 fs;
1394
1395 pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding,
1396 &width, &height, &fs);
1397 if (width > dwidth)
1398 dwidth = width;
1399 if (height > dheight)
1400 {
1401 dheight = height;
1402 dmultiline = true;
1403 }
1404 if (fs > dformatsize)
1405 dformatsize = fs;
1406 }
1407
1408 /*
1409 * We now have all the information we need to setup the formatting
1410 * structures
1411 */
1412 dlineptr = pg_malloc_array(struct lineptr, (dheight + 1));
1413 hlineptr = pg_malloc_array(struct lineptr, (hheight + 1));
1414
1417
1418 if (cont->opt->start_table)
1419 {
1420 /* print title */
1421 if (!opt_tuples_only && cont->title)
1422 fprintf(fout, "%s\n", cont->title);
1423 }
1424
1425 /*
1426 * Choose target output width: \pset columns, or $COLUMNS, or ioctl
1427 */
1428 if (cont->opt->columns > 0)
1429 output_columns = cont->opt->columns;
1430 else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
1431 {
1432 if (cont->opt->env_columns > 0)
1433 output_columns = cont->opt->env_columns;
1434#ifdef TIOCGWINSZ
1435 else
1436 {
1437 struct winsize screen_size;
1438
1439 if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1)
1440 output_columns = screen_size.ws_col;
1441 }
1442#endif
1443 }
1444
1445 /*
1446 * Determine data column width: fit output width in wrapped mode, or
1447 * ensure alignment with the record header line in aligned mode.
1448 */
1449 if (cont->opt->format == PRINT_WRAPPED || cont->opt->format == PRINT_ALIGNED)
1450 {
1451 unsigned int swidth,
1452 rwidth = 0,
1453 newdwidth;
1454
1455 if (opt_border == 0)
1456 {
1457 /*
1458 * For border = 0, one space in the middle. (If we discover we
1459 * need to wrap, the spacer column will be replaced by a wrap
1460 * marker, and we'll make room below for another wrap marker at
1461 * the end of the line. But for now, assume no wrap is needed.)
1462 */
1463 swidth = 1;
1464
1465 /* We might need a column for header newline markers, too */
1466 if (hmultiline)
1467 swidth++;
1468 }
1469 else if (opt_border == 1)
1470 {
1471 /*
1472 * For border = 1, two spaces and a vrule in the middle. (As
1473 * above, we might need one more column for a wrap marker.)
1474 */
1475 swidth = 3;
1476
1477 /* We might need a column for left header newline markers, too */
1479 swidth++;
1480 }
1481 else
1482 {
1483 /*
1484 * For border = 2, two more for the vrules at the beginning and
1485 * end of the lines, plus spacer columns adjacent to these. (We
1486 * won't need extra columns for wrap/newline markers, we'll just
1487 * repurpose the spacers.)
1488 */
1489 swidth = 7;
1490 }
1491
1492 /* Reserve a column for data newline indicators, too, if needed */
1493 if (dmultiline &&
1495 swidth++;
1496
1497 /* Determine width required for record header lines */
1498 if (!opt_tuples_only)
1499 {
1500 if (cont->nrows > 0)
1501 rwidth = 1 + (int) log10(cont->nrows);
1502 if (opt_border == 0)
1503 rwidth += 9; /* "* RECORD " */
1504 else if (opt_border == 1)
1505 rwidth += 12; /* "-[ RECORD ]" */
1506 else
1507 rwidth += 15; /* "+-[ RECORD ]-+" */
1508 }
1509
1510 /* We might need to do the rest of the calculation twice */
1511 for (;;)
1512 {
1513 unsigned int width;
1514
1515 /* Total width required to not wrap data */
1516 width = hwidth + swidth + dwidth;
1517 /* ... and not the header lines, either */
1518 if (width < rwidth)
1519 width = rwidth;
1520
1521 if (cont->opt->format == PRINT_WRAPPED && output_columns > 0)
1522 {
1523 unsigned int min_width;
1524
1525 /* Minimum acceptable width: room for just 3 columns of data */
1526 min_width = hwidth + swidth + 3;
1527 /* ... but not less than what the record header lines need */
1528 if (min_width < rwidth)
1529 min_width = rwidth;
1530
1531 if (output_columns >= width)
1532 {
1533 /* Plenty of room, use native data width */
1534 /* (but at least enough for the record header lines) */
1535 newdwidth = width - hwidth - swidth;
1536 }
1537 else if (output_columns < min_width)
1538 {
1539 /* Set data width to match min_width */
1541 }
1542 else
1543 {
1544 /* Set data width to match output_columns */
1546 }
1547 }
1548 else
1549 {
1550 /* Don't know the wrap limit, so use native data width */
1551 /* (but at least enough for the record header lines) */
1552 newdwidth = width - hwidth - swidth;
1553 }
1554
1555 /*
1556 * If we will need to wrap data and didn't already allocate a data
1557 * newline/wrap marker column, do so and recompute.
1558 */
1559 if (newdwidth < dwidth && !dmultiline &&
1561 {
1562 dmultiline = true;
1563 swidth++;
1564 }
1565 else
1566 break;
1567 }
1568
1569 dwidth = newdwidth;
1570 }
1571
1572 /* print records */
1573 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1574 {
1575 printTextRule pos;
1576 int dline,
1577 hline,
1578 dcomplete,
1579 hcomplete,
1580 offset,
1582
1583 if (cancel_pressed)
1584 break;
1585
1586 if (i == 0)
1587 pos = PRINT_RULE_TOP;
1588 else
1589 pos = PRINT_RULE_MIDDLE;
1590
1591 /* Print record header (e.g. "[ RECORD N ]") above each record */
1592 if (i % cont->ncolumns == 0)
1593 {
1594 unsigned int lhwidth = hwidth;
1595
1596 if ((opt_border < 2) &&
1597 (hmultiline) &&
1599 lhwidth++; /* for newline indicators */
1600
1601 if (!opt_tuples_only)
1602 print_aligned_vertical_line(cont->opt, record++,
1604 pos, fout);
1605 else if (i != 0 || !cont->opt->start_table || opt_border == 2)
1607 dwidth, output_columns, pos, fout);
1608 }
1609
1610 /* Format the header */
1611 pg_wcsformat((const unsigned char *) cont->headers[i % cont->ncolumns],
1612 strlen(cont->headers[i % cont->ncolumns]),
1614 /* Format the data */
1615 pg_wcsformat((const unsigned char *) *ptr, strlen(*ptr), encoding,
1616 dlineptr, dheight);
1617
1618 /*
1619 * Loop through header and data in parallel dealing with newlines and
1620 * wrapped lines until they're both exhausted
1621 */
1622 dline = hline = 0;
1623 dcomplete = hcomplete = 0;
1624 offset = 0;
1626 while (!dcomplete || !hcomplete)
1627 {
1628 /* Left border */
1629 if (opt_border == 2)
1630 fprintf(fout, "%s", dformat->leftvrule);
1631
1632 /* Header (never wrapped so just need to deal with newlines) */
1633 if (!hcomplete)
1634 {
1635 int swidth = hwidth,
1637
1638 /*
1639 * Left spacer or new line indicator
1640 */
1641 if ((opt_border == 2) ||
1643 fputs(hline ? format->header_nl_left : " ", fout);
1644
1645 /*
1646 * Header text
1647 */
1649 encoding);
1650 fprintf(fout, "%-s", hlineptr[hline].ptr);
1651
1652 /*
1653 * Spacer
1654 */
1656 if (swidth > 0)
1657 fprintf(fout, "%*s", swidth, " ");
1658
1659 /*
1660 * New line indicator or separator's space
1661 */
1662 if (hlineptr[hline + 1].ptr)
1663 {
1664 /* More lines after this one due to a newline */
1665 if ((opt_border > 0) ||
1667 fputs(format->header_nl_right, fout);
1668 hline++;
1669 }
1670 else
1671 {
1672 /* This was the last line of the header */
1673 if ((opt_border > 0) ||
1675 fputs(" ", fout);
1676 hcomplete = 1;
1677 }
1678 }
1679 else
1680 {
1681 unsigned int swidth = hwidth + opt_border;
1682
1683 if ((opt_border < 2) &&
1684 (hmultiline) &&
1686 swidth++;
1687
1688 if ((opt_border == 0) &&
1689 (format != &pg_asciiformat_old) &&
1690 (hmultiline))
1691 swidth++;
1692
1693 fprintf(fout, "%*s", swidth, " ");
1694 }
1695
1696 /* Separator */
1697 if (opt_border > 0)
1698 {
1699 if (offset)
1700 fputs(format->midvrule_wrap, fout);
1701 else if (dline == 0)
1702 fputs(dformat->midvrule, fout);
1703 else
1704 fputs(format->midvrule_nl, fout);
1705 }
1706
1707 /* Data */
1708 if (!dcomplete)
1709 {
1710 int target_width = dwidth,
1712 swidth = dwidth;
1713
1714 /*
1715 * Left spacer or wrap indicator
1716 */
1717 fputs(offset == 0 ? " " : format->wrap_left, fout);
1718
1719 /*
1720 * Data text
1721 */
1724 fwrite((char *) (dlineptr[dline].ptr + offset),
1725 1, bytes_to_output, fout);
1726
1728 offset += bytes_to_output;
1729
1730 /* Spacer */
1732
1733 if (chars_to_output)
1734 {
1735 /* continuing a wrapped column */
1736 if ((opt_border > 1) ||
1738 {
1739 if (swidth > 0)
1740 fprintf(fout, "%*s", swidth, " ");
1741 fputs(format->wrap_right, fout);
1742 }
1743 }
1744 else if (dlineptr[dline + 1].ptr)
1745 {
1746 /* reached a newline in the column */
1747 if ((opt_border > 1) ||
1749 {
1750 if (swidth > 0)
1751 fprintf(fout, "%*s", swidth, " ");
1752 fputs(format->nl_right, fout);
1753 }
1754 dline++;
1755 offset = 0;
1757 }
1758 else
1759 {
1760 /* reached the end of the cell */
1761 if (opt_border > 1)
1762 {
1763 if (swidth > 0)
1764 fprintf(fout, "%*s", swidth, " ");
1765 fputs(" ", fout);
1766 }
1767 dcomplete = 1;
1768 }
1769
1770 /* Right border */
1771 if (opt_border == 2)
1772 fputs(dformat->rightvrule, fout);
1773
1774 fputs("\n", fout);
1775 }
1776 else
1777 {
1778 /*
1779 * data exhausted (this can occur if header is longer than the
1780 * data due to newlines in the header)
1781 */
1782 if (opt_border < 2)
1783 fputs("\n", fout);
1784 else
1785 fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule);
1786 }
1787 }
1788 }
1789
1790 if (cont->opt->stop_table)
1791 {
1792 if (opt_border == 2 && !cancel_pressed)
1795
1796 /* print footers */
1797 if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
1798 {
1800
1801 if (opt_border < 2)
1802 fputc('\n', fout);
1803 for (f = cont->footers; f; f = f->next)
1804 fprintf(fout, "%s\n", f->data);
1805 }
1806
1807 fputc('\n', fout);
1808 }
1809
1810 free(hlineptr->ptr);
1811 free(dlineptr->ptr);
1812 free(hlineptr);
1813 free(dlineptr);
1814
1815 if (is_local_pager)
1817}
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

References cancel_pressed, ClosePager(), printTableFooter::data, encoding, fb(), footers_with_default(), format, fout, fprintf, free, get_line_style(), i, IsPagerNeeded(), printTableFooter::next, pg_asciiformat_old, 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:1091
@ 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(), fout, 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 2172 of file print.c.

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

References asciidoc_escaped_print(), cancel_pressed, printTableFooter::data, fb(), footers_with_default(), fout, 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 2282 of file print.c.

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

References asciidoc_escaped_print(), cancel_pressed, printTableFooter::data, fb(), fout, 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 1866 of file print.c.

1867{
1868 const char *const *ptr;
1869 int i;
1870
1871 if (cancel_pressed)
1872 return;
1873
1874 /*
1875 * The title and footer are never printed in csv format. The header is
1876 * printed if opt_tuples_only is false.
1877 *
1878 * Despite RFC 4180 saying that end of lines are CRLF, terminate lines
1879 * with '\n', which prints out as the system-dependent EOL string in text
1880 * mode (typically LF on Unix and CRLF on Windows).
1881 */
1882 if (cont->opt->start_table && !cont->opt->tuples_only)
1883 {
1884 /* print headers */
1885 for (ptr = cont->headers; *ptr; ptr++)
1886 {
1887 if (ptr != cont->headers)
1888 fputc(cont->opt->csvFieldSep[0], fout);
1889 csv_print_field(*ptr, fout, cont->opt->csvFieldSep[0]);
1890 }
1891 fputc('\n', fout);
1892 }
1893
1894 /* print cells */
1895 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1896 {
1897 csv_print_field(*ptr, fout, cont->opt->csvFieldSep[0]);
1898 if ((i + 1) % cont->ncolumns)
1899 fputc(cont->opt->csvFieldSep[0], fout);
1900 else
1901 fputc('\n', fout);
1902 }
1903}
static void csv_print_field(const char *str, FILE *fout, char sep)
Definition print.c:1841

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

Referenced by printTable().

◆ print_csv_vertical()

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

Definition at line 1906 of file print.c.

1907{
1908 const char *const *ptr;
1909 int i;
1910
1911 /* print records */
1912 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1913 {
1914 if (cancel_pressed)
1915 return;
1916
1917 /* print name of column */
1918 csv_print_field(cont->headers[i % cont->ncolumns], fout,
1919 cont->opt->csvFieldSep[0]);
1920
1921 /* print field separator */
1922 fputc(cont->opt->csvFieldSep[0], fout);
1923
1924 /* print field value */
1925 csv_print_field(*ptr, fout, cont->opt->csvFieldSep[0]);
1926
1927 fputc('\n', fout);
1928 }
1929}

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

Referenced by printTable().

◆ print_html_text()

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

Definition at line 1979 of file print.c.

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

References cancel_pressed, printTableFooter::data, fb(), footers_with_default(), fout, 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 2068 of file print.c.

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

References cancel_pressed, printTableFooter::data, fb(), fout, 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 2547 of file print.c.

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

References cancel_pressed, fb(), fout, 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 2440 of file print.c.

2441{
2442 bool opt_tuples_only = cont->opt->tuples_only;
2443 unsigned short opt_border = cont->opt->border;
2444 unsigned int i;
2445 const char *const *ptr;
2446
2447 if (cancel_pressed)
2448 return;
2449
2450 if (opt_border > 3)
2451 opt_border = 3;
2452
2453 if (cont->opt->start_table)
2454 {
2455 /* print title */
2456 if (!opt_tuples_only && cont->title)
2457 {
2458 fputs("\\begin{center}\n", fout);
2459 latex_escaped_print(cont->title, fout);
2460 fputs("\n\\end{center}\n\n", fout);
2461 }
2462
2463 /* begin environment and set alignments and borders */
2464 fputs("\\begin{tabular}{", fout);
2465
2466 if (opt_border >= 2)
2467 fputs("| ", fout);
2468 for (i = 0; i < cont->ncolumns; i++)
2469 {
2470 fputc(*(cont->aligns + i), fout);
2471 if (opt_border != 0 && i < cont->ncolumns - 1)
2472 fputs(" | ", fout);
2473 }
2474 if (opt_border >= 2)
2475 fputs(" |", fout);
2476
2477 fputs("}\n", fout);
2478
2479 if (!opt_tuples_only && opt_border >= 2)
2480 fputs("\\hline\n", fout);
2481
2482 /* print headers */
2483 if (!opt_tuples_only)
2484 {
2485 for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2486 {
2487 if (i != 0)
2488 fputs(" & ", fout);
2489 fputs("\\textit{", fout);
2491 fputc('}', fout);
2492 }
2493 fputs(" \\\\\n", fout);
2494 fputs("\\hline\n", fout);
2495 }
2496 }
2497
2498 /* print cells */
2499 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2500 {
2502
2503 if ((i + 1) % cont->ncolumns == 0)
2504 {
2505 fputs(" \\\\\n", fout);
2506 if (opt_border == 3)
2507 fputs("\\hline\n", fout);
2508 if (cancel_pressed)
2509 break;
2510 }
2511 else
2512 fputs(" & ", fout);
2513 }
2514
2515 if (cont->opt->stop_table)
2516 {
2518
2519 if (opt_border == 2)
2520 fputs("\\hline\n", fout);
2521
2522 fputs("\\end{tabular}\n\n\\noindent ", fout);
2523
2524 /* print footers */
2525 if (footers && !opt_tuples_only && !cancel_pressed)
2526 {
2528
2529 for (f = footers; f; f = f->next)
2530 {
2532 fputs(" \\\\\n", fout);
2533 }
2534 }
2535
2536 fputc('\n', fout);
2537 }
2538}

References cancel_pressed, printTableFooter::data, fb(), footers_with_default(), fout, 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 2703 of file print.c.

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

References cancel_pressed, printTableFooter::data, fb(), fout, 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(), and fout.

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 2813 of file print.c.

2814{
2815 bool opt_tuples_only = cont->opt->tuples_only;
2816 unsigned short opt_border = cont->opt->border;
2817 unsigned int i;
2818 const char *const *ptr;
2819
2820 if (cancel_pressed)
2821 return;
2822
2823 if (opt_border > 2)
2824 opt_border = 2;
2825
2826 if (cont->opt->start_table)
2827 {
2828 /* print title */
2829 if (!opt_tuples_only && cont->title)
2830 {
2831 fputs(".LP\n.DS C\n", fout);
2833 fputs("\n.DE\n", fout);
2834 }
2835
2836 /* begin environment and set alignments and borders */
2837 fputs(".LP\n.TS\n", fout);
2838 if (opt_border == 2)
2839 fputs("center box;\n", fout);
2840 else
2841 fputs("center;\n", fout);
2842
2843 for (i = 0; i < cont->ncolumns; i++)
2844 {
2845 fputc(*(cont->aligns + i), fout);
2846 if (opt_border > 0 && i < cont->ncolumns - 1)
2847 fputs(" | ", fout);
2848 }
2849 fputs(".\n", fout);
2850
2851 /* print headers */
2852 if (!opt_tuples_only)
2853 {
2854 for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2855 {
2856 if (i != 0)
2857 fputc('\t', fout);
2858 fputs("\\fI", fout);
2860 fputs("\\fP", fout);
2861 }
2862 fputs("\n_\n", fout);
2863 }
2864 }
2865
2866 /* print cells */
2867 for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2868 {
2870
2871 if ((i + 1) % cont->ncolumns == 0)
2872 {
2873 fputc('\n', fout);
2874 if (cancel_pressed)
2875 break;
2876 }
2877 else
2878 fputc('\t', fout);
2879 }
2880
2881 if (cont->opt->stop_table)
2882 {
2884
2885 fputs(".TE\n.DS L\n", fout);
2886
2887 /* print footers */
2888 if (footers && !opt_tuples_only && !cancel_pressed)
2889 {
2891
2892 for (f = footers; f; f = f->next)
2893 {
2895 fputc('\n', fout);
2896 }
2897 }
2898
2899 fputs(".DE\n", fout);
2900 }
2901}
static void troff_ms_escaped_print(const char *in, FILE *fout)
Definition print.c:2796

References cancel_pressed, printTableFooter::data, fb(), footers_with_default(), fout, 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 2905 of file print.c.

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

References cancel_pressed, printTableFooter::data, fb(), fout, 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(), fout, 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(), fout, 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 3743 of file print.c.

3745{
3747 int i,
3748 r,
3749 c;
3750
3751 if (cancel_pressed)
3752 return;
3753
3754 printTableInit(&cont, &opt->topt, opt->title,
3756
3757 /* Assert caller supplied enough translate_columns[] entries */
3758 Assert(opt->translate_columns == NULL ||
3759 opt->n_translate_columns >= cont.ncolumns);
3760
3761 for (i = 0; i < cont.ncolumns; i++)
3762 {
3764 opt->translate_header,
3766 }
3767
3768 /* set cells */
3769 for (r = 0; r < cont.nrows; r++)
3770 {
3771 for (c = 0; c < cont.ncolumns; c++)
3772 {
3773 char *cell;
3774 bool mustfree = false;
3775 bool translate;
3776
3777 if (PQgetisnull(result, r, c))
3778 cell = opt->nullPrint ? opt->nullPrint : "";
3779 else if (PQftype(result, c) == BOOLOID)
3780 cell = (PQgetvalue(result, r, c)[0] == 't' ?
3781 (opt->truePrint ? opt->truePrint : "t") :
3782 (opt->falsePrint ? opt->falsePrint : "f"));
3783 else
3784 {
3785 cell = PQgetvalue(result, r, c);
3786 if (cont.aligns[c] == 'r' && opt->topt.numericLocale)
3787 {
3788 cell = format_numeric_locale(cell);
3789 mustfree = true;
3790 }
3791 }
3792
3795 }
3796 }
3797
3798 /* set footers */
3799 if (opt->footers)
3800 {
3801 char **footer;
3802
3803 for (footer = opt->footers; *footer; footer++)
3804 printTableAddFooter(&cont, *footer);
3805 }
3806
3809}
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:3192
void printTableCleanup(printTableContent *const content)
Definition print.c:3373
char column_type_alignment(Oid ftype)
Definition print.c:3812
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition print.c:3280
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:3637
void printTableAddFooter(printTableContent *const content, const char *footer)
Definition print.c:3330
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition print.c:3240
#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(), fout, 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 3637 of file print.c.

3639{
3640 bool is_local_pager = false;
3641
3642 if (cancel_pressed)
3643 return;
3644
3645 if (cont->opt->format == PRINT_NOTHING)
3646 return;
3647
3648 /* print_aligned_*() handle the pager themselves */
3649 if (!is_pager &&
3650 cont->opt->format != PRINT_ALIGNED &&
3651 cont->opt->format != PRINT_WRAPPED)
3652 {
3653 IsPagerNeeded(cont, NULL, (cont->opt->expanded == 1), &fout, &is_pager);
3655 }
3656
3657 /* clear any pre-existing error indication on the output stream */
3658 clearerr(fout);
3659
3660 /* print the stuff */
3661 switch (cont->opt->format)
3662 {
3663 case PRINT_UNALIGNED:
3664 if (cont->opt->expanded == 1)
3666 else
3668 break;
3669 case PRINT_ALIGNED:
3670 case PRINT_WRAPPED:
3671
3672 /*
3673 * In expanded-auto mode, force vertical if a pager is passed in;
3674 * else we may make different decisions for different hunks of the
3675 * query result.
3676 */
3677 if (cont->opt->expanded == 1 ||
3678 (cont->opt->expanded == 2 && is_pager))
3680 else
3682 break;
3683 case PRINT_CSV:
3684 if (cont->opt->expanded == 1)
3686 else
3688 break;
3689 case PRINT_HTML:
3690 if (cont->opt->expanded == 1)
3692 else
3694 break;
3695 case PRINT_ASCIIDOC:
3696 if (cont->opt->expanded == 1)
3698 else
3700 break;
3701 case PRINT_LATEX:
3702 if (cont->opt->expanded == 1)
3704 else
3706 break;
3708 if (cont->opt->expanded == 1)
3710 else
3712 break;
3713 case PRINT_TROFF_MS:
3714 if (cont->opt->expanded == 1)
3716 else
3718 break;
3719 default:
3720 fprintf(stderr, _("invalid output format (internal error): %d"),
3721 cont->opt->format);
3723 }
3724
3725 if (is_local_pager)
3727
3728 /* also produce log output if wanted */
3729 if (flog)
3730 print_aligned_text(cont, flog, false);
3731}
static void print_asciidoc_text(const printTableContent *cont, FILE *fout)
Definition print.c:2172
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:2440
static void print_troff_ms_text(const printTableContent *cont, FILE *fout)
Definition print.c:2813
static void print_html_text(const printTableContent *cont, FILE *fout)
Definition print.c:1979
static void print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
Definition print.c:2905
static void print_csv_text(const printTableContent *cont, FILE *fout)
Definition print.c:1866
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:1906
static void print_html_vertical(const printTableContent *cont, FILE *fout)
Definition print.c:2068
static void print_asciidoc_vertical(const printTableContent *cont, FILE *fout)
Definition print.c:2282
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:2703
static void print_latex_longtable_text(const printTableContent *cont, FILE *fout)
Definition print.c:2547
@ 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(), fout, 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 3280 of file print.c.

3282{
3284
3285#ifndef ENABLE_NLS
3286 (void) translate; /* unused parameter */
3287#endif
3288
3289 total_cells = (uint64) content->ncolumns * content->nrows;
3290 if (content->cellsadded >= total_cells)
3291 {
3292 fprintf(stderr, _("Cannot add cell to table content: total cell count of %" PRIu64 " exceeded.\n"),
3293 total_cells);
3295 }
3296
3297 *content->cell = (char *) mbvalidate((unsigned char *) cell,
3298 content->opt->encoding);
3299
3300#ifdef ENABLE_NLS
3301 if (translate)
3302 *content->cell = _(*content->cell);
3303#endif
3304
3305 if (mustfree)
3306 {
3307 if (content->cellmustfree == NULL)
3308 content->cellmustfree =
3309 pg_malloc0_array(bool, (total_cells + 1));
3310
3311 content->cellmustfree[content->cellsadded] = true;
3312 }
3313 content->cell++;
3314 content->cellsadded++;
3315}
uint64_t uint64
Definition c.h:625
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 3330 of file print.c.

3331{
3333
3335 f->data = pg_strdup(footer);
3336
3337 if (content->footers == NULL)
3338 content->footers = f;
3339 else
3340 content->footer->next = f;
3341
3342 content->footer = f;
3343}
#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 3240 of file print.c.

3242{
3243#ifndef ENABLE_NLS
3244 (void) translate; /* unused parameter */
3245#endif
3246
3247 if (content->header >= content->headers + content->ncolumns)
3248 {
3249 fprintf(stderr, _("Cannot add header to table content: "
3250 "column count of %d exceeded.\n"),
3251 content->ncolumns);
3253 }
3254
3255 *content->header = (char *) mbvalidate((unsigned char *) header,
3256 content->opt->encoding);
3257#ifdef ENABLE_NLS
3258 if (translate)
3259 *content->header = _(*content->header);
3260#endif
3261 content->header++;
3262
3263 *content->align = align;
3264 content->align++;
3265}
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 3373 of file print.c.

3374{
3375 if (content->cellmustfree)
3376 {
3378
3379 total_cells = (uint64) content->ncolumns * content->nrows;
3380 for (uint64 i = 0; i < total_cells; i++)
3381 {
3382 if (content->cellmustfree[i])
3383 free(unconstify(char *, content->cells[i]));
3384 }
3385 free(content->cellmustfree);
3386 content->cellmustfree = NULL;
3387 }
3388 free(content->headers);
3389 free(content->cells);
3390 free(content->aligns);
3391
3392 content->opt = NULL;
3393 content->title = NULL;
3394 content->headers = NULL;
3395 content->cells = NULL;
3396 content->aligns = NULL;
3397 content->header = NULL;
3398 content->cell = NULL;
3399 content->align = NULL;
3400
3401 if (content->footers)
3402 {
3403 for (content->footer = content->footers; content->footer;)
3404 {
3406
3407 f = content->footer;
3408 content->footer = f->next;
3409 free(f->data);
3410 free(f);
3411 }
3412 }
3413 content->footers = NULL;
3414 content->footer = NULL;
3415}
#define unconstify(underlying_type, expr)
Definition c.h:1325
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 3192 of file print.c.

3194{
3196
3197 content->opt = opt;
3198 content->title = title;
3199 content->ncolumns = ncolumns;
3200 content->nrows = nrows;
3201
3202 content->headers = pg_malloc0_array(const char *, (ncolumns + 1));
3203
3204 total_cells = (uint64) ncolumns * nrows;
3205 /* Catch possible overflow. Using >= here allows adding 1 below */
3206 if (total_cells >= SIZE_MAX / sizeof(*content->cells))
3207 {
3208 fprintf(stderr, _("Cannot print table contents: number of cells %" PRIu64 " is equal to or exceeds maximum %zu.\n"),
3210 SIZE_MAX / sizeof(*content->cells));
3212 }
3213 content->cells = pg_malloc0_array(const char *, (total_cells + 1));
3214
3215 content->cellmustfree = NULL;
3216 content->footers = NULL;
3217
3218 content->aligns = pg_malloc0_array(char, (ncolumns + 1));
3219
3220 content->header = content->headers;
3221 content->cell = content->cells;
3222 content->footer = content->footers;
3223 content->align = content->aligns;
3224 content->cellsadded = 0;
3225}

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 3355 of file print.c.

3356{
3357 if (content->footers != NULL)
3358 {
3359 free(content->footer->data);
3360 content->footer->data = pg_strdup(footer);
3361 }
3362 else
3363 printTableAddFooter(content, footer);
3364}

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 3890 of file print.c.

3891{
3893
3894 const unicodeStyleBorderFormat *border;
3895 const unicodeStyleRowFormat *header;
3897
3898 popt->name = "unicode";
3899
3903
3904 popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
3906 popt->lrule[PRINT_RULE_TOP].midvrule = column->down_and_horizontal[opt->unicode_border_linestyle];
3908
3909 popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
3911 popt->lrule[PRINT_RULE_MIDDLE].midvrule = column->vertical_and_horizontal[opt->unicode_header_linestyle];
3913
3914 popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
3916 popt->lrule[PRINT_RULE_BOTTOM].midvrule = column->up_and_horizontal[opt->unicode_border_linestyle];
3918
3919 /* N/A */
3920 popt->lrule[PRINT_RULE_DATA].hrule = "";
3921 popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
3922 popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
3923 popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
3924
3925 popt->midvrule_nl = column->vertical;
3926 popt->midvrule_wrap = column->vertical;
3927 popt->midvrule_blank = column->vertical;
3928
3929 /* Same for all unicode today */
3937}
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 3048 of file print.c.

3049{
3050#ifndef WIN32
3052#endif
3053}
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 3061 of file print.c.

3062{
3063 always_ignore_sigpipe = ignore;
3064}

References always_ignore_sigpipe.

Referenced by setQFout().

◆ setDecimalLocale()

void setDecimalLocale ( void  )

Definition at line 3840 of file print.c.

3841{
3842 struct lconv *extlconv;
3843
3844 extlconv = localeconv();
3845
3846 /* Don't accept an empty decimal_point string */
3847 if (*extlconv->decimal_point)
3848 decimal_point = pg_strdup(extlconv->decimal_point);
3849 else
3850 decimal_point = "."; /* SQL output standard */
3851
3852 /*
3853 * Although the Open Group standard allows locales to supply more than one
3854 * group width, we consider only the first one, and we ignore any attempt
3855 * to suppress grouping by specifying CHAR_MAX. As in the backend's
3856 * cash.c, we must apply a range check to avoid being fooled by variant
3857 * CHAR_MAX values.
3858 */
3859 groupdigits = *extlconv->grouping;
3861 groupdigits = 3; /* most common */
3862
3863 /* Don't accept an empty thousands_sep string, either */
3864 /* similar code exists in formatting.c */
3865 if (*extlconv->thousands_sep)
3866 thousands_sep = pg_strdup(extlconv->thousands_sep);
3867 /* Make sure thousands separator doesn't match decimal point symbol. */
3868 else if (strcmp(decimal_point, ",") != 0)
3869 thousands_sep = ",";
3870 else
3871 thousands_sep = ".";
3872}

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 3945 of file print.c.

3946{
3947 unsigned char *start = str;
3948 unsigned char *end = str + strlen((char *) str);
3949 int curr_width = 0;
3950
3951 while (str < end)
3952 {
3953 int char_width = PQdsplen((char *) str, encoding);
3954
3955 /*
3956 * If the display width of the new character causes the string to
3957 * exceed its target width, skip it and return. However, if this is
3958 * the first character of the string (curr_width == 0), we have to
3959 * accept it.
3960 */
3962 break;
3963
3965
3966 str += PQmblen((char *) str, encoding);
3967
3968 if (str > end) /* Don't overrun invalid string */
3969 str = end;
3970 }
3971
3973
3974 return str - start;
3975}
int PQmblen(const char *s, int encoding)
Definition fe-misc.c:1255
int PQdsplen(const char *s, int encoding)
Definition fe-misc.c:1276
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 2796 of file print.c.

2797{
2798 const char *p;
2799
2800 for (p = in; *p; p++)
2801 switch (*p)
2802 {
2803 case '\\':
2804 fputs("\\(rs", fout);
2805 break;
2806 default:
2807 fputc(*p, fout);
2808 }
2809}

References fb(), and fout.

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().