/*------------------------------------------------------------------------- * * Query-result printing support for frontend code * * * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fe_utils/print.h * *------------------------------------------------------------------------- */ #ifndef PRINT_H #define PRINT_H #include #include "libpq-fe.h" /* This is not a particularly great place for this ... */ #ifndef __CYGWIN__ #define DEFAULT_PAGER "more" #else #define DEFAULT_PAGER "less" #endif enum printFormat { PRINT_NOTHING = 0, /* to make sure someone initializes this */ PRINT_ALIGNED, PRINT_ASCIIDOC, PRINT_CSV, PRINT_HTML, PRINT_LATEX, PRINT_LATEX_LONGTABLE, PRINT_TROFF_MS, PRINT_UNALIGNED, PRINT_WRAPPED /* add your favourite output format here ... */ }; typedef struct printTextLineFormat { /* Line drawing characters to be used in various contexts */ const char *hrule; /* horizontal line character */ const char *leftvrule; /* left vertical line (+horizontal) */ const char *midvrule; /* intra-column vertical line (+horizontal) */ const char *rightvrule; /* right vertical line (+horizontal) */ } printTextLineFormat; typedef enum printTextRule { /* Additional context for selecting line drawing characters */ PRINT_RULE_TOP, /* top horizontal line */ PRINT_RULE_MIDDLE, /* intra-data horizontal line */ PRINT_RULE_BOTTOM, /* bottom horizontal line */ PRINT_RULE_DATA /* data line (hrule is unused here) */ } printTextRule; typedef enum printTextLineWrap { /* Line wrapping conditions */ PRINT_LINE_WRAP_NONE, /* No wrapping */ PRINT_LINE_WRAP_WRAP, /* Wraparound due to overlength line */ PRINT_LINE_WRAP_NEWLINE /* Newline in data */ } printTextLineWrap; typedef enum printXheaderWidthType { /* Expanded header line width variants */ PRINT_XHEADER_FULL, /* do not truncate header line (this is the * default) */ PRINT_XHEADER_COLUMN, /* only print header line above the first * column */ PRINT_XHEADER_PAGE, /* header line must not be longer than * terminal width */ PRINT_XHEADER_EXACT_WIDTH, /* explicitly specified width */ } printXheaderWidthType; typedef struct printTextFormat { /* A complete line style */ const char *name; /* for display purposes */ printTextLineFormat lrule[4]; /* indexed by enum printTextRule */ const char *midvrule_nl; /* vertical line for continue after newline */ const char *midvrule_wrap; /* vertical line for wrapped data */ const char *midvrule_blank; /* vertical line for blank data */ const char *header_nl_left; /* left mark after newline */ const char *header_nl_right; /* right mark for newline */ const char *nl_left; /* left mark after newline */ const char *nl_right; /* right mark for newline */ const char *wrap_left; /* left mark after wrapped data */ const char *wrap_right; /* right mark for wrapped data */ bool wrap_right_border; /* use right-hand border for wrap marks * when border=0? */ } printTextFormat; typedef enum unicode_linestyle { UNICODE_LINESTYLE_SINGLE = 0, UNICODE_LINESTYLE_DOUBLE } unicode_linestyle; struct separator { char *separator; bool separator_zero; }; typedef struct printTableOpt { enum printFormat format; /* see enum above */ unsigned short int expanded; /* expanded/vertical output (if supported * by output format); 0=no, 1=yes, 2=auto */ printXheaderWidthType expanded_header_width_type; /* width type for header * line in expanded mode */ int expanded_header_exact_width; /* explicit width for header * line in expanded mode */ unsigned short int border; /* Print a border around the table. 0=none, * 1=dividing lines, 2=full */ unsigned short int pager; /* use pager for output (if to stdout and * stdout is a tty) 0=off 1=on 2=always */ int pager_min_lines; /* don't use pager unless there are at * least this many lines */ bool tuples_only; /* don't output headers, row counts, etc. */ bool start_table; /* print start decoration, eg */ bool stop_table; /* print stop decoration, eg
*/ bool default_footer; /* allow "(xx rows)" default footer */ unsigned long prior_records; /* start offset for record counters */ const printTextFormat *line_style; /* line style (NULL for default) */ struct separator fieldSep; /* field separator for unaligned text mode */ struct separator recordSep; /* record separator for unaligned text mode */ char csvFieldSep[2]; /* field separator for csv format */ bool numericLocale; /* locale-aware numeric units separator and * decimal marker */ char *tableAttr; /* attributes for HTML */ int encoding; /* character encoding */ int env_columns; /* $COLUMNS on psql start, 0 is unset */ int columns; /* target width for wrapped format */ unicode_linestyle unicode_border_linestyle; unicode_linestyle unicode_column_linestyle; unicode_linestyle unicode_header_linestyle; } printTableOpt; /* * Table footers are implemented as a singly-linked list. * * This is so that you don't need to know the number of footers in order to * initialise the printTableContent struct, which is very convenient when * preparing complex footers (as in describeOneTableDetails). */ typedef struct printTableFooter { char *data; struct printTableFooter *next; } printTableFooter; /* * The table content struct holds all the information which will be displayed * by printTable(). */ typedef struct printTableContent { const printTableOpt *opt; const char *title; /* May be NULL */ int ncolumns; /* Specified in Init() */ int nrows; /* Specified in Init() */ const char **headers; /* NULL-terminated array of header strings */ const char **header; /* Pointer to the last added header */ const char **cells; /* NULL-terminated array of cell content * strings */ const char **cell; /* Pointer to the last added cell */ long cellsadded; /* Number of cells added this far */ bool *cellmustfree; /* true for cells that need to be free()d */ printTableFooter *footers; /* Pointer to the first footer */ printTableFooter *footer; /* Pointer to the last added footer */ char *aligns; /* Array of alignment specifiers; 'l' or 'r', * one per column */ char *align; /* Pointer to the last added alignment */ } printTableContent; typedef struct printQueryOpt { printTableOpt topt; /* the options above */ char *nullPrint; /* how to print null entities */ char *title; /* override title */ char **footers; /* override footer (default is "(xx rows)") */ bool translate_header; /* do gettext on column headers */ const bool *translate_columns; /* translate_columns[i-1] => do gettext on * col i */ int n_translate_columns; /* length of translate_columns[] */ } printQueryOpt; extern PGDLLIMPORT volatile sig_atomic_t cancel_pressed; extern PGDLLIMPORT const printTextFormat pg_asciiformat; extern PGDLLIMPORT const printTextFormat pg_asciiformat_old; extern PGDLLIMPORT printTextFormat pg_utf8format; /* ideally would be const, * but... */ extern void disable_sigpipe_trap(void); extern void restore_sigpipe_trap(void); extern void set_sigpipe_trap_state(bool ignore); extern FILE *PageOutput(int lines, const printTableOpt *topt); extern void ClosePager(FILE *pagerpipe); extern void html_escaped_print(const char *in, FILE *fout); extern void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows); extern void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align); extern void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree); extern void printTableAddFooter(printTableContent *const content, const char *footer); extern void printTableSetFooter(printTableContent *const content, const char *footer); extern void printTableCleanup(printTableContent *const content); extern void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog); extern void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog); extern char column_type_alignment(Oid); extern void setDecimalLocale(void); extern const printTextFormat *get_line_style(const printTableOpt *opt); extern void refresh_utf8format(const printTableOpt *opt); #endif /* PRINT_H */