summaryrefslogtreecommitdiffstats
path: root/src/include/fe_utils/print.h
blob: cc6652def9eba41c7fabff03062992b1b8a0e3a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*-------------------------------------------------------------------------
 *
 * 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 <signal.h>

#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 <table> */
	bool		stop_table;		/* print stop decoration, eg </table> */
	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 <table ...> */
	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 */