PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
print.c File Reference
#include "postgres_fe.h"
#include <limits.h>
#include <math.h>
#include <signal.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include "fe_utils/print.h"
#include "catalog/pg_type.h"
#include "fe_utils/mbprint.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 void IsPagerNeeded (const printTableContent *cont, int extra_lines, bool expanded, 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 char * format_numeric_locale (const char *my_str)
 
static void fputnbytes (FILE *f, const char *str, size_t n)
 
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 printTextFormat *format, const unsigned short opt_border, unsigned long record, unsigned int hwidth, unsigned int dwidth, printTextRule pos, 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)
 
FILE * PageOutput (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 bool cancel_pressed = false
 
static bool always_ignore_sigpipe = false
 
static char * decimal_point
 
static int groupdigits
 
static char * thousands_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

#define LONGTABLE_WHITESPACE   " \t\n"

Typedef Documentation

Function Documentation

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

References printTextLineFormat::hrule, i, printTextLineFormat::leftvrule, printTextFormat::lrule, printTextLineFormat::midvrule, and printTextLineFormat::rightvrule.

Referenced by print_aligned_text().

544 {
545  const printTextLineFormat *lformat = &format->lrule[pos];
546  unsigned int i,
547  j;
548 
549  if (border == 1)
550  fputs(lformat->hrule, fout);
551  else if (border == 2)
552  fprintf(fout, "%s%s", lformat->leftvrule, lformat->hrule);
553 
554  for (i = 0; i < ncolumns; i++)
555  {
556  for (j = 0; j < widths[i]; j++)
557  fputs(lformat->hrule, fout);
558 
559  if (i < ncolumns - 1)
560  {
561  if (border == 0)
562  fputc(' ', fout);
563  else
564  fprintf(fout, "%s%s%s", lformat->hrule,
565  lformat->midvrule, lformat->hrule);
566  }
567  }
568 
569  if (border == 2)
570  fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
571  else if (border == 1)
572  fputs(lformat->hrule, fout);
573 
574  fputc('\n', fout);
575 }
const char * midvrule
Definition: print.h:45
printTextLineFormat lrule[4]
Definition: print.h:70
const char * hrule
Definition: print.h:43
const char * leftvrule
Definition: print.h:44
const char * rightvrule
Definition: print.h:46
int i
static int additional_numeric_locale_len ( const char *  my_str)
static

Definition at line 222 of file print.c.

References decimal_point, groupdigits, integer_digits(), NULL, and thousands_sep.

Referenced by format_numeric_locale().

223 {
224  int int_len = integer_digits(my_str),
225  len = 0;
226 
227  /* Account for added thousands_sep instances */
228  if (int_len > groupdigits)
229  len += ((int_len - 1) / groupdigits) * strlen(thousands_sep);
230 
231  /* Account for possible additional length of decimal_point */
232  if (strchr(my_str, '.') != NULL)
233  len += strlen(decimal_point) - 1;
234 
235  return len;
236 }
static int integer_digits(const char *my_str)
Definition: print.c:211
static int groupdigits
Definition: print.c:52
#define NULL
Definition: c.h:229
static char * decimal_point
Definition: print.c:51
static char * thousands_sep
Definition: print.c:53
static void asciidoc_escaped_print ( const char *  in,
FILE *  fout 
)
static

Definition at line 1960 of file print.c.

Referenced by print_asciidoc_text(), and print_asciidoc_vertical().

1961 {
1962  const char *p;
1963 
1964  for (p = in; *p; p++)
1965  {
1966  switch (*p)
1967  {
1968  case '|':
1969  fputs("\\|", fout);
1970  break;
1971  default:
1972  fputc(*p, fout);
1973  }
1974  }
1975 }
void ClosePager ( FILE *  pagerpipe)

Definition at line 2900 of file print.c.

References _, cancel_pressed, and restore_sigpipe_trap().

Referenced by exec_command_sf(), exec_command_sv(), ExecQueryUsingCursor(), helpSQL(), helpVariables(), print_aligned_text(), print_aligned_vertical(), printHistory(), printTable(), slashUsage(), and usage().

2901 {
2902  if (pagerpipe && pagerpipe != stdout)
2903  {
2904  /*
2905  * If printing was canceled midstream, warn about it.
2906  *
2907  * Some pagers like less use Ctrl-C as part of their command set. Even
2908  * so, we abort our processing and warn the user what we did. If the
2909  * pager quit as a result of the SIGINT, this message won't go
2910  * anywhere ...
2911  */
2912  if (cancel_pressed)
2913  fprintf(pagerpipe, _("Interrupted\n"));
2914 
2915  pclose(pagerpipe);
2917  }
2918 }
volatile bool cancel_pressed
Definition: print.c:46
void restore_sigpipe_trap(void)
Definition: print.c:2824
#define _(x)
Definition: elog.c:84
char column_type_alignment ( Oid  ftype)

Definition at line 3350 of file print.c.

References CASHOID, CIDOID, FLOAT4OID, FLOAT8OID, INT2OID, INT4OID, INT8OID, NUMERICOID, OIDOID, and XIDOID.

Referenced by printCrosstab(), and printQuery().

3351 {
3352  char align;
3353 
3354  switch (ftype)
3355  {
3356  case INT2OID:
3357  case INT4OID:
3358  case INT8OID:
3359  case FLOAT4OID:
3360  case FLOAT8OID:
3361  case NUMERICOID:
3362  case OIDOID:
3363  case XIDOID:
3364  case CIDOID:
3365  case CASHOID:
3366  align = 'r';
3367  break;
3368  default:
3369  align = 'l';
3370  break;
3371  }
3372  return align;
3373 }
#define OIDOID
Definition: pg_type.h:328
#define NUMERICOID
Definition: pg_type.h:554
#define INT4OID
Definition: pg_type.h:316
#define XIDOID
Definition: pg_type.h:336
#define INT2OID
Definition: pg_type.h:308
#define FLOAT4OID
Definition: pg_type.h:416
#define CIDOID
Definition: pg_type.h:340
#define INT8OID
Definition: pg_type.h:304
#define FLOAT8OID
Definition: pg_type.h:419
#define CASHOID
Definition: pg_type.h:439
void disable_sigpipe_trap ( void  )

Definition at line 2801 of file print.c.

References pqsignal(), SIG_IGN, and SIGPIPE.

Referenced by do_copy(), exec_command_write(), ExecQueryUsingCursor(), PageOutput(), and PrintQueryTuples().

2802 {
2803 #ifndef WIN32
2805 #endif
2806 }
#define SIG_IGN
Definition: win32.h:185
#define SIGPIPE
Definition: win32.h:193
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
static printTableFooter* footers_with_default ( const printTableContent cont)
static

Definition at line 345 of file print.c.

References default_footer, printTableOpt::default_footer, default_footer_cell, printTableContent::footers, ngettext, printTableContent::nrows, NULL, printTableContent::opt, printTableOpt::prior_records, 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().

346 {
347  if (cont->footers == NULL && cont->opt->default_footer)
348  {
349  unsigned long total_records;
350 
351  total_records = cont->opt->prior_records + cont->nrows;
353  ngettext("(%lu row)", "(%lu rows)", total_records),
354  total_records);
355 
356  return &default_footer_cell;
357  }
358  else
359  return cont->footers;
360 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
const printTableOpt * opt
Definition: print.h:145
unsigned long prior_records
Definition: print.h:111
#define ngettext(s, p, n)
Definition: c.h:127
static printTableFooter default_footer_cell
Definition: print.c:56
bool default_footer
Definition: print.h:110
#define NULL
Definition: c.h:229
printTableFooter * footers
Definition: print.h:156
static char default_footer[100]
Definition: print.c:55
static char* format_numeric_locale ( const char *  my_str)
static

Definition at line 247 of file print.c.

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

Referenced by printQuery().

248 {
249  char *new_str;
250  int new_len,
251  int_len,
252  leading_digits,
253  i,
254  new_str_pos;
255 
256  /*
257  * If the string doesn't look like a number, return it unchanged. This
258  * check is essential to avoid mangling already-localized "money" values.
259  */
260  if (strspn(my_str, "0123456789+-.eE") != strlen(my_str))
261  return pg_strdup(my_str);
262 
263  new_len = strlen(my_str) + additional_numeric_locale_len(my_str);
264  new_str = pg_malloc(new_len + 1);
265  new_str_pos = 0;
266  int_len = integer_digits(my_str);
267 
268  /* number of digits in first thousands group */
269  leading_digits = int_len % groupdigits;
270  if (leading_digits == 0)
271  leading_digits = groupdigits;
272 
273  /* process sign */
274  if (my_str[0] == '-' || my_str[0] == '+')
275  {
276  new_str[new_str_pos++] = my_str[0];
277  my_str++;
278  }
279 
280  /* process integer part of number */
281  for (i = 0; i < int_len; i++)
282  {
283  /* Time to insert separator? */
284  if (i > 0 && --leading_digits == 0)
285  {
286  strcpy(&new_str[new_str_pos], thousands_sep);
287  new_str_pos += strlen(thousands_sep);
288  leading_digits = groupdigits;
289  }
290  new_str[new_str_pos++] = my_str[i];
291  }
292 
293  /* handle decimal point if any */
294  if (my_str[i] == '.')
295  {
296  strcpy(&new_str[new_str_pos], decimal_point);
297  new_str_pos += strlen(decimal_point);
298  i++;
299  }
300 
301  /* copy the rest (fractional digits and/or exponent, and \0 terminator) */
302  strcpy(&new_str[new_str_pos], &my_str[i]);
303 
304  /* assert we didn't underestimate new_len (an overestimate is OK) */
305  Assert(strlen(new_str) <= new_len);
306 
307  return new_str;
308 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
static int integer_digits(const char *my_str)
Definition: print.c:211
static int groupdigits
Definition: print.c:52
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define Assert(condition)
Definition: c.h:675
static char * decimal_point
Definition: print.c:51
int i
static char * thousands_sep
Definition: print.c:53
static int additional_numeric_locale_len(const char *my_str)
Definition: print.c:222
static void fputnbytes ( FILE *  f,
const char *  str,
size_t  n 
)
static

Definition at line 318 of file print.c.

Referenced by print_aligned_text(), and print_aligned_vertical().

319 {
320  while (n-- > 0)
321  fputc(*str++, f);
322 }
const printTextFormat* get_line_style ( const printTableOpt opt)

Definition at line 3412 of file print.c.

References printTableOpt::line_style, NULL, and pg_asciiformat.

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

3413 {
3414  /*
3415  * Note: this function mainly exists to preserve the convention that a
3416  * printTableOpt struct can be initialized to zeroes to get default
3417  * behavior.
3418  */
3419  if (opt->line_style != NULL)
3420  return opt->line_style;
3421  else
3422  return &pg_asciiformat;
3423 }
const printTextFormat * line_style
Definition: print.h:112
#define NULL
Definition: c.h:229
const printTextFormat pg_asciiformat
Definition: print.c:59
void html_escaped_print ( const char *  in,
FILE *  fout 
)

Definition at line 1745 of file print.c.

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

1746 {
1747  const char *p;
1748  bool leading_space = true;
1749 
1750  for (p = in; *p; p++)
1751  {
1752  switch (*p)
1753  {
1754  case '&':
1755  fputs("&amp;", fout);
1756  break;
1757  case '<':
1758  fputs("&lt;", fout);
1759  break;
1760  case '>':
1761  fputs("&gt;", fout);
1762  break;
1763  case '\n':
1764  fputs("<br />\n", fout);
1765  break;
1766  case '"':
1767  fputs("&quot;", fout);
1768  break;
1769  case ' ':
1770  /* protect leading space, for EXPLAIN output */
1771  if (leading_space)
1772  fputs("&nbsp;", fout);
1773  else
1774  fputs(" ", fout);
1775  break;
1776  default:
1777  fputc(*p, fout);
1778  }
1779  if (*p != ' ')
1780  leading_space = false;
1781  }
1782 }
static int integer_digits ( const char *  my_str)
static

Definition at line 211 of file print.c.

Referenced by additional_numeric_locale_len(), and format_numeric_locale().

212 {
213  /* ignoring any sign ... */
214  if (my_str[0] == '-' || my_str[0] == '+')
215  my_str++;
216  /* ... count initial integral digits */
217  return strspn(my_str, "0123456789");
218 }
static void IsPagerNeeded ( const printTableContent cont,
int  extra_lines,
bool  expanded,
FILE **  fout,
bool is_pager 
)
static

Definition at line 3148 of file print.c.

References printTableContent::footers, printTableContent::ncolumns, printTableFooter::next, printTableContent::nrows, printTableContent::opt, PageOutput(), and printTableOpt::tuples_only.

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

3150 {
3151  if (*fout == stdout)
3152  {
3153  int lines;
3154 
3155  if (expanded)
3156  lines = (cont->ncolumns + 1) * cont->nrows;
3157  else
3158  lines = cont->nrows + 1;
3159 
3160  if (!cont->opt->tuples_only)
3161  {
3162  printTableFooter *f;
3163 
3164  /*
3165  * FIXME -- this is slightly bogus: it counts the number of
3166  * footers, not the number of lines in them.
3167  */
3168  for (f = cont->footers; f; f = f->next)
3169  lines++;
3170  }
3171 
3172  *fout = PageOutput(lines + extra_lines, cont->opt);
3173  *is_pager = (*fout != stdout);
3174  }
3175  else
3176  *is_pager = false;
3177 }
const printTableOpt * opt
Definition: print.h:145
struct printTableFooter * next
Definition: print.h:136
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:2851
bool tuples_only
Definition: print.h:107
printTableFooter * footers
Definition: print.h:156
static void latex_escaped_print ( const char *  in,
FILE *  fout 
)
static

Definition at line 2183 of file print.c.

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

2184 {
2185  const char *p;
2186 
2187  for (p = in; *p; p++)
2188  switch (*p)
2189  {
2190  case '&':
2191  fputs("\\&", fout);
2192  break;
2193  case '%':
2194  fputs("\\%", fout);
2195  break;
2196  case '$':
2197  fputs("\\$", fout);
2198  break;
2199  case '_':
2200  fputs("\\_", fout);
2201  break;
2202  case '{':
2203  fputs("\\{", fout);
2204  break;
2205  case '}':
2206  fputs("\\}", fout);
2207  break;
2208  case '\\':
2209  fputs("\\backslash", fout);
2210  break;
2211  case '\n':
2212  fputs("\\\\", fout);
2213  break;
2214  default:
2215  fputc(*p, fout);
2216  }
2217 }
FILE* PageOutput ( int  lines,
const printTableOpt topt 
)

Definition at line 2851 of file print.c.

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

Referenced by exec_command_sf(), exec_command_sv(), ExecQueryUsingCursor(), helpSQL(), helpVariables(), IsPagerNeeded(), print_aligned_text(), printHistory(), slashUsage(), and usage().

2852 {
2853  /* check whether we need / can / are supposed to use pager */
2854  if (topt && topt->pager && isatty(fileno(stdin)) && isatty(fileno(stdout)))
2855  {
2856 #ifdef TIOCGWINSZ
2857  unsigned short int pager = topt->pager;
2858  int min_lines = topt->pager_min_lines;
2859  int result;
2860  struct winsize screen_size;
2861 
2862  result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size);
2863 
2864  /* >= accounts for a one-line prompt */
2865  if (result == -1
2866  || (lines >= screen_size.ws_row && lines >= min_lines)
2867  || pager > 1)
2868 #endif
2869  {
2870  const char *pagerprog;
2871  FILE *pagerpipe;
2872 
2873  pagerprog = getenv("PAGER");
2874  if (!pagerprog)
2875  pagerprog = DEFAULT_PAGER;
2876  else
2877  {
2878  /* if PAGER is empty or all-white-space, don't use pager */
2879  if (strspn(pagerprog, " \t\r\n") == strlen(pagerprog))
2880  return stdout;
2881  }
2883  pagerpipe = popen(pagerprog, "w");
2884  if (pagerpipe)
2885  return pagerpipe;
2886  /* if popen fails, silently proceed without pager */
2888  }
2889  }
2890 
2891  return stdout;
2892 }
void disable_sigpipe_trap(void)
Definition: print.c:2801
return result
Definition: formatting.c:1632
void restore_sigpipe_trap(void)
Definition: print.c:2824
unsigned short int pager
Definition: print.h:103
int pager_min_lines
Definition: print.h:105
#define DEFAULT_PAGER
Definition: print.h:21
static void print_aligned_text ( const printTableContent cont,
FILE *  fout,
bool  is_pager 
)
static

Definition at line 582 of file print.c.

References _print_horizontal_line(), printTableContent::aligns, printTableOpt::border, cancel_pressed, printTableContent::cells, cleanup(), ClosePager(), printTableOpt::columns, printTableFooter::data, printTableOpt::encoding, encoding, printTableOpt::env_columns, printTableOpt::expanded, footers_with_default(), format, printTableOpt::format, fputnbytes(), free, get_line_style(), printTextFormat::header_nl_left, printTextFormat::header_nl_right, printTableContent::headers, i, IsPagerNeeded(), printTextLineFormat::leftvrule, printTextFormat::lrule, printTextLineFormat::midvrule, printTextFormat::midvrule_blank, printTextFormat::midvrule_nl, printTextFormat::midvrule_wrap, printTableContent::ncolumns, printTableFooter::next, printTextFormat::nl_left, printTextFormat::nl_right, NULL, printTableContent::opt, PageOutput(), pg_malloc(), pg_malloc0(), 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, printTextLineFormat::rightvrule, printTableOpt::start_table, printTableOpt::stop_table, strlen_max_width(), printTableContent::title, printTableOpt::tuples_only, lineptr::width, printTextFormat::wrap_left, printTextFormat::wrap_right, and printTextFormat::wrap_right_border.

Referenced by printTable().

583 {
584  bool opt_tuples_only = cont->opt->tuples_only;
585  int encoding = cont->opt->encoding;
586  unsigned short opt_border = cont->opt->border;
587  const printTextFormat *format = get_line_style(cont->opt);
588  const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
589 
590  unsigned int col_count = 0,
591  cell_count = 0;
592 
593  unsigned int i,
594  j;
595 
596  unsigned int *width_header,
597  *max_width,
598  *width_wrap,
599  *width_average;
600  unsigned int *max_nl_lines, /* value split by newlines */
601  *curr_nl_line,
602  *max_bytes;
603  unsigned char **format_buf;
604  unsigned int width_total;
605  unsigned int total_header_width;
606  unsigned int extra_row_output_lines = 0;
607  unsigned int extra_output_lines = 0;
608 
609  const char *const * ptr;
610 
611  struct lineptr **col_lineptrs; /* pointers to line pointer per column */
612 
613  bool *header_done; /* Have all header lines been output? */
614  int *bytes_output; /* Bytes output for column value */
615  printTextLineWrap *wrap; /* Wrap status for each column */
616  int output_columns = 0; /* Width of interactive console */
617  bool is_local_pager = false;
618 
619  if (cancel_pressed)
620  return;
621 
622  if (opt_border > 2)
623  opt_border = 2;
624 
625  if (cont->ncolumns > 0)
626  {
627  col_count = cont->ncolumns;
628  width_header = pg_malloc0(col_count * sizeof(*width_header));
629  width_average = pg_malloc0(col_count * sizeof(*width_average));
630  max_width = pg_malloc0(col_count * sizeof(*max_width));
631  width_wrap = pg_malloc0(col_count * sizeof(*width_wrap));
632  max_nl_lines = pg_malloc0(col_count * sizeof(*max_nl_lines));
633  curr_nl_line = pg_malloc0(col_count * sizeof(*curr_nl_line));
634  col_lineptrs = pg_malloc0(col_count * sizeof(*col_lineptrs));
635  max_bytes = pg_malloc0(col_count * sizeof(*max_bytes));
636  format_buf = pg_malloc0(col_count * sizeof(*format_buf));
637  header_done = pg_malloc0(col_count * sizeof(*header_done));
638  bytes_output = pg_malloc0(col_count * sizeof(*bytes_output));
639  wrap = pg_malloc0(col_count * sizeof(*wrap));
640  }
641  else
642  {
643  width_header = NULL;
644  width_average = NULL;
645  max_width = NULL;
646  width_wrap = NULL;
647  max_nl_lines = NULL;
648  curr_nl_line = NULL;
649  col_lineptrs = NULL;
650  max_bytes = NULL;
651  format_buf = NULL;
652  header_done = NULL;
653  bytes_output = NULL;
654  wrap = NULL;
655  }
656 
657  /* scan all column headers, find maximum width and max max_nl_lines */
658  for (i = 0; i < col_count; i++)
659  {
660  int width,
661  nl_lines,
662  bytes_required;
663 
664  pg_wcssize((const unsigned char *) cont->headers[i], strlen(cont->headers[i]),
665  encoding, &width, &nl_lines, &bytes_required);
666  if (width > max_width[i])
667  max_width[i] = width;
668  if (nl_lines > max_nl_lines[i])
669  max_nl_lines[i] = nl_lines;
670  if (bytes_required > max_bytes[i])
671  max_bytes[i] = bytes_required;
672  if (nl_lines > extra_row_output_lines)
673  extra_row_output_lines = nl_lines;
674 
675  width_header[i] = width;
676  }
677  /* Add height of tallest header column */
678  extra_output_lines += extra_row_output_lines;
679  extra_row_output_lines = 0;
680 
681  /* scan all cells, find maximum width, compute cell_count */
682  for (i = 0, ptr = cont->cells; *ptr; ptr++, i++, cell_count++)
683  {
684  int width,
685  nl_lines,
686  bytes_required;
687 
688  pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding,
689  &width, &nl_lines, &bytes_required);
690 
691  if (width > max_width[i % col_count])
692  max_width[i % col_count] = width;
693  if (nl_lines > max_nl_lines[i % col_count])
694  max_nl_lines[i % col_count] = nl_lines;
695  if (bytes_required > max_bytes[i % col_count])
696  max_bytes[i % col_count] = bytes_required;
697 
698  width_average[i % col_count] += width;
699  }
700 
701  /* If we have rows, compute average */
702  if (col_count != 0 && cell_count != 0)
703  {
704  int rows = cell_count / col_count;
705 
706  for (i = 0; i < col_count; i++)
707  width_average[i] /= rows;
708  }
709 
710  /* adjust the total display width based on border style */
711  if (opt_border == 0)
712  width_total = col_count;
713  else if (opt_border == 1)
714  width_total = col_count * 3 - ((col_count > 0) ? 1 : 0);
715  else
716  width_total = col_count * 3 + 1;
717  total_header_width = width_total;
718 
719  for (i = 0; i < col_count; i++)
720  {
721  width_total += max_width[i];
722  total_header_width += width_header[i];
723  }
724 
725  /*
726  * At this point: max_width[] contains the max width of each column,
727  * max_nl_lines[] contains the max number of lines in each column,
728  * max_bytes[] contains the maximum storage space for formatting strings,
729  * width_total contains the giant width sum. Now we allocate some memory
730  * for line pointers.
731  */
732  for (i = 0; i < col_count; i++)
733  {
734  /* Add entry for ptr == NULL array termination */
735  col_lineptrs[i] = pg_malloc0((max_nl_lines[i] + 1) *
736  sizeof(**col_lineptrs));
737 
738  format_buf[i] = pg_malloc(max_bytes[i] + 1);
739 
740  col_lineptrs[i]->ptr = format_buf[i];
741  }
742 
743  /* Default word wrap to the full width, i.e. no word wrap */
744  for (i = 0; i < col_count; i++)
745  width_wrap[i] = max_width[i];
746 
747  /*
748  * Choose target output width: \pset columns, or $COLUMNS, or ioctl
749  */
750  if (cont->opt->columns > 0)
751  output_columns = cont->opt->columns;
752  else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
753  {
754  if (cont->opt->env_columns > 0)
755  output_columns = cont->opt->env_columns;
756 #ifdef TIOCGWINSZ
757  else
758  {
759  struct winsize screen_size;
760 
761  if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1)
762  output_columns = screen_size.ws_col;
763  }
764 #endif
765  }
766 
767  if (cont->opt->format == PRINT_WRAPPED)
768  {
769  /*
770  * Optional optimized word wrap. Shrink columns with a high max/avg
771  * ratio. Slightly bias against wider columns. (Increases chance a
772  * narrow column will fit in its cell.) If available columns is
773  * positive... and greater than the width of the unshrinkable column
774  * headers
775  */
776  if (output_columns > 0 && output_columns >= total_header_width)
777  {
778  /* While there is still excess width... */
779  while (width_total > output_columns)
780  {
781  double max_ratio = 0;
782  int worst_col = -1;
783 
784  /*
785  * Find column that has the highest ratio of its maximum width
786  * compared to its average width. This tells us which column
787  * will produce the fewest wrapped values if shortened.
788  * width_wrap starts as equal to max_width.
789  */
790  for (i = 0; i < col_count; i++)
791  {
792  if (width_average[i] && width_wrap[i] > width_header[i])
793  {
794  /* Penalize wide columns by 1% of their width */
795  double ratio;
796 
797  ratio = (double) width_wrap[i] / width_average[i] +
798  max_width[i] * 0.01;
799  if (ratio > max_ratio)
800  {
801  max_ratio = ratio;
802  worst_col = i;
803  }
804  }
805  }
806 
807  /* Exit loop if we can't squeeze any more. */
808  if (worst_col == -1)
809  break;
810 
811  /* Decrease width of target column by one. */
812  width_wrap[worst_col]--;
813  width_total--;
814  }
815  }
816  }
817 
818  /*
819  * If in expanded auto mode, we have now calculated the expected width, so
820  * we can now escape to vertical mode if necessary. If the output has
821  * only one column, the expanded format would be wider than the regular
822  * format, so don't use it in that case.
823  */
824  if (cont->opt->expanded == 2 && output_columns > 0 && cont->ncolumns > 1 &&
825  (output_columns < total_header_width || output_columns < width_total))
826  {
827  print_aligned_vertical(cont, fout, is_pager);
828  goto cleanup;
829  }
830 
831  /* If we wrapped beyond the display width, use the pager */
832  if (!is_pager && fout == stdout && output_columns > 0 &&
833  (output_columns < total_header_width || output_columns < width_total))
834  {
835  fout = PageOutput(INT_MAX, cont->opt); /* force pager */
836  is_pager = is_local_pager = true;
837  }
838 
839  /* Check if newlines or our wrapping now need the pager */
840  if (!is_pager && fout == stdout)
841  {
842  /* scan all cells, find maximum width, compute cell_count */
843  for (i = 0, ptr = cont->cells; *ptr; ptr++, cell_count++)
844  {
845  int width,
846  nl_lines,
847  bytes_required;
848 
849  pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding,
850  &width, &nl_lines, &bytes_required);
851 
852  /*
853  * A row can have both wrapping and newlines that cause it to
854  * display across multiple lines. We check for both cases below.
855  */
856  if (width > 0 && width_wrap[i])
857  {
858  unsigned int extra_lines;
859 
860  /* don't count the first line of nl_lines - it's not "extra" */
861  extra_lines = ((width - 1) / width_wrap[i]) + nl_lines - 1;
862  if (extra_lines > extra_row_output_lines)
863  extra_row_output_lines = extra_lines;
864  }
865 
866  /* i is the current column number: increment with wrap */
867  if (++i >= col_count)
868  {
869  i = 0;
870  /* At last column of each row, add tallest column height */
871  extra_output_lines += extra_row_output_lines;
872  extra_row_output_lines = 0;
873  }
874  }
875  IsPagerNeeded(cont, extra_output_lines, false, &fout, &is_pager);
876  is_local_pager = is_pager;
877  }
878 
879  /* time to output */
880  if (cont->opt->start_table)
881  {
882  /* print title */
883  if (cont->title && !opt_tuples_only)
884  {
885  int width,
886  height;
887 
888  pg_wcssize((const unsigned char *) cont->title, strlen(cont->title),
889  encoding, &width, &height, NULL);
890  if (width >= width_total)
891  /* Aligned */
892  fprintf(fout, "%s\n", cont->title);
893  else
894  /* Centered */
895  fprintf(fout, "%-*s%s\n", (width_total - width) / 2, "",
896  cont->title);
897  }
898 
899  /* print headers */
900  if (!opt_tuples_only)
901  {
902  int more_col_wrapping;
903  int curr_nl_line;
904 
905  if (opt_border == 2)
906  _print_horizontal_line(col_count, width_wrap, opt_border,
907  PRINT_RULE_TOP, format, fout);
908 
909  for (i = 0; i < col_count; i++)
910  pg_wcsformat((const unsigned char *) cont->headers[i],
911  strlen(cont->headers[i]), encoding,
912  col_lineptrs[i], max_nl_lines[i]);
913 
914  more_col_wrapping = col_count;
915  curr_nl_line = 0;
916  memset(header_done, false, col_count * sizeof(bool));
917  while (more_col_wrapping)
918  {
919  if (opt_border == 2)
920  fputs(dformat->leftvrule, fout);
921 
922  for (i = 0; i < cont->ncolumns; i++)
923  {
924  struct lineptr *this_line = col_lineptrs[i] + curr_nl_line;
925  unsigned int nbspace;
926 
927  if (opt_border != 0 ||
928  (!format->wrap_right_border && i > 0))
929  fputs(curr_nl_line ? format->header_nl_left : " ",
930  fout);
931 
932  if (!header_done[i])
933  {
934  nbspace = width_wrap[i] - this_line->width;
935 
936  /* centered */
937  fprintf(fout, "%-*s%s%-*s",
938  nbspace / 2, "", this_line->ptr, (nbspace + 1) / 2, "");
939 
940  if (!(this_line + 1)->ptr)
941  {
942  more_col_wrapping--;
943  header_done[i] = 1;
944  }
945  }
946  else
947  fprintf(fout, "%*s", width_wrap[i], "");
948 
949  if (opt_border != 0 || format->wrap_right_border)
950  fputs(!header_done[i] ? format->header_nl_right : " ",
951  fout);
952 
953  if (opt_border != 0 && col_count > 0 && i < col_count - 1)
954  fputs(dformat->midvrule, fout);
955  }
956  curr_nl_line++;
957 
958  if (opt_border == 2)
959  fputs(dformat->rightvrule, fout);
960  fputc('\n', fout);
961  }
962 
963  _print_horizontal_line(col_count, width_wrap, opt_border,
964  PRINT_RULE_MIDDLE, format, fout);
965  }
966  }
967 
968  /* print cells, one loop per row */
969  for (i = 0, ptr = cont->cells; *ptr; i += col_count, ptr += col_count)
970  {
971  bool more_lines;
972 
973  if (cancel_pressed)
974  break;
975 
976  /*
977  * Format each cell.
978  */
979  for (j = 0; j < col_count; j++)
980  {
981  pg_wcsformat((const unsigned char *) ptr[j], strlen(ptr[j]), encoding,
982  col_lineptrs[j], max_nl_lines[j]);
983  curr_nl_line[j] = 0;
984  }
985 
986  memset(bytes_output, 0, col_count * sizeof(int));
987 
988  /*
989  * Each time through this loop, one display line is output. It can
990  * either be a full value or a partial value if embedded newlines
991  * exist or if 'format=wrapping' mode is enabled.
992  */
993  do
994  {
995  more_lines = false;
996 
997  /* left border */
998  if (opt_border == 2)
999  fputs(dformat->leftvrule, fout);
1000 
1001  /* for each column */
1002  for (j = 0; j < col_count; j++)
1003  {
1004  /* We have a valid array element, so index it */
1005  struct lineptr *this_line = &col_lineptrs[j][curr_nl_line[j]];
1006  int bytes_to_output;
1007  int chars_to_output = width_wrap[j];
1008  bool finalspaces = (opt_border == 2 ||
1009  (col_count > 0 && j < col_count - 1));
1010 
1011  /* Print left-hand wrap or newline mark */
1012  if (opt_border != 0)
1013  {
1014  if (wrap[j] == PRINT_LINE_WRAP_WRAP)
1015  fputs(format->wrap_left, fout);
1016  else if (wrap[j] == PRINT_LINE_WRAP_NEWLINE)
1017  fputs(format->nl_left, fout);
1018  else
1019  fputc(' ', fout);
1020  }
1021 
1022  if (!this_line->ptr)
1023  {
1024  /* Past newline lines so just pad for other columns */
1025  if (finalspaces)
1026  fprintf(fout, "%*s", chars_to_output, "");
1027  }
1028  else
1029  {
1030  /* Get strlen() of the characters up to width_wrap */
1031  bytes_to_output =
1032  strlen_max_width(this_line->ptr + bytes_output[j],
1033  &chars_to_output, encoding);
1034 
1035  /*
1036  * If we exceeded width_wrap, it means the display width
1037  * of a single character was wider than our target width.
1038  * In that case, we have to pretend we are only printing
1039  * the target display width and make the best of it.
1040  */
1041  if (chars_to_output > width_wrap[j])
1042  chars_to_output = width_wrap[j];
1043 
1044  if (cont->aligns[j] == 'r') /* Right aligned cell */
1045  {
1046  /* spaces first */
1047  fprintf(fout, "%*s", width_wrap[j] - chars_to_output, "");
1048  fputnbytes(fout,
1049  (char *) (this_line->ptr + bytes_output[j]),
1050  bytes_to_output);
1051  }
1052  else /* Left aligned cell */
1053  {
1054  /* spaces second */
1055  fputnbytes(fout,
1056  (char *) (this_line->ptr + bytes_output[j]),
1057  bytes_to_output);
1058  }
1059 
1060  bytes_output[j] += bytes_to_output;
1061 
1062  /* Do we have more text to wrap? */
1063  if (*(this_line->ptr + bytes_output[j]) != '\0')
1064  more_lines = true;
1065  else
1066  {
1067  /* Advance to next newline line */
1068  curr_nl_line[j]++;
1069  if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
1070  more_lines = true;
1071  bytes_output[j] = 0;
1072  }
1073  }
1074 
1075  /* Determine next line's wrap status for this column */
1076  wrap[j] = PRINT_LINE_WRAP_NONE;
1077  if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
1078  {
1079  if (bytes_output[j] != 0)
1080  wrap[j] = PRINT_LINE_WRAP_WRAP;
1081  else if (curr_nl_line[j] != 0)
1082  wrap[j] = PRINT_LINE_WRAP_NEWLINE;
1083  }
1084 
1085  /*
1086  * If left-aligned, pad out remaining space if needed (not
1087  * last column, and/or wrap marks required).
1088  */
1089  if (cont->aligns[j] != 'r') /* Left aligned cell */
1090  {
1091  if (finalspaces ||
1092  wrap[j] == PRINT_LINE_WRAP_WRAP ||
1093  wrap[j] == PRINT_LINE_WRAP_NEWLINE)
1094  fprintf(fout, "%*s",
1095  width_wrap[j] - chars_to_output, "");
1096  }
1097 
1098  /* Print right-hand wrap or newline mark */
1099  if (wrap[j] == PRINT_LINE_WRAP_WRAP)
1100  fputs(format->wrap_right, fout);
1101  else if (wrap[j] == PRINT_LINE_WRAP_NEWLINE)
1102  fputs(format->nl_right, fout);
1103  else if (opt_border == 2 || (col_count > 0 && j < col_count - 1))
1104  fputc(' ', fout);
1105 
1106  /* Print column divider, if not the last column */
1107  if (opt_border != 0 && (col_count > 0 && j < col_count - 1))
1108  {
1109  if (wrap[j + 1] == PRINT_LINE_WRAP_WRAP)
1110  fputs(format->midvrule_wrap, fout);
1111  else if (wrap[j + 1] == PRINT_LINE_WRAP_NEWLINE)
1112  fputs(format->midvrule_nl, fout);
1113  else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL)
1114  fputs(format->midvrule_blank, fout);
1115  else
1116  fputs(dformat->midvrule, fout);
1117  }
1118  }
1119 
1120  /* end-of-row border */
1121  if (opt_border == 2)
1122  fputs(dformat->rightvrule, fout);
1123  fputc('\n', fout);
1124 
1125  } while (more_lines);
1126  }
1127 
1128  if (cont->opt->stop_table)
1129  {
1130  printTableFooter *footers = footers_with_default(cont);
1131 
1132  if (opt_border == 2 && !cancel_pressed)
1133  _print_horizontal_line(col_count, width_wrap, opt_border,
1134  PRINT_RULE_BOTTOM, format, fout);
1135 
1136  /* print footers */
1137  if (footers && !opt_tuples_only && !cancel_pressed)
1138  {
1139  printTableFooter *f;
1140 
1141  for (f = footers; f; f = f->next)
1142  fprintf(fout, "%s\n", f->data);
1143  }
1144 
1145  fputc('\n', fout);
1146  }
1147 
1148 cleanup:
1149  /* clean up */
1150  for (i = 0; i < col_count; i++)
1151  {
1152  free(col_lineptrs[i]);
1153  free(format_buf[i]);
1154  }
1155  free(width_header);
1156  free(width_average);
1157  free(max_width);
1158  free(width_wrap);
1159  free(max_nl_lines);
1160  free(curr_nl_line);
1161  free(col_lineptrs);
1162  free(max_bytes);
1163  free(format_buf);
1164  free(header_done);
1165  free(bytes_output);
1166  free(wrap);
1167 
1168  if (is_local_pager)
1169  ClosePager(fout);
1170 }
const char * midvrule
Definition: print.h:45
int env_columns
Definition: print.h:119
const char * title
Definition: print.h:146
int encoding
Definition: print.h:118
void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, struct lineptr *lines, int count)
Definition: mbprint.c:294
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
const char * midvrule_wrap
Definition: print.h:72
static printTableFooter * footers_with_default(const printTableContent *cont)
Definition: print.c:345
const char * header_nl_left
Definition: print.h:74
void ClosePager(FILE *pagerpipe)
Definition: print.c:2900
bool wrap_right_border
Definition: print.h:80
bool start_table
Definition: print.h:108
enum printFormat format
Definition: print.h:98
static void print_aligned_vertical(const printTableContent *cont, FILE *fout, bool is_pager)
Definition: print.c:1230
printTextLineFormat lrule[4]
Definition: print.h:70
const printTableOpt * opt
Definition: print.h:145
printTextLineWrap
Definition: print.h:58
const char * midvrule_blank
Definition: print.h:73
struct printTableFooter * next
Definition: print.h:136
const char * header_nl_right
Definition: print.h:75
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
volatile bool cancel_pressed
Definition: print.c:46
static void IsPagerNeeded(const printTableContent *cont, int extra_lines, bool expanded, FILE **fout, bool *is_pager)
Definition: print.c:3148
unsigned short int border
Definition: print.h:101
char * aligns
Definition: print.h:158
unsigned short int expanded
Definition: print.h:99
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:2851
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
const char * midvrule_nl
Definition: print.h:71
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
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:540
const char * leftvrule
Definition: print.h:44
static void cleanup(void)
Definition: bootstrap.c:855
bool stop_table
Definition: print.h:109
static char * encoding
Definition: initdb.c:122
#define free(a)
Definition: header.h:65
const printTextFormat * get_line_style(const printTableOpt *opt)
Definition: print.c:3412
#define NULL
Definition: c.h:229
const char * nl_right
Definition: print.h:77
int width
Definition: mbprint.h:19
static int strlen_max_width(unsigned char *str, int *target_width, int encoding)
Definition: print.c:3483
const char * nl_left
Definition: print.h:76
const char * rightvrule
Definition: print.h:46
static void fputnbytes(FILE *f, const char *str, size_t n)
Definition: print.c:318
const char * wrap_left
Definition: print.h:78
int i
char * data
Definition: print.h:135
const char * wrap_right
Definition: print.h:79
static char format
Definition: pg_basebackup.c:80
unsigned char * ptr
Definition: mbprint.h:18
const char ** headers
Definition: print.h:149
int columns
Definition: print.h:120
static void print_aligned_vertical ( const printTableContent cont,
FILE *  fout,
bool  is_pager 
)
static

Definition at line 1230 of file print.c.

References printTableOpt::border, cancel_pressed, printTableContent::cells, ClosePager(), printTableOpt::columns, printTableFooter::data, printTableOpt::encoding, encoding, printTableOpt::env_columns, printTableContent::footers, footers_with_default(), format, printTableOpt::format, fputnbytes(), free, get_line_style(), printTextFormat::header_nl_left, printTextFormat::header_nl_right, printTableContent::headers, i, IsPagerNeeded(), printTextLineFormat::leftvrule, printTextFormat::lrule, printTextLineFormat::midvrule, printTextFormat::midvrule_nl, printTextFormat::midvrule_wrap, printTableContent::ncolumns, printTableFooter::next, printTextFormat::nl_right, printTableContent::nrows, NULL, printTableContent::opt, pg_malloc(), pg_wcsformat(), pg_wcssize(), print_aligned_vertical_line(), PRINT_RULE_BOTTOM, PRINT_RULE_DATA, PRINT_RULE_MIDDLE, PRINT_RULE_TOP, PRINT_WRAPPED, printTableOpt::prior_records, lineptr::ptr, printTextLineFormat::rightvrule, printTableOpt::start_table, printTableOpt::stop_table, strlen_max_width(), printTableContent::title, printTableOpt::tuples_only, lineptr::width, printTextFormat::wrap_left, and printTextFormat::wrap_right.

Referenced by print_aligned_text(), and printTable().

1232 {
1233  bool opt_tuples_only = cont->opt->tuples_only;
1234  unsigned short opt_border = cont->opt->border;
1235  const printTextFormat *format = get_line_style(cont->opt);
1236  const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
1237  int encoding = cont->opt->encoding;
1238  unsigned long record = cont->opt->prior_records + 1;
1239  const char *const * ptr;
1240  unsigned int i,
1241  hwidth = 0,
1242  dwidth = 0,
1243  hheight = 1,
1244  dheight = 1,
1245  hformatsize = 0,
1246  dformatsize = 0;
1247  struct lineptr *hlineptr,
1248  *dlineptr;
1249  bool is_local_pager = false,
1250  hmultiline = false,
1251  dmultiline = false;
1252  int output_columns = 0; /* Width of interactive console */
1253 
1254  if (cancel_pressed)
1255  return;
1256 
1257  if (opt_border > 2)
1258  opt_border = 2;
1259 
1260  if (cont->cells[0] == NULL && cont->opt->start_table &&
1261  cont->opt->stop_table)
1262  {
1263  printTableFooter *footers = footers_with_default(cont);
1264 
1265  if (!opt_tuples_only && !cancel_pressed && footers)
1266  {
1267  printTableFooter *f;
1268 
1269  for (f = footers; f; f = f->next)
1270  fprintf(fout, "%s\n", f->data);
1271  }
1272 
1273  fputc('\n', fout);
1274 
1275  return;
1276  }
1277 
1278  /*
1279  * Deal with the pager here instead of in printTable(), because we could
1280  * get here via print_aligned_text() in expanded auto mode, and so we have
1281  * to recalculate the pager requirement based on vertical output.
1282  */
1283  if (!is_pager)
1284  {
1285  IsPagerNeeded(cont, 0, true, &fout, &is_pager);
1286  is_local_pager = is_pager;
1287  }
1288 
1289  /* Find the maximum dimensions for the headers */
1290  for (i = 0; i < cont->ncolumns; i++)
1291  {
1292  int width,
1293  height,
1294  fs;
1295 
1296  pg_wcssize((const unsigned char *) cont->headers[i], strlen(cont->headers[i]),
1297  encoding, &width, &height, &fs);
1298  if (width > hwidth)
1299  hwidth = width;
1300  if (height > hheight)
1301  {
1302  hheight = height;
1303  hmultiline = true;
1304  }
1305  if (fs > hformatsize)
1306  hformatsize = fs;
1307  }
1308 
1309  /* find longest data cell */
1310  for (i = 0, ptr = cont->cells; *ptr; ptr++, i++)
1311  {
1312  int width,
1313  height,
1314  fs;
1315 
1316  pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding,
1317  &width, &height, &fs);
1318  if (width > dwidth)
1319  dwidth = width;
1320  if (height > dheight)
1321  {
1322  dheight = height;
1323  dmultiline = true;
1324  }
1325  if (fs > dformatsize)
1326  dformatsize = fs;
1327  }
1328 
1329  /*
1330  * We now have all the information we need to setup the formatting
1331  * structures
1332  */
1333  dlineptr = pg_malloc((sizeof(*dlineptr)) * (dheight + 1));
1334  hlineptr = pg_malloc((sizeof(*hlineptr)) * (hheight + 1));
1335 
1336  dlineptr->ptr = pg_malloc(dformatsize);
1337  hlineptr->ptr = pg_malloc(hformatsize);
1338 
1339  if (cont->opt->start_table)
1340  {
1341  /* print title */
1342  if (!opt_tuples_only && cont->title)
1343  fprintf(fout, "%s\n", cont->title);
1344  }
1345 
1346  /*
1347  * Choose target output width: \pset columns, or $COLUMNS, or ioctl
1348  */
1349  if (cont->opt->columns > 0)
1350  output_columns = cont->opt->columns;
1351  else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
1352  {
1353  if (cont->opt->env_columns > 0)
1354  output_columns = cont->opt->env_columns;
1355 #ifdef TIOCGWINSZ
1356  else
1357  {
1358  struct winsize screen_size;
1359 
1360  if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1)
1361  output_columns = screen_size.ws_col;
1362  }
1363 #endif
1364  }
1365 
1366  /*
1367  * Calculate available width for data in wrapped mode
1368  */
1369  if (cont->opt->format == PRINT_WRAPPED)
1370  {
1371  unsigned int swidth,
1372  rwidth = 0,
1373  newdwidth;
1374 
1375  if (opt_border == 0)
1376  {
1377  /*
1378  * For border = 0, one space in the middle. (If we discover we
1379  * need to wrap, the spacer column will be replaced by a wrap
1380  * marker, and we'll make room below for another wrap marker at
1381  * the end of the line. But for now, assume no wrap is needed.)
1382  */
1383  swidth = 1;
1384 
1385  /* We might need a column for header newline markers, too */
1386  if (hmultiline)
1387  swidth++;
1388  }
1389  else if (opt_border == 1)
1390  {
1391  /*
1392  * For border = 1, two spaces and a vrule in the middle. (As
1393  * above, we might need one more column for a wrap marker.)
1394  */
1395  swidth = 3;
1396 
1397  /* We might need a column for left header newline markers, too */
1398  if (hmultiline && (format == &pg_asciiformat_old))
1399  swidth++;
1400  }
1401  else
1402  {
1403  /*
1404  * For border = 2, two more for the vrules at the beginning and
1405  * end of the lines, plus spacer columns adjacent to these. (We
1406  * won't need extra columns for wrap/newline markers, we'll just
1407  * repurpose the spacers.)
1408  */
1409  swidth = 7;
1410  }
1411 
1412  /* Reserve a column for data newline indicators, too, if needed */
1413  if (dmultiline &&
1414  opt_border < 2 && format != &pg_asciiformat_old)
1415  swidth++;
1416 
1417  /* Determine width required for record header lines */
1418  if (!opt_tuples_only)
1419  {
1420  if (cont->nrows > 0)
1421  rwidth = 1 + (int) log10(cont->nrows);
1422  if (opt_border == 0)
1423  rwidth += 9; /* "* RECORD " */
1424  else if (opt_border == 1)
1425  rwidth += 12; /* "-[ RECORD ]" */
1426  else
1427  rwidth += 15; /* "+-[ RECORD ]-+" */
1428  }
1429 
1430  /* We might need to do the rest of the calculation twice */
1431  for (;;)
1432  {
1433  unsigned int width;
1434 
1435  /* Total width required to not wrap data */
1436  width = hwidth + swidth + dwidth;
1437  /* ... and not the header lines, either */
1438  if (width < rwidth)
1439  width = rwidth;
1440 
1441  if (output_columns > 0)
1442  {
1443  unsigned int min_width;
1444 
1445  /* Minimum acceptable width: room for just 3 columns of data */
1446  min_width = hwidth + swidth + 3;
1447  /* ... but not less than what the record header lines need */
1448  if (min_width < rwidth)
1449  min_width = rwidth;
1450 
1451  if (output_columns >= width)
1452  {
1453  /* Plenty of room, use native data width */
1454  /* (but at least enough for the record header lines) */
1455  newdwidth = width - hwidth - swidth;
1456  }
1457  else if (output_columns < min_width)
1458  {
1459  /* Set data width to match min_width */
1460  newdwidth = min_width - hwidth - swidth;
1461  }
1462  else
1463  {
1464  /* Set data width to match output_columns */
1465  newdwidth = output_columns - hwidth - swidth;
1466  }
1467  }
1468  else
1469  {
1470  /* Don't know the wrap limit, so use native data width */
1471  /* (but at least enough for the record header lines) */
1472  newdwidth = width - hwidth - swidth;
1473  }
1474 
1475  /*
1476  * If we will need to wrap data and didn't already allocate a data
1477  * newline/wrap marker column, do so and recompute.
1478  */
1479  if (newdwidth < dwidth && !dmultiline &&
1480  opt_border < 2 && format != &pg_asciiformat_old)
1481  {
1482  dmultiline = true;
1483  swidth++;
1484  }
1485  else
1486  break;
1487  }
1488 
1489  dwidth = newdwidth;
1490  }
1491 
1492  /* print records */
1493  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1494  {
1495  printTextRule pos;
1496  int dline,
1497  hline,
1498  dcomplete,
1499  hcomplete,
1500  offset,
1501  chars_to_output;
1502 
1503  if (cancel_pressed)
1504  break;
1505 
1506  if (i == 0)
1507  pos = PRINT_RULE_TOP;
1508  else
1509  pos = PRINT_RULE_MIDDLE;
1510 
1511  /* Print record header (e.g. "[ RECORD N ]") above each record */
1512  if (i % cont->ncolumns == 0)
1513  {
1514  unsigned int lhwidth = hwidth;
1515 
1516  if ((opt_border < 2) &&
1517  (hmultiline) &&
1518  (format == &pg_asciiformat_old))
1519  lhwidth++; /* for newline indicators */
1520 
1521  if (!opt_tuples_only)
1522  print_aligned_vertical_line(format, opt_border, record++,
1523  lhwidth, dwidth, pos, fout);
1524  else if (i != 0 || !cont->opt->start_table || opt_border == 2)
1525  print_aligned_vertical_line(format, opt_border, 0, lhwidth,
1526  dwidth, pos, fout);
1527  }
1528 
1529  /* Format the header */
1530  pg_wcsformat((const unsigned char *) cont->headers[i % cont->ncolumns],
1531  strlen(cont->headers[i % cont->ncolumns]),
1532  encoding, hlineptr, hheight);
1533  /* Format the data */
1534  pg_wcsformat((const unsigned char *) *ptr, strlen(*ptr), encoding,
1535  dlineptr, dheight);
1536 
1537  /*
1538  * Loop through header and data in parallel dealing with newlines and
1539  * wrapped lines until they're both exhausted
1540  */
1541  dline = hline = 0;
1542  dcomplete = hcomplete = 0;
1543  offset = 0;
1544  chars_to_output = dlineptr[dline].width;
1545  while (!dcomplete || !hcomplete)
1546  {
1547  /* Left border */
1548  if (opt_border == 2)
1549  fprintf(fout, "%s", dformat->leftvrule);
1550 
1551  /* Header (never wrapped so just need to deal with newlines) */
1552  if (!hcomplete)
1553  {
1554  int swidth = hwidth,
1555  target_width = hwidth;
1556 
1557  /*
1558  * Left spacer or new line indicator
1559  */
1560  if ((opt_border == 2) ||
1561  (hmultiline && (format == &pg_asciiformat_old)))
1562  fputs(hline ? format->header_nl_left : " ", fout);
1563 
1564  /*
1565  * Header text
1566  */
1567  strlen_max_width(hlineptr[hline].ptr, &target_width,
1568  encoding);
1569  fprintf(fout, "%-s", hlineptr[hline].ptr);
1570 
1571  /*
1572  * Spacer
1573  */
1574  swidth -= target_width;
1575  if (swidth > 0)
1576  fprintf(fout, "%*s", swidth, " ");
1577 
1578  /*
1579  * New line indicator or separator's space
1580  */
1581  if (hlineptr[hline + 1].ptr)
1582  {
1583  /* More lines after this one due to a newline */
1584  if ((opt_border > 0) ||
1585  (hmultiline && (format != &pg_asciiformat_old)))
1586  fputs(format->header_nl_right, fout);
1587  hline++;
1588  }
1589  else
1590  {
1591  /* This was the last line of the header */
1592  if ((opt_border > 0) ||
1593  (hmultiline && (format != &pg_asciiformat_old)))
1594  fputs(" ", fout);
1595  hcomplete = 1;
1596  }
1597  }
1598  else
1599  {
1600  unsigned int swidth = hwidth + opt_border;
1601 
1602  if ((opt_border < 2) &&
1603  (hmultiline) &&
1604  (format == &pg_asciiformat_old))
1605  swidth++;
1606 
1607  if ((opt_border == 0) &&
1608  (format != &pg_asciiformat_old) &&
1609  (hmultiline))
1610  swidth++;
1611 
1612  fprintf(fout, "%*s", swidth, " ");
1613  }
1614 
1615  /* Separator */
1616  if (opt_border > 0)
1617  {
1618  if (offset)
1619  fputs(format->midvrule_wrap, fout);
1620  else if (dline == 0)
1621  fputs(dformat->midvrule, fout);
1622  else
1623  fputs(format->midvrule_nl, fout);
1624  }
1625 
1626  /* Data */
1627  if (!dcomplete)
1628  {
1629  int target_width = dwidth,
1630  bytes_to_output,
1631  swidth = dwidth;
1632 
1633  /*
1634  * Left spacer or wrap indicator
1635  */
1636  fputs(offset == 0 ? " " : format->wrap_left, fout);
1637 
1638  /*
1639  * Data text
1640  */
1641  bytes_to_output = strlen_max_width(dlineptr[dline].ptr + offset,
1642  &target_width, encoding);
1643  fputnbytes(fout, (char *) (dlineptr[dline].ptr + offset),
1644  bytes_to_output);
1645 
1646  chars_to_output -= target_width;
1647  offset += bytes_to_output;
1648 
1649  /* Spacer */
1650  swidth -= target_width;
1651 
1652  if (chars_to_output)
1653  {
1654  /* continuing a wrapped column */
1655  if ((opt_border > 1) ||
1656  (dmultiline && (format != &pg_asciiformat_old)))
1657  {
1658  if (swidth > 0)
1659  fprintf(fout, "%*s", swidth, " ");
1660  fputs(format->wrap_right, fout);
1661  }
1662  }
1663  else if (dlineptr[dline + 1].ptr)
1664  {
1665  /* reached a newline in the column */
1666  if ((opt_border > 1) ||
1667  (dmultiline && (format != &pg_asciiformat_old)))
1668  {
1669  if (swidth > 0)
1670  fprintf(fout, "%*s", swidth, " ");
1671  fputs(format->nl_right, fout);
1672  }
1673  dline++;
1674  offset = 0;
1675  chars_to_output = dlineptr[dline].width;
1676  }
1677  else
1678  {
1679  /* reached the end of the cell */
1680  if (opt_border > 1)
1681  {
1682  if (swidth > 0)
1683  fprintf(fout, "%*s", swidth, " ");
1684  fputs(" ", fout);
1685  }
1686  dcomplete = 1;
1687  }
1688 
1689  /* Right border */
1690  if (opt_border == 2)
1691  fputs(dformat->rightvrule, fout);
1692 
1693  fputs("\n", fout);
1694  }
1695  else
1696  {
1697  /*
1698  * data exhausted (this can occur if header is longer than the
1699  * data due to newlines in the header)
1700  */
1701  if (opt_border < 2)
1702  fputs("\n", fout);
1703  else
1704  fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule);
1705  }
1706  }
1707  }
1708 
1709  if (cont->opt->stop_table)
1710  {
1711  if (opt_border == 2 && !cancel_pressed)
1712  print_aligned_vertical_line(format, opt_border, 0, hwidth, dwidth,
1713  PRINT_RULE_BOTTOM, fout);
1714 
1715  /* print footers */
1716  if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
1717  {
1718  printTableFooter *f;
1719 
1720  if (opt_border < 2)
1721  fputc('\n', fout);
1722  for (f = cont->footers; f; f = f->next)
1723  fprintf(fout, "%s\n", f->data);
1724  }
1725 
1726  fputc('\n', fout);
1727  }
1728 
1729  free(hlineptr->ptr);
1730  free(dlineptr->ptr);
1731  free(hlineptr);
1732  free(dlineptr);
1733 
1734  if (is_local_pager)
1735  ClosePager(fout);
1736 }
const char * midvrule
Definition: print.h:45
int env_columns
Definition: print.h:119
const char * title
Definition: print.h:146
int encoding
Definition: print.h:118
void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, struct lineptr *lines, int count)
Definition: mbprint.c:294
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
const char * midvrule_wrap
Definition: print.h:72
static printTableFooter * footers_with_default(const printTableContent *cont)
Definition: print.c:345
const char * header_nl_left
Definition: print.h:74
static void print_aligned_vertical_line(const printTextFormat *format, const unsigned short opt_border, unsigned long record, unsigned int hwidth, unsigned int dwidth, printTextRule pos, FILE *fout)
Definition: print.c:1174
void ClosePager(FILE *pagerpipe)
Definition: print.c:2900
const printTextFormat pg_asciiformat_old
Definition: print.c:80
bool start_table
Definition: print.h:108
enum printFormat format
Definition: print.h:98
printTextLineFormat lrule[4]
Definition: print.h:70
const printTableOpt * opt
Definition: print.h:145
unsigned long prior_records
Definition: print.h:111
struct printTableFooter * next
Definition: print.h:136
const char * header_nl_right
Definition: print.h:75
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
volatile bool cancel_pressed
Definition: print.c:46
static void IsPagerNeeded(const printTableContent *cont, int extra_lines, bool expanded, FILE **fout, bool *is_pager)
Definition: print.c:3148
unsigned short int border
Definition: print.h:101
const char * midvrule_nl
Definition: print.h:71
bool tuples_only
Definition: print.h:107
printTextRule
Definition: print.h:49
const char ** cells
Definition: print.h:151
const char * leftvrule
Definition: print.h:44
bool stop_table
Definition: print.h:109
static char * encoding
Definition: initdb.c:122
#define free(a)
Definition: header.h:65
const printTextFormat * get_line_style(const printTableOpt *opt)
Definition: print.c:3412
#define NULL
Definition: c.h:229
const char * nl_right
Definition: print.h:77
printTableFooter * footers
Definition: print.h:156
int width
Definition: mbprint.h:19
static int strlen_max_width(unsigned char *str, int *target_width, int encoding)
Definition: print.c:3483
const char * rightvrule
Definition: print.h:46
static void fputnbytes(FILE *f, const char *str, size_t n)
Definition: print.c:318
const char * wrap_left
Definition: print.h:78
int i
char * data
Definition: print.h:135
const char * wrap_right
Definition: print.h:79
static char format
Definition: pg_basebackup.c:80
unsigned char * ptr
Definition: mbprint.h:18
const char ** headers
Definition: print.h:149
int columns
Definition: print.h:120
static void print_aligned_vertical_line ( const printTextFormat format,
const unsigned short  opt_border,
unsigned long  record,
unsigned int  hwidth,
unsigned int  dwidth,
printTextRule  pos,
FILE *  fout 
)
static

Definition at line 1174 of file print.c.

References printTextLineFormat::hrule, i, printTextLineFormat::leftvrule, printTextFormat::lrule, printTextLineFormat::midvrule, and printTextLineFormat::rightvrule.

Referenced by print_aligned_vertical().

1181 {
1182  const printTextLineFormat *lformat = &format->lrule[pos];
1183  unsigned int i;
1184  int reclen = 0;
1185 
1186  if (opt_border == 2)
1187  fprintf(fout, "%s%s", lformat->leftvrule, lformat->hrule);
1188  else if (opt_border == 1)
1189  fputs(lformat->hrule, fout);
1190 
1191  if (record)
1192  {
1193  if (opt_border == 0)
1194  reclen = fprintf(fout, "* Record %lu", record);
1195  else
1196  reclen = fprintf(fout, "[ RECORD %lu ]", record);
1197  }
1198  if (opt_border != 2)
1199  reclen++;
1200  if (reclen < 0)
1201  reclen = 0;
1202  for (i = reclen; i < hwidth; i++)
1203  fputs(opt_border > 0 ? lformat->hrule : " ", fout);
1204  reclen -= hwidth;
1205 
1206  if (opt_border > 0)
1207  {
1208  if (reclen-- <= 0)
1209  fputs(lformat->hrule, fout);
1210  if (reclen-- <= 0)
1211  fputs(lformat->midvrule, fout);
1212  if (reclen-- <= 0)
1213  fputs(lformat->hrule, fout);
1214  }
1215  else
1216  {
1217  if (reclen-- <= 0)
1218  fputc(' ', fout);
1219  }
1220  if (reclen < 0)
1221  reclen = 0;
1222  for (i = reclen; i < dwidth; i++)
1223  fputs(opt_border > 0 ? lformat->hrule : " ", fout);
1224  if (opt_border == 2)
1225  fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
1226  fputc('\n', fout);
1227 }
const char * midvrule
Definition: print.h:45
printTextLineFormat lrule[4]
Definition: print.h:70
const char * hrule
Definition: print.h:43
const char * leftvrule
Definition: print.h:44
const char * rightvrule
Definition: print.h:46
int i
static void print_asciidoc_text ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 1978 of file print.c.

References printTableContent::aligns, asciidoc_escaped_print(), printTableOpt::border, cancel_pressed, printTableContent::cells, printTableFooter::data, footers_with_default(), printTableContent::headers, i, printTableContent::ncolumns, printTableFooter::next, NULL, printTableContent::opt, printTableOpt::start_table, printTableOpt::stop_table, printTableContent::title, and printTableOpt::tuples_only.

Referenced by printTable().

1979 {
1980  bool opt_tuples_only = cont->opt->tuples_only;
1981  unsigned short opt_border = cont->opt->border;
1982  unsigned int i;
1983  const char *const * ptr;
1984 
1985  if (cancel_pressed)
1986  return;
1987 
1988  if (cont->opt->start_table)
1989  {
1990  /* print table in new paragraph - enforce preliminary new line */
1991  fputs("\n", fout);
1992 
1993  /* print title */
1994  if (!opt_tuples_only && cont->title)
1995  {
1996  fputs(".", fout);
1997  fputs(cont->title, fout);
1998  fputs("\n", fout);
1999  }
2000 
2001  /* print table [] header definition */
2002  fprintf(fout, "[%scols=\"", !opt_tuples_only ? "options=\"header\"," : "");
2003  for (i = 0; i < cont->ncolumns; i++)
2004  {
2005  if (i != 0)
2006  fputs(",", fout);
2007  fprintf(fout, "%s", cont->aligns[(i) % cont->ncolumns] == 'r' ? ">l" : "<l");
2008  }
2009  fputs("\"", fout);
2010  switch (opt_border)
2011  {
2012  case 0:
2013  fputs(",frame=\"none\",grid=\"none\"", fout);
2014  break;
2015  case 1:
2016  fputs(",frame=\"none\"", fout);
2017  break;
2018  case 2:
2019  fputs(",frame=\"all\",grid=\"all\"", fout);
2020  break;
2021  }
2022  fputs("]\n", fout);
2023  fputs("|====\n", fout);
2024 
2025  /* print headers */
2026  if (!opt_tuples_only)
2027  {
2028  for (ptr = cont->headers; *ptr; ptr++)
2029  {
2030  if (ptr != cont->headers)
2031  fputs(" ", fout);
2032  fputs("^l|", fout);
2033  asciidoc_escaped_print(*ptr, fout);
2034  }
2035  fputs("\n", fout);
2036  }
2037  }
2038 
2039  /* print cells */
2040  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2041  {
2042  if (i % cont->ncolumns == 0)
2043  {
2044  if (cancel_pressed)
2045  break;
2046  }
2047 
2048  if (i % cont->ncolumns != 0)
2049  fputs(" ", fout);
2050  fputs("|", fout);
2051 
2052  /* protect against needless spaces */
2053  if ((*ptr)[strspn(*ptr, " \t")] == '\0')
2054  {
2055  if ((i + 1) % cont->ncolumns != 0)
2056  fputs(" ", fout);
2057  }
2058  else
2059  asciidoc_escaped_print(*ptr, fout);
2060 
2061  if ((i + 1) % cont->ncolumns == 0)
2062  fputs("\n", fout);
2063  }
2064 
2065  fputs("|====\n", fout);
2066 
2067  if (cont->opt->stop_table)
2068  {
2069  printTableFooter *footers = footers_with_default(cont);
2070 
2071  /* print footers */
2072  if (!opt_tuples_only && footers != NULL && !cancel_pressed)
2073  {
2074  printTableFooter *f;
2075 
2076  fputs("\n....\n", fout);
2077  for (f = footers; f; f = f->next)
2078  {
2079  fputs(f->data, fout);
2080  fputs("\n", fout);
2081  }
2082  fputs("....\n", fout);
2083  }
2084  }
2085 }
const char * title
Definition: print.h:146
static void asciidoc_escaped_print(const char *in, FILE *fout)
Definition: print.c:1960
static printTableFooter * footers_with_default(const printTableContent *cont)
Definition: print.c:345
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
unsigned short int border
Definition: print.h:101
char * aligns
Definition: print.h:158
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
bool stop_table
Definition: print.h:109
#define NULL
Definition: c.h:229
int i
char * data
Definition: print.h:135
const char ** headers
Definition: print.h:149
static void print_asciidoc_vertical ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 2088 of file print.c.

References printTableContent::aligns, asciidoc_escaped_print(), printTableOpt::border, cancel_pressed, printTableContent::cells, printTableFooter::data, printTableContent::footers, printTableContent::headers, i, printTableContent::ncolumns, printTableFooter::next, NULL, printTableContent::opt, printTableOpt::prior_records, printTableOpt::start_table, printTableOpt::stop_table, printTableContent::title, and printTableOpt::tuples_only.

Referenced by printTable().

2089 {
2090  bool opt_tuples_only = cont->opt->tuples_only;
2091  unsigned short opt_border = cont->opt->border;
2092  unsigned long record = cont->opt->prior_records + 1;
2093  unsigned int i;
2094  const char *const * ptr;
2095 
2096  if (cancel_pressed)
2097  return;
2098 
2099  if (cont->opt->start_table)
2100  {
2101  /* print table in new paragraph - enforce preliminary new line */
2102  fputs("\n", fout);
2103 
2104  /* print title */
2105  if (!opt_tuples_only && cont->title)
2106  {
2107  fputs(".", fout);
2108  fputs(cont->title, fout);
2109  fputs("\n", fout);
2110  }
2111 
2112  /* print table [] header definition */
2113  fputs("[cols=\"h,l\"", fout);
2114  switch (opt_border)
2115  {
2116  case 0:
2117  fputs(",frame=\"none\",grid=\"none\"", fout);
2118  break;
2119  case 1:
2120  fputs(",frame=\"none\"", fout);
2121  break;
2122  case 2:
2123  fputs(",frame=\"all\",grid=\"all\"", fout);
2124  break;
2125  }
2126  fputs("]\n", fout);
2127  fputs("|====\n", fout);
2128  }
2129 
2130  /* print records */
2131  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2132  {
2133  if (i % cont->ncolumns == 0)
2134  {
2135  if (cancel_pressed)
2136  break;
2137  if (!opt_tuples_only)
2138  fprintf(fout,
2139  "2+^|Record %lu\n",
2140  record++);
2141  else
2142  fputs("2+|\n", fout);
2143  }
2144 
2145  fputs("<l|", fout);
2146  asciidoc_escaped_print(cont->headers[i % cont->ncolumns], fout);
2147 
2148  fprintf(fout, " %s|", cont->aligns[i % cont->ncolumns] == 'r' ? ">l" : "<l");
2149  /* is string only whitespace? */
2150  if ((*ptr)[strspn(*ptr, " \t")] == '\0')
2151  fputs(" ", fout);
2152  else
2153  asciidoc_escaped_print(*ptr, fout);
2154  fputs("\n", fout);
2155  }
2156 
2157  fputs("|====\n", fout);
2158 
2159  if (cont->opt->stop_table)
2160  {
2161  /* print footers */
2162  if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
2163  {
2164  printTableFooter *f;
2165 
2166  fputs("\n....\n", fout);
2167  for (f = cont->footers; f; f = f->next)
2168  {
2169  fputs(f->data, fout);
2170  fputs("\n", fout);
2171  }
2172  fputs("....\n", fout);
2173  }
2174  }
2175 }
const char * title
Definition: print.h:146
static void asciidoc_escaped_print(const char *in, FILE *fout)
Definition: print.c:1960
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
unsigned long prior_records
Definition: print.h:111
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
unsigned short int border
Definition: print.h:101
char * aligns
Definition: print.h:158
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
bool stop_table
Definition: print.h:109
#define NULL
Definition: c.h:229
printTableFooter * footers
Definition: print.h:156
int i
char * data
Definition: print.h:135
const char ** headers
Definition: print.h:149
static void print_html_text ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 1786 of file print.c.

References printTableContent::aligns, printTableOpt::border, cancel_pressed, printTableContent::cells, printTableFooter::data, footers_with_default(), printTableContent::headers, html_escaped_print(), i, printTableContent::ncolumns, printTableFooter::next, NULL, printTableContent::opt, printTableOpt::start_table, printTableOpt::stop_table, printTableOpt::tableAttr, printTableContent::title, and printTableOpt::tuples_only.

Referenced by printTable().

1787 {
1788  bool opt_tuples_only = cont->opt->tuples_only;
1789  unsigned short opt_border = cont->opt->border;
1790  const char *opt_table_attr = cont->opt->tableAttr;
1791  unsigned int i;
1792  const char *const * ptr;
1793 
1794  if (cancel_pressed)
1795  return;
1796 
1797  if (cont->opt->start_table)
1798  {
1799  fprintf(fout, "<table border=\"%d\"", opt_border);
1800  if (opt_table_attr)
1801  fprintf(fout, " %s", opt_table_attr);
1802  fputs(">\n", fout);
1803 
1804  /* print title */
1805  if (!opt_tuples_only && cont->title)
1806  {
1807  fputs(" <caption>", fout);
1808  html_escaped_print(cont->title, fout);
1809  fputs("</caption>\n", fout);
1810  }
1811 
1812  /* print headers */
1813  if (!opt_tuples_only)
1814  {
1815  fputs(" <tr>\n", fout);
1816  for (ptr = cont->headers; *ptr; ptr++)
1817  {
1818  fputs(" <th align=\"center\">", fout);
1819  html_escaped_print(*ptr, fout);
1820  fputs("</th>\n", fout);
1821  }
1822  fputs(" </tr>\n", fout);
1823  }
1824  }
1825 
1826  /* print cells */
1827  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1828  {
1829  if (i % cont->ncolumns == 0)
1830  {
1831  if (cancel_pressed)
1832  break;
1833  fputs(" <tr valign=\"top\">\n", fout);
1834  }
1835 
1836  fprintf(fout, " <td align=\"%s\">", cont->aligns[(i) % cont->ncolumns] == 'r' ? "right" : "left");
1837  /* is string only whitespace? */
1838  if ((*ptr)[strspn(*ptr, " \t")] == '\0')
1839  fputs("&nbsp; ", fout);
1840  else
1841  html_escaped_print(*ptr, fout);
1842 
1843  fputs("</td>\n", fout);
1844 
1845  if ((i + 1) % cont->ncolumns == 0)
1846  fputs(" </tr>\n", fout);
1847  }
1848 
1849  if (cont->opt->stop_table)
1850  {
1851  printTableFooter *footers = footers_with_default(cont);
1852 
1853  fputs("</table>\n", fout);
1854 
1855  /* print footers */
1856  if (!opt_tuples_only && footers != NULL && !cancel_pressed)
1857  {
1858  printTableFooter *f;
1859 
1860  fputs("<p>", fout);
1861  for (f = footers; f; f = f->next)
1862  {
1863  html_escaped_print(f->data, fout);
1864  fputs("<br />\n", fout);
1865  }
1866  fputs("</p>", fout);
1867  }
1868 
1869  fputc('\n', fout);
1870  }
1871 }
const char * title
Definition: print.h:146
static printTableFooter * footers_with_default(const printTableContent *cont)
Definition: print.c:345
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
unsigned short int border
Definition: print.h:101
char * aligns
Definition: print.h:158
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
char * tableAttr
Definition: print.h:117
bool stop_table
Definition: print.h:109
#define NULL
Definition: c.h:229
int i
char * data
Definition: print.h:135
void html_escaped_print(const char *in, FILE *fout)
Definition: print.c:1745
const char ** headers
Definition: print.h:149
static void print_html_vertical ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 1875 of file print.c.

References printTableContent::aligns, printTableOpt::border, cancel_pressed, printTableContent::cells, printTableFooter::data, printTableContent::footers, printTableContent::headers, html_escaped_print(), i, printTableContent::ncolumns, printTableFooter::next, NULL, printTableContent::opt, printTableOpt::prior_records, printTableOpt::start_table, printTableOpt::stop_table, printTableOpt::tableAttr, printTableContent::title, and printTableOpt::tuples_only.

Referenced by printTable().

1876 {
1877  bool opt_tuples_only = cont->opt->tuples_only;
1878  unsigned short opt_border = cont->opt->border;
1879  const char *opt_table_attr = cont->opt->tableAttr;
1880  unsigned long record = cont->opt->prior_records + 1;
1881  unsigned int i;
1882  const char *const * ptr;
1883 
1884  if (cancel_pressed)
1885  return;
1886 
1887  if (cont->opt->start_table)
1888  {
1889  fprintf(fout, "<table border=\"%d\"", opt_border);
1890  if (opt_table_attr)
1891  fprintf(fout, " %s", opt_table_attr);
1892  fputs(">\n", fout);
1893 
1894  /* print title */
1895  if (!opt_tuples_only && cont->title)
1896  {
1897  fputs(" <caption>", fout);
1898  html_escaped_print(cont->title, fout);
1899  fputs("</caption>\n", fout);
1900  }
1901  }
1902 
1903  /* print records */
1904  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1905  {
1906  if (i % cont->ncolumns == 0)
1907  {
1908  if (cancel_pressed)
1909  break;
1910  if (!opt_tuples_only)
1911  fprintf(fout,
1912  "\n <tr><td colspan=\"2\" align=\"center\">Record %lu</td></tr>\n",
1913  record++);
1914  else
1915  fputs("\n <tr><td colspan=\"2\">&nbsp;</td></tr>\n", fout);
1916  }
1917  fputs(" <tr valign=\"top\">\n"
1918  " <th>", fout);
1919  html_escaped_print(cont->headers[i % cont->ncolumns], fout);
1920  fputs("</th>\n", fout);
1921 
1922  fprintf(fout, " <td align=\"%s\">", cont->aligns[i % cont->ncolumns] == 'r' ? "right" : "left");
1923  /* is string only whitespace? */
1924  if ((*ptr)[strspn(*ptr, " \t")] == '\0')
1925  fputs("&nbsp; ", fout);
1926  else
1927  html_escaped_print(*ptr, fout);
1928 
1929  fputs("</td>\n </tr>\n", fout);
1930  }
1931 
1932  if (cont->opt->stop_table)
1933  {
1934  fputs("</table>\n", fout);
1935 
1936  /* print footers */
1937  if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
1938  {
1939  printTableFooter *f;
1940 
1941  fputs("<p>", fout);
1942  for (f = cont->footers; f; f = f->next)
1943  {
1944  html_escaped_print(f->data, fout);
1945  fputs("<br />\n", fout);
1946  }
1947  fputs("</p>", fout);
1948  }
1949 
1950  fputc('\n', fout);
1951  }
1952 }
const char * title
Definition: print.h:146
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
unsigned long prior_records
Definition: print.h:111
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
unsigned short int border
Definition: print.h:101
char * aligns
Definition: print.h:158
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
char * tableAttr
Definition: print.h:117
bool stop_table
Definition: print.h:109
#define NULL
Definition: c.h:229
printTableFooter * footers
Definition: print.h:156
int i
char * data
Definition: print.h:135
void html_escaped_print(const char *in, FILE *fout)
Definition: print.c:1745
const char ** headers
Definition: print.h:149
static void print_latex_longtable_text ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 2323 of file print.c.

References printTableContent::aligns, printTableOpt::border, cancel_pressed, printTableContent::cells, printTableContent::headers, i, latex_escaped_print(), LONGTABLE_WHITESPACE, printTableContent::ncolumns, NULL, printTableContent::opt, printTableOpt::start_table, printTableOpt::stop_table, printTableOpt::tableAttr, printTableContent::title, and printTableOpt::tuples_only.

Referenced by printTable().

2324 {
2325  bool opt_tuples_only = cont->opt->tuples_only;
2326  unsigned short opt_border = cont->opt->border;
2327  unsigned int i;
2328  const char *opt_table_attr = cont->opt->tableAttr;
2329  const char *next_opt_table_attr_char = opt_table_attr;
2330  const char *last_opt_table_attr_char = NULL;
2331  const char *const * ptr;
2332 
2333  if (cancel_pressed)
2334  return;
2335 
2336  if (opt_border > 3)
2337  opt_border = 3;
2338 
2339  if (cont->opt->start_table)
2340  {
2341  /* begin environment and set alignments and borders */
2342  fputs("\\begin{longtable}{", fout);
2343 
2344  if (opt_border >= 2)
2345  fputs("| ", fout);
2346 
2347  for (i = 0; i < cont->ncolumns; i++)
2348  {
2349  /* longtable supports either a width (p) or an alignment (l/r) */
2350  /* Are we left-justified and was a proportional width specified? */
2351  if (*(cont->aligns + i) == 'l' && opt_table_attr)
2352  {
2353 #define LONGTABLE_WHITESPACE " \t\n"
2354 
2355  /* advance over whitespace */
2356  next_opt_table_attr_char += strspn(next_opt_table_attr_char,
2358  /* We have a value? */
2359  if (next_opt_table_attr_char[0] != '\0')
2360  {
2361  fputs("p{", fout);
2362  fwrite(next_opt_table_attr_char, strcspn(next_opt_table_attr_char,
2363  LONGTABLE_WHITESPACE), 1, fout);
2364  last_opt_table_attr_char = next_opt_table_attr_char;
2365  next_opt_table_attr_char += strcspn(next_opt_table_attr_char,
2367  fputs("\\textwidth}", fout);
2368  }
2369  /* use previous value */
2370  else if (last_opt_table_attr_char != NULL)
2371  {
2372  fputs("p{", fout);
2373  fwrite(last_opt_table_attr_char, strcspn(last_opt_table_attr_char,
2374  LONGTABLE_WHITESPACE), 1, fout);
2375  fputs("\\textwidth}", fout);
2376  }
2377  else
2378  fputc('l', fout);
2379  }
2380  else
2381  fputc(*(cont->aligns + i), fout);
2382 
2383  if (opt_border != 0 && i < cont->ncolumns - 1)
2384  fputs(" | ", fout);
2385  }
2386 
2387  if (opt_border >= 2)
2388  fputs(" |", fout);
2389 
2390  fputs("}\n", fout);
2391 
2392  /* print headers */
2393  if (!opt_tuples_only)
2394  {
2395  /* firsthead */
2396  if (opt_border >= 2)
2397  fputs("\\toprule\n", fout);
2398  for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2399  {
2400  if (i != 0)
2401  fputs(" & ", fout);
2402  fputs("\\small\\textbf{\\textit{", fout);
2403  latex_escaped_print(*ptr, fout);
2404  fputs("}}", fout);
2405  }
2406  fputs(" \\\\\n", fout);
2407  fputs("\\midrule\n\\endfirsthead\n", fout);
2408 
2409  /* secondary heads */
2410  if (opt_border >= 2)
2411  fputs("\\toprule\n", fout);
2412  for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2413  {
2414  if (i != 0)
2415  fputs(" & ", fout);
2416  fputs("\\small\\textbf{\\textit{", fout);
2417  latex_escaped_print(*ptr, fout);
2418  fputs("}}", fout);
2419  }
2420  fputs(" \\\\\n", fout);
2421  /* If the line under the row already appeared, don't do another */
2422  if (opt_border != 3)
2423  fputs("\\midrule\n", fout);
2424  fputs("\\endhead\n", fout);
2425 
2426  /* table name, caption? */
2427  if (!opt_tuples_only && cont->title)
2428  {
2429  /* Don't output if we are printing a line under each row */
2430  if (opt_border == 2)
2431  fputs("\\bottomrule\n", fout);
2432  fputs("\\caption[", fout);
2433  latex_escaped_print(cont->title, fout);
2434  fputs(" (Continued)]{", fout);
2435  latex_escaped_print(cont->title, fout);
2436  fputs("}\n\\endfoot\n", fout);
2437  if (opt_border == 2)
2438  fputs("\\bottomrule\n", fout);
2439  fputs("\\caption[", fout);
2440  latex_escaped_print(cont->title, fout);
2441  fputs("]{", fout);
2442  latex_escaped_print(cont->title, fout);
2443  fputs("}\n\\endlastfoot\n", fout);
2444  }
2445  /* output bottom table line? */
2446  else if (opt_border >= 2)
2447  {
2448  fputs("\\bottomrule\n\\endfoot\n", fout);
2449  fputs("\\bottomrule\n\\endlastfoot\n", fout);
2450  }
2451  }
2452  }
2453 
2454  /* print cells */
2455  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2456  {
2457  /* Add a line under each row? */
2458  if (i != 0 && i % cont->ncolumns != 0)
2459  fputs("\n&\n", fout);
2460  fputs("\\raggedright{", fout);
2461  latex_escaped_print(*ptr, fout);
2462  fputc('}', fout);
2463  if ((i + 1) % cont->ncolumns == 0)
2464  {
2465  fputs(" \\tabularnewline\n", fout);
2466  if (opt_border == 3)
2467  fputs(" \\hline\n", fout);
2468  }
2469  if (cancel_pressed)
2470  break;
2471  }
2472 
2473  if (cont->opt->stop_table)
2474  fputs("\\end{longtable}\n", fout);
2475 }
const char * title
Definition: print.h:146
static void latex_escaped_print(const char *in, FILE *fout)
Definition: print.c:2183
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
volatile bool cancel_pressed
Definition: print.c:46
unsigned short int border
Definition: print.h:101
char * aligns
Definition: print.h:158
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
#define LONGTABLE_WHITESPACE
char * tableAttr
Definition: print.h:117
bool stop_table
Definition: print.h:109
#define NULL
Definition: c.h:229
int i
const char ** headers
Definition: print.h:149
static void print_latex_text ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 2221 of file print.c.

References printTableContent::aligns, printTableOpt::border, cancel_pressed, printTableContent::cells, printTableFooter::data, footers_with_default(), printTableContent::headers, i, latex_escaped_print(), printTableContent::ncolumns, printTableFooter::next, printTableContent::opt, printTableOpt::start_table, printTableOpt::stop_table, printTableContent::title, and printTableOpt::tuples_only.

Referenced by printTable().

2222 {
2223  bool opt_tuples_only = cont->opt->tuples_only;
2224  unsigned short opt_border = cont->opt->border;
2225  unsigned int i;
2226  const char *const * ptr;
2227 
2228  if (cancel_pressed)
2229  return;
2230 
2231  if (opt_border > 3)
2232  opt_border = 3;
2233 
2234  if (cont->opt->start_table)
2235  {
2236  /* print title */
2237  if (!opt_tuples_only && cont->title)
2238  {
2239  fputs("\\begin{center}\n", fout);
2240  latex_escaped_print(cont->title, fout);
2241  fputs("\n\\end{center}\n\n", fout);
2242  }
2243 
2244  /* begin environment and set alignments and borders */
2245  fputs("\\begin{tabular}{", fout);
2246 
2247  if (opt_border >= 2)
2248  fputs("| ", fout);
2249  for (i = 0; i < cont->ncolumns; i++)
2250  {
2251  fputc(*(cont->aligns + i), fout);
2252  if (opt_border != 0 && i < cont->ncolumns - 1)
2253  fputs(" | ", fout);
2254  }
2255  if (opt_border >= 2)
2256  fputs(" |", fout);
2257 
2258  fputs("}\n", fout);
2259 
2260  if (!opt_tuples_only && opt_border >= 2)
2261  fputs("\\hline\n", fout);
2262 
2263  /* print headers */
2264  if (!opt_tuples_only)
2265  {
2266  for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2267  {
2268  if (i != 0)
2269  fputs(" & ", fout);
2270  fputs("\\textit{", fout);
2271  latex_escaped_print(*ptr, fout);
2272  fputc('}', fout);
2273  }
2274  fputs(" \\\\\n", fout);
2275  fputs("\\hline\n", fout);
2276  }
2277  }
2278 
2279  /* print cells */
2280  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2281  {
2282  latex_escaped_print(*ptr, fout);
2283 
2284  if ((i + 1) % cont->ncolumns == 0)
2285  {
2286  fputs(" \\\\\n", fout);
2287  if (opt_border == 3)
2288  fputs("\\hline\n", fout);
2289  if (cancel_pressed)
2290  break;
2291  }
2292  else
2293  fputs(" & ", fout);
2294  }
2295 
2296  if (cont->opt->stop_table)
2297  {
2298  printTableFooter *footers = footers_with_default(cont);
2299 
2300  if (opt_border == 2)
2301  fputs("\\hline\n", fout);
2302 
2303  fputs("\\end{tabular}\n\n\\noindent ", fout);
2304 
2305  /* print footers */
2306  if (footers && !opt_tuples_only && !cancel_pressed)
2307  {
2308  printTableFooter *f;
2309 
2310  for (f = footers; f; f = f->next)
2311  {
2312  latex_escaped_print(f->data, fout);
2313  fputs(" \\\\\n", fout);
2314  }
2315  }
2316 
2317  fputc('\n', fout);
2318  }
2319 }
const char * title
Definition: print.h:146
static void latex_escaped_print(const char *in, FILE *fout)
Definition: print.c:2183
static printTableFooter * footers_with_default(const printTableContent *cont)
Definition: print.c:345
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
unsigned short int border
Definition: print.h:101
char * aligns
Definition: print.h:158
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
bool stop_table
Definition: print.h:109
int i
char * data
Definition: print.h:135
const char ** headers
Definition: print.h:149
static void print_latex_vertical ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 2479 of file print.c.

References printTableOpt::border, cancel_pressed, printTableContent::cells, printTableFooter::data, printTableContent::footers, printTableContent::headers, i, latex_escaped_print(), printTableContent::ncolumns, printTableFooter::next, printTableContent::opt, printTableOpt::prior_records, printTableOpt::start_table, printTableOpt::stop_table, printTableContent::title, and printTableOpt::tuples_only.

Referenced by printTable().

2480 {
2481  bool opt_tuples_only = cont->opt->tuples_only;
2482  unsigned short opt_border = cont->opt->border;
2483  unsigned long record = cont->opt->prior_records + 1;
2484  unsigned int i;
2485  const char *const * ptr;
2486 
2487  if (cancel_pressed)
2488  return;
2489 
2490  if (opt_border > 2)
2491  opt_border = 2;
2492 
2493  if (cont->opt->start_table)
2494  {
2495  /* print title */
2496  if (!opt_tuples_only && cont->title)
2497  {
2498  fputs("\\begin{center}\n", fout);
2499  latex_escaped_print(cont->title, fout);
2500  fputs("\n\\end{center}\n\n", fout);
2501  }
2502 
2503  /* begin environment and set alignments and borders */
2504  fputs("\\begin{tabular}{", fout);
2505  if (opt_border == 0)
2506  fputs("cl", fout);
2507  else if (opt_border == 1)
2508  fputs("c|l", fout);
2509  else if (opt_border == 2)
2510  fputs("|c|l|", fout);
2511  fputs("}\n", fout);
2512  }
2513 
2514  /* print records */
2515  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2516  {
2517  /* new record */
2518  if (i % cont->ncolumns == 0)
2519  {
2520  if (cancel_pressed)
2521  break;
2522  if (!opt_tuples_only)
2523  {
2524  if (opt_border == 2)
2525  {
2526  fputs("\\hline\n", fout);
2527  fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %lu}} \\\\\n", record++);
2528  }
2529  else
2530  fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %lu}} \\\\\n", record++);
2531  }
2532  if (opt_border >= 1)
2533  fputs("\\hline\n", fout);
2534  }
2535 
2536  latex_escaped_print(cont->headers[i % cont->ncolumns], fout);
2537  fputs(" & ", fout);
2538  latex_escaped_print(*ptr, fout);
2539  fputs(" \\\\\n", fout);
2540  }
2541 
2542  if (cont->opt->stop_table)
2543  {
2544  if (opt_border == 2)
2545  fputs("\\hline\n", fout);
2546 
2547  fputs("\\end{tabular}\n\n\\noindent ", fout);
2548 
2549  /* print footers */
2550  if (cont->footers && !opt_tuples_only && !cancel_pressed)
2551  {
2552  printTableFooter *f;
2553 
2554  for (f = cont->footers; f; f = f->next)
2555  {
2556  latex_escaped_print(f->data, fout);
2557  fputs(" \\\\\n", fout);
2558  }
2559  }
2560 
2561  fputc('\n', fout);
2562  }
2563 }
const char * title
Definition: print.h:146
static void latex_escaped_print(const char *in, FILE *fout)
Definition: print.c:2183
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
unsigned long prior_records
Definition: print.h:111
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
unsigned short int border
Definition: print.h:101
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
bool stop_table
Definition: print.h:109
printTableFooter * footers
Definition: print.h:156
int i
char * data
Definition: print.h:135
const char ** headers
Definition: print.h:149
static void print_separator ( struct separator  sep,
FILE *  fout 
)
static

Definition at line 326 of file print.c.

References separator::separator, and separator::separator_zero.

Referenced by print_unaligned_text(), and print_unaligned_vertical().

327 {
328  if (sep.separator_zero)
329  fputc('\000', fout);
330  else if (sep.separator)
331  fputs(sep.separator, fout);
332 }
bool separator_zero
Definition: print.h:93
char * separator
Definition: print.h:92
static void print_troff_ms_text ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 2589 of file print.c.

References printTableContent::aligns, printTableOpt::border, cancel_pressed, printTableContent::cells, printTableFooter::data, footers_with_default(), printTableContent::headers, i, printTableContent::ncolumns, printTableFooter::next, printTableContent::opt, printTableOpt::start_table, printTableOpt::stop_table, printTableContent::title, troff_ms_escaped_print(), and printTableOpt::tuples_only.

Referenced by printTable().

2590 {
2591  bool opt_tuples_only = cont->opt->tuples_only;
2592  unsigned short opt_border = cont->opt->border;
2593  unsigned int i;
2594  const char *const * ptr;
2595 
2596  if (cancel_pressed)
2597  return;
2598 
2599  if (opt_border > 2)
2600  opt_border = 2;
2601 
2602  if (cont->opt->start_table)
2603  {
2604  /* print title */
2605  if (!opt_tuples_only && cont->title)
2606  {
2607  fputs(".LP\n.DS C\n", fout);
2608  troff_ms_escaped_print(cont->title, fout);
2609  fputs("\n.DE\n", fout);
2610  }
2611 
2612  /* begin environment and set alignments and borders */
2613  fputs(".LP\n.TS\n", fout);
2614  if (opt_border == 2)
2615  fputs("center box;\n", fout);
2616  else
2617  fputs("center;\n", fout);
2618 
2619  for (i = 0; i < cont->ncolumns; i++)
2620  {
2621  fputc(*(cont->aligns + i), fout);
2622  if (opt_border > 0 && i < cont->ncolumns - 1)
2623  fputs(" | ", fout);
2624  }
2625  fputs(".\n", fout);
2626 
2627  /* print headers */
2628  if (!opt_tuples_only)
2629  {
2630  for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
2631  {
2632  if (i != 0)
2633  fputc('\t', fout);
2634  fputs("\\fI", fout);
2635  troff_ms_escaped_print(*ptr, fout);
2636  fputs("\\fP", fout);
2637  }
2638  fputs("\n_\n", fout);
2639  }
2640  }
2641 
2642  /* print cells */
2643  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2644  {
2645  troff_ms_escaped_print(*ptr, fout);
2646 
2647  if ((i + 1) % cont->ncolumns == 0)
2648  {
2649  fputc('\n', fout);
2650  if (cancel_pressed)
2651  break;
2652  }
2653  else
2654  fputc('\t', fout);
2655  }
2656 
2657  if (cont->opt->stop_table)
2658  {
2659  printTableFooter *footers = footers_with_default(cont);
2660 
2661  fputs(".TE\n.DS L\n", fout);
2662 
2663  /* print footers */
2664  if (footers && !opt_tuples_only && !cancel_pressed)
2665  {
2666  printTableFooter *f;
2667 
2668  for (f = footers; f; f = f->next)
2669  {
2670  troff_ms_escaped_print(f->data, fout);
2671  fputc('\n', fout);
2672  }
2673  }
2674 
2675  fputs(".DE\n", fout);
2676  }
2677 }
const char * title
Definition: print.h:146
static printTableFooter * footers_with_default(const printTableContent *cont)
Definition: print.c:345
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
unsigned short int border
Definition: print.h:101
char * aligns
Definition: print.h:158
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
static void troff_ms_escaped_print(const char *in, FILE *fout)
Definition: print.c:2572
bool stop_table
Definition: print.h:109
int i
char * data
Definition: print.h:135
const char ** headers
Definition: print.h:149
static void print_troff_ms_vertical ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 2681 of file print.c.

References printTableOpt::border, cancel_pressed, printTableContent::cells, printTableFooter::data, printTableContent::footers, printTableContent::headers, i, printTableContent::ncolumns, printTableFooter::next, printTableContent::opt, printTableOpt::prior_records, printTableOpt::start_table, printTableOpt::stop_table, printTableContent::title, troff_ms_escaped_print(), and printTableOpt::tuples_only.

Referenced by printTable().

2682 {
2683  bool opt_tuples_only = cont->opt->tuples_only;
2684  unsigned short opt_border = cont->opt->border;
2685  unsigned long record = cont->opt->prior_records + 1;
2686  unsigned int i;
2687  const char *const * ptr;
2688  unsigned short current_format = 0; /* 0=none, 1=header, 2=body */
2689 
2690  if (cancel_pressed)
2691  return;
2692 
2693  if (opt_border > 2)
2694  opt_border = 2;
2695 
2696  if (cont->opt->start_table)
2697  {
2698  /* print title */
2699  if (!opt_tuples_only && cont->title)
2700  {
2701  fputs(".LP\n.DS C\n", fout);
2702  troff_ms_escaped_print(cont->title, fout);
2703  fputs("\n.DE\n", fout);
2704  }
2705 
2706  /* begin environment and set alignments and borders */
2707  fputs(".LP\n.TS\n", fout);
2708  if (opt_border == 2)
2709  fputs("center box;\n", fout);
2710  else
2711  fputs("center;\n", fout);
2712 
2713  /* basic format */
2714  if (opt_tuples_only)
2715  fputs("c l;\n", fout);
2716  }
2717  else
2718  current_format = 2; /* assume tuples printed already */
2719 
2720  /* print records */
2721  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
2722  {
2723  /* new record */
2724  if (i % cont->ncolumns == 0)
2725  {
2726  if (cancel_pressed)
2727  break;
2728  if (!opt_tuples_only)
2729  {
2730  if (current_format != 1)
2731  {
2732  if (opt_border == 2 && record > 1)
2733  fputs("_\n", fout);
2734  if (current_format != 0)
2735  fputs(".T&\n", fout);
2736  fputs("c s.\n", fout);
2737  current_format = 1;
2738  }
2739  fprintf(fout, "\\fIRecord %lu\\fP\n", record++);
2740  }
2741  if (opt_border >= 1)
2742  fputs("_\n", fout);
2743  }
2744 
2745  if (!opt_tuples_only)
2746  {
2747  if (current_format != 2)
2748  {
2749  if (current_format != 0)
2750  fputs(".T&\n", fout);
2751  if (opt_border != 1)
2752  fputs("c l.\n", fout);
2753  else
2754  fputs("c | l.\n", fout);
2755  current_format = 2;
2756  }
2757  }
2758 
2759  troff_ms_escaped_print(cont->headers[i % cont->ncolumns], fout);
2760  fputc('\t', fout);
2761  troff_ms_escaped_print(*ptr, fout);
2762 
2763  fputc('\n', fout);
2764  }
2765 
2766  if (cont->opt->stop_table)
2767  {
2768  fputs(".TE\n.DS L\n", fout);
2769 
2770  /* print footers */
2771  if (cont->footers && !opt_tuples_only && !cancel_pressed)
2772  {
2773  printTableFooter *f;
2774 
2775  for (f = cont->footers; f; f = f->next)
2776  {
2777  troff_ms_escaped_print(f->data, fout);
2778  fputc('\n', fout);
2779  }
2780  }
2781 
2782  fputs(".DE\n", fout);
2783  }
2784 }
const char * title
Definition: print.h:146
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
unsigned long prior_records
Definition: print.h:111
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
unsigned short int border
Definition: print.h:101
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
static void troff_ms_escaped_print(const char *in, FILE *fout)
Definition: print.c:2572
bool stop_table
Definition: print.h:109
printTableFooter * footers
Definition: print.h:156
int i
char * data
Definition: print.h:135
const char ** headers
Definition: print.h:149
static void print_unaligned_text ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 369 of file print.c.

References cancel_pressed, printTableContent::cells, printTableFooter::data, printTableOpt::fieldSep, footers_with_default(), printTableContent::headers, i, printTableContent::ncolumns, printTableFooter::next, NULL, printTableContent::opt, print_separator(), printTableOpt::recordSep, separator::separator_zero, printTableOpt::start_table, printTableOpt::stop_table, printTableContent::title, and printTableOpt::tuples_only.

Referenced by printTable().

370 {
371  bool opt_tuples_only = cont->opt->tuples_only;
372  unsigned int i;
373  const char *const * ptr;
374  bool need_recordsep = false;
375 
376  if (cancel_pressed)
377  return;
378 
379  if (cont->opt->start_table)
380  {
381  /* print title */
382  if (!opt_tuples_only && cont->title)
383  {
384  fputs(cont->title, fout);
385  print_separator(cont->opt->recordSep, fout);
386  }
387 
388  /* print headers */
389  if (!opt_tuples_only)
390  {
391  for (ptr = cont->headers; *ptr; ptr++)
392  {
393  if (ptr != cont->headers)
394  print_separator(cont->opt->fieldSep, fout);
395  fputs(*ptr, fout);
396  }
397  need_recordsep = true;
398  }
399  }
400  else
401  /* assume continuing printout */
402  need_recordsep = true;
403 
404  /* print cells */
405  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
406  {
407  if (need_recordsep)
408  {
409  print_separator(cont->opt->recordSep, fout);
410  need_recordsep = false;
411  if (cancel_pressed)
412  break;
413  }
414  fputs(*ptr, fout);
415 
416  if ((i + 1) % cont->ncolumns)
417  print_separator(cont->opt->fieldSep, fout);
418  else
419  need_recordsep = true;
420  }
421 
422  /* print footers */
423  if (cont->opt->stop_table)
424  {
425  printTableFooter *footers = footers_with_default(cont);
426 
427  if (!opt_tuples_only && footers != NULL && !cancel_pressed)
428  {
429  printTableFooter *f;
430 
431  for (f = footers; f; f = f->next)
432  {
433  if (need_recordsep)
434  {
435  print_separator(cont->opt->recordSep, fout);
436  need_recordsep = false;
437  }
438  fputs(f->data, fout);
439  need_recordsep = true;
440  }
441  }
442 
443  /*
444  * The last record is terminated by a newline, independent of the set
445  * record separator. But when the record separator is a zero byte, we
446  * use that (compatible with find -print0 and xargs).
447  */
448  if (need_recordsep)
449  {
450  if (cont->opt->recordSep.separator_zero)
451  print_separator(cont->opt->recordSep, fout);
452  else
453  fputc('\n', fout);
454  }
455  }
456 }
const char * title
Definition: print.h:146
static void print_separator(struct separator sep, FILE *fout)
Definition: print.c:326
static printTableFooter * footers_with_default(const printTableContent *cont)
Definition: print.c:345
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
bool separator_zero
Definition: print.h:93
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
bool stop_table
Definition: print.h:109
struct separator fieldSep
Definition: print.h:113
#define NULL
Definition: c.h:229
int i
char * data
Definition: print.h:135
const char ** headers
Definition: print.h:149
struct separator recordSep
Definition: print.h:114
static void print_unaligned_vertical ( const printTableContent cont,
FILE *  fout 
)
static

Definition at line 460 of file print.c.

References cancel_pressed, printTableContent::cells, printTableFooter::data, printTableOpt::fieldSep, printTableContent::footers, printTableContent::headers, i, printTableContent::ncolumns, printTableFooter::next, NULL, printTableContent::opt, print_separator(), printTableOpt::recordSep, separator::separator_zero, printTableOpt::start_table, printTableOpt::stop_table, printTableContent::title, and printTableOpt::tuples_only.

Referenced by printTable().

461 {
462  bool opt_tuples_only = cont->opt->tuples_only;
463  unsigned int i;
464  const char *const * ptr;
465  bool need_recordsep = false;
466 
467  if (cancel_pressed)
468  return;
469 
470  if (cont->opt->start_table)
471  {
472  /* print title */
473  if (!opt_tuples_only && cont->title)
474  {
475  fputs(cont->title, fout);
476  need_recordsep = true;
477  }
478  }
479  else
480  /* assume continuing printout */
481  need_recordsep = true;
482 
483  /* print records */
484  for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
485  {
486  if (need_recordsep)
487  {
488  /* record separator is 2 occurrences of recordsep in this mode */
489  print_separator(cont->opt->recordSep, fout);
490  print_separator(cont->opt->recordSep, fout);
491  need_recordsep = false;
492  if (cancel_pressed)
493  break;
494  }
495 
496  fputs(cont->headers[i % cont->ncolumns], fout);
497  print_separator(cont->opt->fieldSep, fout);
498  fputs(*ptr, fout);
499 
500  if ((i + 1) % cont->ncolumns)
501  print_separator(cont->opt->recordSep, fout);
502  else
503  need_recordsep = true;
504  }
505 
506  if (cont->opt->stop_table)
507  {
508  /* print footers */
509  if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
510  {
511  printTableFooter *f;
512 
513  print_separator(cont->opt->recordSep, fout);
514  for (f = cont->footers; f; f = f->next)
515  {
516  print_separator(cont->opt->recordSep, fout);
517  fputs(f->data, fout);
518  }
519  }
520 
521  /* see above in print_unaligned_text() */
522  if (need_recordsep)
523  {
524  if (cont->opt->recordSep.separator_zero)
525  print_separator(cont->opt->recordSep, fout);
526  else
527  fputc('\n', fout);
528  }
529  }
530 }
const char * title
Definition: print.h:146
static void print_separator(struct separator sep, FILE *fout)
Definition: print.c:326
bool start_table
Definition: print.h:108
const printTableOpt * opt
Definition: print.h:145
bool separator_zero
Definition: print.h:93
struct printTableFooter * next
Definition: print.h:136
volatile bool cancel_pressed
Definition: print.c:46
bool tuples_only
Definition: print.h:107
const char ** cells
Definition: print.h:151
bool stop_table
Definition: print.h:109
struct separator fieldSep
Definition: print.h:113
#define NULL
Definition: c.h:229
printTableFooter * footers
Definition: print.h:156
int i
char * data
Definition: print.h:135
const char ** headers
Definition: print.h:149
struct separator recordSep
Definition: print.h:114
void printQuery ( const PGresult result,
const printQueryOpt opt,
FILE *  fout,
bool  is_pager,
FILE *  flog 
)

Definition at line 3285 of file print.c.

References printTableContent::aligns, Assert, cancel_pressed, column_type_alignment(), printQueryOpt::footers, format_numeric_locale(), i, printQueryOpt::n_translate_columns, printTableContent::ncolumns, printTableContent::nrows, NULL, printQueryOpt::nullPrint, printTableOpt::numericLocale, PQfname(), PQftype(), PQgetisnull(), PQgetvalue(), PQnfields(), PQntuples(), printTable(), printTableAddCell(), printTableAddFooter(), printTableAddHeader(), printTableCleanup(), printTableInit(), printQueryOpt::title, printQueryOpt::topt, translate(), printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by describeAccessMethods(), describeAggregates(), describeFunctions(), describeOneTSConfig(), describeOneTSParser(), describeOperators(), describeSubscriptions(), describeTablespaces(), describeTypes(), do_lo_list(), ExecQueryUsingCursor(), listAllDbs(), listCasts(), listCollations(), listConversions(), listDbRoleSettings(), listDefaultACLs(), listDomains(), listEventTriggers(), listExtensions(), listForeignDataWrappers(), listForeignServers(), listForeignTables(), listLanguages(), listOneExtensionContents(), listPublications(), listSchemas(), listTables(), listTSConfigs(), listTSDictionaries(), listTSParsers(), listTSTemplates(), listUserMappings(), objectDescription(), permissionsList(), PrintQueryTuples(), and PSQLexecWatch().

3287 {
3288  printTableContent cont;
3289  int i,
3290  r,
3291  c;
3292 
3293  if (cancel_pressed)
3294  return;
3295 
3296  printTableInit(&cont, &opt->topt, opt->title,
3297  PQnfields(result), PQntuples(result));
3298 
3299  /* Assert caller supplied enough translate_columns[] entries */
3300  Assert(opt->translate_columns == NULL ||
3301  opt->n_translate_columns >= cont.ncolumns);
3302 
3303  for (i = 0; i < cont.ncolumns; i++)
3304  {
3305  printTableAddHeader(&cont, PQfname(result, i),
3306  opt->translate_header,
3307  column_type_alignment(PQftype(result, i)));
3308  }
3309 
3310  /* set cells */
3311  for (r = 0; r < cont.nrows; r++)
3312  {
3313  for (c = 0; c < cont.ncolumns; c++)
3314  {
3315  char *cell;
3316  bool mustfree = false;
3317  bool translate;
3318 
3319  if (PQgetisnull(result, r, c))
3320  cell = opt->nullPrint ? opt->nullPrint : "";
3321  else
3322  {
3323  cell = PQgetvalue(result, r, c);
3324  if (cont.aligns[c] == 'r' && opt->topt.numericLocale)
3325  {
3326  cell = format_numeric_locale(cell);
3327  mustfree = true;
3328  }
3329  }
3330 
3331  translate = (opt->translate_columns && opt->translate_columns[c]);
3332  printTableAddCell(&cont, cell, translate, mustfree);
3333  }
3334  }
3335 
3336  /* set footers */
3337  if (opt->footers)
3338  {
3339  char **footer;
3340 
3341  for (footer = opt->footers; *footer; footer++)
3342  printTableAddFooter(&cont, *footer);
3343  }
3344 
3345  printTable(&cont, fout, is_pager, flog);
3346  printTableCleanup(&cont);
3347 }
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2681
char * nullPrint
Definition: print.h:166
void printTableCleanup(printTableContent *const content)
Definition: print.c:3099
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2759
printTableOpt topt
Definition: print.h:165
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
Datum translate(PG_FUNCTION_ARGS)
volatile bool cancel_pressed
Definition: print.c:46
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition: print.c:2968
char * aligns
Definition: print.h:158
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition: print.c:3008
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:2911
char * c
bool translate_header
Definition: print.h:169
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3188
char column_type_alignment(Oid ftype)
Definition: print.c:3350
void printTableAddFooter(printTableContent *const content, const char *footer)
Definition: print.c:3056
char * title
Definition: print.h:167
char ** footers
Definition: print.h:168
#define NULL
Definition: c.h:229
static char * format_numeric_locale(const char *my_str)
Definition: print.c:247
#define Assert(condition)
Definition: c.h:675
int n_translate_columns
Definition: print.h:172
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
Definition: print.c:2931
bool numericLocale
Definition: print.h:115
int i
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3092
const bool * translate_columns
Definition: print.h:170
void printTable ( const printTableContent cont,
FILE *  fout,
bool  is_pager,
FILE *  flog 
)

Definition at line 3188 of file print.c.

References _, cancel_pressed, ClosePager(), EXIT_FAILURE, printTableOpt::expanded, printTableOpt::format, IsPagerNeeded(), printTableContent::opt, PRINT_ALIGNED, print_aligned_text(), print_aligned_vertical(), PRINT_ASCIIDOC, print_asciidoc_text(), print_asciidoc_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(), printCrosstab(), and printQuery().

3190 {
3191  bool is_local_pager = false;
3192 
3193  if (cancel_pressed)
3194  return;
3195 
3196  if (cont->opt->format == PRINT_NOTHING)
3197  return;
3198 
3199  /* print_aligned_*() handle the pager themselves */
3200  if (!is_pager &&
3201  cont->opt->format != PRINT_ALIGNED &&
3202  cont->opt->format != PRINT_WRAPPED)
3203  {
3204  IsPagerNeeded(cont, 0, (cont->opt->expanded == 1), &fout, &is_pager);
3205  is_local_pager = is_pager;
3206  }
3207 
3208  /* print the stuff */
3209 
3210  if (flog)
3211  print_aligned_text(cont, flog, false);
3212 
3213  switch (cont->opt->format)
3214  {
3215  case PRINT_UNALIGNED:
3216  if (cont->opt->expanded == 1)
3217  print_unaligned_vertical(cont, fout);
3218  else
3219  print_unaligned_text(cont, fout);
3220  break;
3221  case PRINT_ALIGNED:
3222  case PRINT_WRAPPED:
3223 
3224  /*
3225  * In expanded-auto mode, force vertical if a pager is passed in;
3226  * else we may make different decisions for different hunks of the
3227  * query result.
3228  */
3229  if (cont->opt->expanded == 1 ||
3230  (cont->opt->expanded == 2 && is_pager))
3231  print_aligned_vertical(cont, fout, is_pager);
3232  else
3233  print_aligned_text(cont, fout, is_pager);
3234  break;
3235  case PRINT_HTML:
3236  if (cont->opt->expanded == 1)
3237  print_html_vertical(cont, fout);
3238  else
3239  print_html_text(cont, fout);
3240  break;
3241  case PRINT_ASCIIDOC:
3242  if (cont->opt->expanded == 1)
3243  print_asciidoc_vertical(cont, fout);
3244  else
3245  print_asciidoc_text(cont, fout);
3246  break;
3247  case PRINT_LATEX:
3248  if (cont->opt->expanded == 1)
3249  print_latex_vertical(cont, fout);
3250  else
3251  print_latex_text(cont, fout);
3252  break;
3253  case PRINT_LATEX_LONGTABLE:
3254  if (cont->opt->expanded == 1)
3255  print_latex_vertical(cont, fout);
3256  else
3257  print_latex_longtable_text(cont, fout);
3258  break;
3259  case PRINT_TROFF_MS:
3260  if (cont->opt->expanded == 1)
3261  print_troff_ms_vertical(cont, fout);
3262  else
3263  print_troff_ms_text(cont, fout);
3264  break;
3265  default:
3266  fprintf(stderr, _("invalid output format (internal error): %d"),
3267  cont->opt->format);
3268  exit(EXIT_FAILURE);
3269  }
3270 
3271  if (is_local_pager)
3272  ClosePager(fout);
3273 }
static void print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
Definition: print.c:2681
static void print_unaligned_vertical(const printTableContent *cont, FILE *fout)
Definition: print.c:460
void ClosePager(FILE *pagerpipe)
Definition: print.c:2900
static void print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager)
Definition: print.c:582
enum printFormat format
Definition: print.h:98
static void print_aligned_vertical(const printTableContent *cont, FILE *fout, bool is_pager)
Definition: print.c:1230
static void print_troff_ms_text(const printTableContent *cont, FILE *fout)
Definition: print.c:2589
const printTableOpt * opt
Definition: print.h:145
volatile bool cancel_pressed
Definition: print.c:46
static void IsPagerNeeded(const printTableContent *cont, int extra_lines, bool expanded, FILE **fout, bool *is_pager)
Definition: print.c:3148
unsigned short int expanded
Definition: print.h:99
static void print_html_text(const printTableContent *cont, FILE *fout)
Definition: print.c:1786
static void print_latex_text(const printTableContent *cont, FILE *fout)
Definition: print.c:2221
static void print_unaligned_text(const printTableContent *cont, FILE *fout)
Definition: print.c:369
static void print_asciidoc_vertical(const printTableContent *cont, FILE *fout)
Definition: print.c:2088
static void print_html_vertical(const printTableContent *cont, FILE *fout)
Definition: print.c:1875
static void print_latex_longtable_text(const printTableContent *cont, FILE *fout)
Definition: print.c:2323
static void print_asciidoc_text(const printTableContent *cont, FILE *fout)
Definition: print.c:1978
static void print_latex_vertical(const printTableContent *cont, FILE *fout)
Definition: print.c:2479
#define EXIT_FAILURE
Definition: settings.h:151
#define _(x)
Definition: elog.c:84
void printTableAddCell ( printTableContent *const  content,
char *  cell,
const bool  translate,
const bool  mustfree 
)

Definition at line 3008 of file print.c.

References _, printTableContent::cell, printTableContent::cellmustfree, printTableContent::cellsadded, printTableOpt::encoding, EXIT_FAILURE, mbvalidate(), printTableContent::ncolumns, printTableContent::nrows, NULL, printTableContent::opt, and pg_malloc0().

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

3010 {
3011 #ifndef ENABLE_NLS
3012  (void) translate; /* unused parameter */
3013 #endif
3014 
3015  if (content->cellsadded >= content->ncolumns * content->nrows)
3016  {
3017  fprintf(stderr, _("Cannot add cell to table content: "
3018  "total cell count of %d exceeded.\n"),
3019  content->ncolumns * content->nrows);
3020  exit(EXIT_FAILURE);
3021  }
3022 
3023  *content->cell = (char *) mbvalidate((unsigned char *) cell,
3024  content->opt->encoding);
3025 
3026 #ifdef ENABLE_NLS
3027  if (translate)
3028  *content->cell = _(*content->cell);
3029 #endif
3030 
3031  if (mustfree)
3032  {
3033  if (content->cellmustfree == NULL)
3034  content->cellmustfree =
3035  pg_malloc0((content->ncolumns * content->nrows + 1) * sizeof(bool));
3036 
3037  content->cellmustfree[content->cellsadded] = true;
3038  }
3039  content->cell++;
3040  content->cellsadded++;
3041 }
int encoding
Definition: print.h:118
const printTableOpt * opt
Definition: print.h:145
Datum translate(PG_FUNCTION_ARGS)
const char ** cell
Definition: print.h:153
bool * cellmustfree
Definition: print.h:155
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
unsigned char * mbvalidate(unsigned char *pwcs, int encoding)
Definition: mbprint.c:392
long cellsadded
Definition: print.h:154
#define NULL
Definition: c.h:229
#define EXIT_FAILURE
Definition: settings.h:151
#define _(x)
Definition: elog.c:84
void printTableAddFooter ( printTableContent *const  content,
const char *  footer 
)

Definition at line 3056 of file print.c.

References printTableFooter::data, printTableContent::footer, printTableContent::footers, printTableFooter::next, NULL, pg_malloc0(), and pg_strdup().

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

3057 {
3058  printTableFooter *f;
3059 
3060  f = pg_malloc0(sizeof(*f));
3061  f->data = pg_strdup(footer);
3062 
3063  if (content->footers == NULL)
3064  content->footers = f;
3065  else
3066  content->footer->next = f;
3067 
3068  content->footer = f;
3069 }
struct printTableFooter * next
Definition: print.h:136
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
printTableFooter * footer
Definition: print.h:157
#define NULL
Definition: c.h:229
printTableFooter * footers
Definition: print.h:156
char * data
Definition: print.h:135
void printTableAddHeader ( printTableContent *const  content,
char *  header,
const bool  translate,
const char  align 
)

Definition at line 2968 of file print.c.

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

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

2970 {
2971 #ifndef ENABLE_NLS
2972  (void) translate; /* unused parameter */
2973 #endif
2974 
2975  if (content->header >= content->headers + content->ncolumns)
2976  {
2977  fprintf(stderr, _("Cannot add header to table content: "
2978  "column count of %d exceeded.\n"),
2979  content->ncolumns);
2980  exit(EXIT_FAILURE);
2981  }
2982 
2983  *content->header = (char *) mbvalidate((unsigned char *) header,
2984  content->opt->encoding);
2985 #ifdef ENABLE_NLS
2986  if (translate)
2987  *content->header = _(*content->header);
2988 #endif
2989  content->header++;
2990 
2991  *content->align = align;
2992  content->align++;
2993 }
int encoding
Definition: print.h:118
const printTableOpt * opt
Definition: print.h:145
Datum translate(PG_FUNCTION_ARGS)
unsigned char * mbvalidate(unsigned char *pwcs, int encoding)
Definition: mbprint.c:392
const char ** header
Definition: print.h:150
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:207
#define EXIT_FAILURE
Definition: settings.h:151
char * align
Definition: print.h:160
const char ** headers
Definition: print.h:149
#define _(x)
Definition: elog.c:84
void printTableCleanup ( printTableContent *const  content)

Definition at line 3099 of file print.c.

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

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

3100 {
3101  if (content->cellmustfree)
3102  {
3103  int i;
3104 
3105  for (i = 0; i < content->nrows * content->ncolumns; i++)
3106  {
3107  if (content->cellmustfree[i])
3108  free((char *) content->cells[i]);
3109  }
3110  free(content->cellmustfree);
3111  content->cellmustfree = NULL;
3112  }
3113  free(content->headers);
3114  free(content->cells);
3115  free(content->aligns);
3116 
3117  content->opt = NULL;
3118  content->title = NULL;
3119  content->headers = NULL;
3120  content->cells = NULL;
3121  content->aligns = NULL;
3122  content->header = NULL;
3123  content->cell = NULL;
3124  content->align = NULL;
3125 
3126  if (content->footers)
3127  {
3128  for (content->footer = content->footers; content->footer;)
3129  {
3130  printTableFooter *f;
3131 
3132  f = content->footer;
3133  content->footer = f->next;
3134  free(f->data);
3135  free(f);
3136  }
3137  }
3138  content->footers = NULL;
3139  content->footer = NULL;
3140 }
const char * title
Definition: print.h:146
const printTableOpt * opt
Definition: print.h:145
struct printTableFooter * next
Definition: print.h:136
const char ** cell
Definition: print.h:153
bool * cellmustfree
Definition: print.h:155
char * aligns
Definition: print.h:158
const char ** cells
Definition: print.h:151
const char ** header
Definition: print.h:150
printTableFooter * footer
Definition: print.h:157
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
printTableFooter * footers
Definition: print.h:156
int i
char * data
Definition: print.h:135
char * align
Definition: print.h:160
const char ** headers
Definition: print.h:149
void printTableInit ( printTableContent *const  content,
const printTableOpt opt,
const char *  title,
const int  ncolumns,
const int  nrows 
)

Definition at line 2931 of file print.c.

References printTableContent::align, printTableContent::aligns, printTableContent::cell, printTableContent::cellmustfree, printTableContent::cells, printTableContent::cellsadded, printTableContent::footer, printTableContent::footers, printTableContent::header, printTableContent::headers, printTableContent::ncolumns, printTableContent::nrows, NULL, printTableContent::opt, pg_malloc0(), and printTableContent::title.

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

2933 {
2934  content->opt = opt;
2935  content->title = title;
2936  content->ncolumns = ncolumns;
2937  content->nrows = nrows;
2938 
2939  content->headers = pg_malloc0((ncolumns + 1) * sizeof(*content->headers));
2940 
2941  content->cells = pg_malloc0((ncolumns * nrows + 1) * sizeof(*content->cells));
2942 
2943  content->cellmustfree = NULL;
2944  content->footers = NULL;
2945 
2946  content->aligns = pg_malloc0((ncolumns + 1) * sizeof(*content->align));
2947 
2948  content->header = content->headers;
2949  content->cell = content->cells;
2950  content->footer = content->footers;
2951  content->align = content->aligns;
2952  content->cellsadded = 0;
2953 }
const char * title
Definition: print.h:146
const printTableOpt * opt
Definition: print.h:145
const char ** cell
Definition: print.h:153
bool * cellmustfree
Definition: print.h:155
char * aligns
Definition: print.h:158
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
const char ** cells
Definition: print.h:151
long cellsadded
Definition: print.h:154
const char ** header
Definition: print.h:150
printTableFooter * footer
Definition: print.h:157
#define NULL
Definition: c.h:229
printTableFooter * footers
Definition: print.h:156
char * align
Definition: print.h:160
const char ** headers
Definition: print.h:149
void printTableSetFooter ( printTableContent *const  content,
const char *  footer 
)

Definition at line 3081 of file print.c.

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

Referenced by add_tablespace_footer().

3082 {
3083  if (content->footers != NULL)
3084  {
3085  free(content->footer->data);
3086  content->footer->data = pg_strdup(footer);
3087  }
3088  else
3089  printTableAddFooter(content, footer);
3090 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void printTableAddFooter(printTableContent *const content, const char *footer)
Definition: print.c:3056
printTableFooter * footer
Definition: print.h:157
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
printTableFooter * footers
Definition: print.h:156
char * data
Definition: print.h:135
void refresh_utf8format ( const printTableOpt opt)

Definition at line 3426 of file print.c.

References unicodeStyleFormat::border_style, unicodeStyleFormat::column_style, unicodeStyleColumnFormat::down_and_horizontal, unicodeStyleBorderFormat::down_and_left, unicodeStyleBorderFormat::down_and_right, header(), printTextFormat::header_nl_left, unicodeStyleFormat::header_nl_left, printTextFormat::header_nl_right, unicodeStyleFormat::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, printTextFormat::nl_left, unicodeStyleFormat::nl_left, printTextFormat::nl_right, unicodeStyleFormat::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, unicodeStyleColumnFormat::up_and_horizontal, unicodeStyleBorderFormat::up_and_right, unicodeStyleColumnFormat::vertical, unicodeStyleBorderFormat::vertical, unicodeStyleColumnFormat::vertical_and_horizontal, unicodeStyleRowFormat::vertical_and_left, unicodeStyleRowFormat::vertical_and_right, printTextFormat::wrap_left, unicodeStyleFormat::wrap_left, printTextFormat::wrap_right, unicodeStyleFormat::wrap_right, printTextFormat::wrap_right_border, and unicodeStyleFormat::wrap_right_border.

Referenced by do_pset(), and main().

3427 {
3428  printTextFormat *popt = &pg_utf8format;
3429 
3430  const unicodeStyleBorderFormat *border;
3432  const unicodeStyleColumnFormat *column;
3433 
3434  popt->name = "unicode";
3435 
3439 
3440  popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
3441  popt->lrule[PRINT_RULE_TOP].leftvrule = border->down_and_right;
3443  popt->lrule[PRINT_RULE_TOP].rightvrule = border->down_and_left;
3444 
3445  popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
3449 
3450  popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
3451  popt->lrule[PRINT_RULE_BOTTOM].leftvrule = border->up_and_right;
3454 
3455  /* N/A */
3456  popt->lrule[PRINT_RULE_DATA].hrule = "";
3457  popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
3458  popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
3459  popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
3460 
3461  popt->midvrule_nl = column->vertical;
3462  popt->midvrule_wrap = column->vertical;
3463  popt->midvrule_blank = column->vertical;
3464 
3465  /* Same for all unicode today */
3468  popt->nl_left = unicode_style.nl_left;
3473 
3474  return;
3475 }
const char * midvrule
Definition: print.h:45
const char * vertical
Definition: print.c:113
unicodeStyleColumnFormat column_style[2]
Definition: print.c:132
const char * midvrule_wrap
Definition: print.h:72
static const unicodeStyleFormat unicode_style
Definition: print.c:143
const char * header_nl_left
Definition: print.c:134
const char * header_nl_left
Definition: print.h:74
printTextFormat pg_utf8format
Definition: print.c:102
bool wrap_right_border
Definition: print.h:80
const char * wrap_left
Definition: print.c:138
unicode_linestyle unicode_header_linestyle
Definition: print.h:123
printTextLineFormat lrule[4]
Definition: print.h:70
const char * horizontal
Definition: print.c:124
const char * down_and_left
Definition: print.c:125
const char * name
Definition: print.h:69
const char * up_and_right
Definition: print.c:121
const char * midvrule_blank
Definition: print.h:73
unicode_linestyle unicode_border_linestyle
Definition: print.h:121
const char * header_nl_right
Definition: print.c:135
const char * vertical_and_left[2]
Definition: print.c:108
const char * header_nl_right
Definition: print.h:75
unicodeStyleBorderFormat border_style[2]
Definition: print.c:133
const char * down_and_horizontal[2]
Definition: print.c:116
const char * horizontal
Definition: print.c:106
const char * hrule
Definition: print.h:43
const char * vertical_and_horizontal[2]
Definition: print.c:114
unicode_linestyle unicode_column_linestyle
Definition: print.h:122
const char * midvrule_nl
Definition: print.h:71
const char * left_and_right
Definition: print.c:126
const char * wrap_right
Definition: print.c:139
bool wrap_right_border
Definition: print.c:140
const char * nl_left
Definition: print.c:136
const char * leftvrule
Definition: print.h:44
const char * nl_right
Definition: print.c:137
const char * up_and_horizontal[2]
Definition: print.c:115
const char * down_and_right
Definition: print.c:123
const char * nl_right
Definition: print.h:77
const char * vertical
Definition: print.c:122
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:207
const char * vertical_and_right[2]
Definition: print.c:107
const char * nl_left
Definition: print.h:76
const char * rightvrule
Definition: print.h:46
const char * wrap_left
Definition: print.h:78
const char * wrap_right
Definition: print.h:79
unicodeStyleRowFormat row_style[2]
Definition: print.c:131
void restore_sigpipe_trap ( void  )

Definition at line 2824 of file print.c.

References always_ignore_sigpipe, pqsignal(), SIG_DFL, SIG_IGN, and SIGPIPE.

Referenced by ClosePager(), do_copy(), exec_command_write(), ExecQueryUsingCursor(), PageOutput(), PrintQueryTuples(), and setQFout().

2825 {
2826 #ifndef WIN32
2828 #endif
2829 }
#define SIG_IGN
Definition: win32.h:185
static bool always_ignore_sigpipe
Definition: print.c:48
#define SIGPIPE
Definition: win32.h:193
#define SIG_DFL
Definition: win32.h:183
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
void set_sigpipe_trap_state ( bool  ignore)

Definition at line 2837 of file print.c.

References always_ignore_sigpipe.

Referenced by setQFout().

2838 {
2839  always_ignore_sigpipe = ignore;
2840 }
static bool always_ignore_sigpipe
Definition: print.c:48
void setDecimalLocale ( void  )

Definition at line 3376 of file print.c.

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

Referenced by main().

3377 {
3378  struct lconv *extlconv;
3379 
3380  extlconv = localeconv();
3381 
3382  /* Don't accept an empty decimal_point string */
3383  if (*extlconv->decimal_point)
3384  decimal_point = pg_strdup(extlconv->decimal_point);
3385  else
3386  decimal_point = "."; /* SQL output standard */
3387 
3388  /*
3389  * Although the Open Group standard allows locales to supply more than one
3390  * group width, we consider only the first one, and we ignore any attempt
3391  * to suppress grouping by specifying CHAR_MAX. As in the backend's
3392  * cash.c, we must apply a range check to avoid being fooled by variant
3393  * CHAR_MAX values.
3394  */
3395  groupdigits = *extlconv->grouping;
3396  if (groupdigits <= 0 || groupdigits > 6)
3397  groupdigits = 3; /* most common */
3398 
3399  /* Don't accept an empty thousands_sep string, either */
3400  /* similar code exists in formatting.c */
3401  if (*extlconv->thousands_sep)
3402  thousands_sep = pg_strdup(extlconv->thousands_sep);
3403  /* Make sure thousands separator doesn't match decimal point symbol. */
3404  else if (strcmp(decimal_point, ",") != 0)
3405  thousands_sep = ",";
3406  else
3407  thousands_sep = ".";
3408 }
static int groupdigits
Definition: print.c:52
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static char * decimal_point
Definition: print.c:51
static char * thousands_sep
Definition: print.c:53
static int strlen_max_width ( unsigned char *  str,
int *  target_width,
int  encoding 
)
static

Definition at line 3483 of file print.c.

References PQdsplen(), and PQmblen().

Referenced by print_aligned_text(), and print_aligned_vertical().

3484 {
3485  unsigned char *start = str;
3486  unsigned char *end = str + strlen((char *) str);
3487  int curr_width = 0;
3488 
3489  while (str < end)
3490  {
3491  int char_width = PQdsplen((char *) str, encoding);
3492 
3493  /*
3494  * If the display width of the new character causes the string to
3495  * exceed its target width, skip it and return. However, if this is
3496  * the first character of the string (curr_width == 0), we have to
3497  * accept it.
3498  */
3499  if (*target_width < curr_width + char_width && curr_width != 0)
3500  break;
3501 
3502  curr_width += char_width;
3503 
3504  str += PQmblen((char *) str, encoding);
3505  }
3506 
3507  *target_width = curr_width;
3508 
3509  return str - start;
3510 }
int PQdsplen(const char *s, int encoding)
Definition: fe-misc.c:1192
static char * encoding
Definition: initdb.c:122
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1182
static void troff_ms_escaped_print ( const char *  in,
FILE *  fout 
)
static

Definition at line 2572 of file print.c.

Referenced by print_troff_ms_text(), and print_troff_ms_vertical().

2573 {
2574  const char *p;
2575 
2576  for (p = in; *p; p++)
2577  switch (*p)
2578  {
2579  case '\\':
2580  fputs("\\(rs", fout);
2581  break;
2582  default:
2583  fputc(*p, fout);
2584  }
2585 }

Variable Documentation

bool always_ignore_sigpipe = false
static

Definition at line 48 of file print.c.

Referenced by restore_sigpipe_trap(), and set_sigpipe_trap_state().

char* decimal_point
static

Definition at line 51 of file print.c.

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

char default_footer[100]
static

Definition at line 55 of file print.c.

Referenced by footers_with_default().

printTableFooter default_footer_cell = {default_footer, NULL}
static

Definition at line 56 of file print.c.

Referenced by footers_with_default().

int groupdigits
static

Definition at line 52 of file print.c.

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

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

Definition at line 59 of file print.c.

Referenced by do_pset(), and get_line_style().

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

Definition at line 80 of file print.c.

Referenced by do_pset().

printTextFormat pg_utf8format

Definition at line 102 of file print.c.

Referenced by do_pset(), and refresh_utf8format().

char* thousands_sep
static

Definition at line 53 of file print.c.

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

const unicodeStyleFormat unicode_style
static

Definition at line 143 of file print.c.