1 /*-------------------------------------------------------------------------
2  *
3  * Query-result printing support for frontend code
4  *
5  *
6  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * src/include/fe_utils/print.h
10  *
11  *-------------------------------------------------------------------------
12  */
13 #ifndef PRINT_H
14 #define PRINT_H
15 
16 #include "libpq-fe.h"
17 
18 
19 /* This is not a particularly great place for this ... */
20 #ifndef __CYGWIN__
21 #define DEFAULT_PAGER "more"
22 #else
23 #define DEFAULT_PAGER "less"
24 #endif
25 
26 enum printFormat
27 {
28 	PRINT_NOTHING = 0,			/* to make sure someone initializes this */
29 	PRINT_UNALIGNED,
30 	PRINT_ALIGNED,
31 	PRINT_WRAPPED,
32 	PRINT_HTML,
33 	PRINT_ASCIIDOC,
34 	PRINT_LATEX,
35 	PRINT_LATEX_LONGTABLE,
36 	PRINT_TROFF_MS
37 	/* add your favourite output format here ... */
38 };
39 
40 typedef struct printTextLineFormat
41 {
42 	/* Line drawing characters to be used in various contexts */
43 	const char *hrule;			/* horizontal line character */
44 	const char *leftvrule;		/* left vertical line (+horizontal) */
45 	const char *midvrule;		/* intra-column vertical line (+horizontal) */
46 	const char *rightvrule;		/* right vertical line (+horizontal) */
47 } printTextLineFormat;
48 
49 typedef enum printTextRule
50 {
51 	/* Additional context for selecting line drawing characters */
52 	PRINT_RULE_TOP,				/* top horizontal line */
53 	PRINT_RULE_MIDDLE,			/* intra-data horizontal line */
54 	PRINT_RULE_BOTTOM,			/* bottom horizontal line */
55 	PRINT_RULE_DATA				/* data line (hrule is unused here) */
56 } printTextRule;
57 
58 typedef enum printTextLineWrap
59 {
60 	/* Line wrapping conditions */
61 	PRINT_LINE_WRAP_NONE,		/* No wrapping */
62 	PRINT_LINE_WRAP_WRAP,		/* Wraparound due to overlength line */
63 	PRINT_LINE_WRAP_NEWLINE		/* Newline in data */
64 } printTextLineWrap;
65 
66 typedef struct printTextFormat
67 {
68 	/* A complete line style */
69 	const char *name;			/* for display purposes */
70 	printTextLineFormat lrule[4];		/* indexed by enum printTextRule */
71 	const char *midvrule_nl;	/* vertical line for continue after newline */
72 	const char *midvrule_wrap;	/* vertical line for wrapped data */
73 	const char *midvrule_blank; /* vertical line for blank data */
74 	const char *header_nl_left; /* left mark after newline */
75 	const char *header_nl_right;	/* right mark for newline */
76 	const char *nl_left;		/* left mark after newline */
77 	const char *nl_right;		/* right mark for newline */
78 	const char *wrap_left;		/* left mark after wrapped data */
79 	const char *wrap_right;		/* right mark for wrapped data */
80 	bool		wrap_right_border;		/* use right-hand border for wrap
81 										 * marks when border=0? */
82 } printTextFormat;
83 
84 typedef enum unicode_linestyle
85 {
86 	UNICODE_LINESTYLE_SINGLE = 0,
87 	UNICODE_LINESTYLE_DOUBLE
88 } unicode_linestyle;
89 
90 struct separator
91 {
92 	char	   *separator;
93 	bool		separator_zero;
94 };
95 
96 typedef struct printTableOpt
97 {
98 	enum printFormat format;	/* see enum above */
99 	unsigned short int expanded;/* expanded/vertical output (if supported by
100 								 * output format); 0=no, 1=yes, 2=auto */
101 	unsigned short int border;	/* Print a border around the table. 0=none,
102 								 * 1=dividing lines, 2=full */
103 	unsigned short int pager;	/* use pager for output (if to stdout and
104 								 * stdout is a tty) 0=off 1=on 2=always */
105 	int			pager_min_lines;/* don't use pager unless there are at least
106 								 * this many lines */
107 	bool		tuples_only;	/* don't output headers, row counts, etc. */
108 	bool		start_table;	/* print start decoration, eg <table> */
109 	bool		stop_table;		/* print stop decoration, eg </table> */
110 	bool		default_footer; /* allow "(xx rows)" default footer */
111 	unsigned long prior_records;	/* start offset for record counters */
112 	const printTextFormat *line_style;	/* line style (NULL for default) */
113 	struct separator fieldSep;	/* field separator for unaligned text mode */
114 	struct separator recordSep; /* record separator for unaligned text mode */
115 	bool		numericLocale;	/* locale-aware numeric units separator and
116 								 * decimal marker */
117 	char	   *tableAttr;		/* attributes for HTML <table ...> */
118 	int			encoding;		/* character encoding */
119 	int			env_columns;	/* $COLUMNS on psql start, 0 is unset */
120 	int			columns;		/* target width for wrapped format */
121 	unicode_linestyle unicode_border_linestyle;
122 	unicode_linestyle unicode_column_linestyle;
123 	unicode_linestyle unicode_header_linestyle;
124 } printTableOpt;
125 
126 /*
127  * Table footers are implemented as a singly-linked list.
128  *
129  * This is so that you don't need to know the number of footers in order to
130  * initialise the printTableContent struct, which is very convenient when
131  * preparing complex footers (as in describeOneTableDetails).
132  */
133 typedef struct printTableFooter
134 {
135 	char	   *data;
136 	struct printTableFooter *next;
137 } printTableFooter;
138 
139 /*
140  * The table content struct holds all the information which will be displayed
141  * by printTable().
142  */
143 typedef struct printTableContent
144 {
145 	const printTableOpt *opt;
146 	const char *title;			/* May be NULL */
147 	int			ncolumns;		/* Specified in Init() */
148 	int			nrows;			/* Specified in Init() */
149 	const char **headers;		/* NULL-terminated array of header strings */
150 	const char **header;		/* Pointer to the last added header */
151 	const char **cells;			/* NULL-terminated array of cell content
152 								 * strings */
153 	const char **cell;			/* Pointer to the last added cell */
154 	long		cellsadded;		/* Number of cells added this far */
155 	bool	   *cellmustfree;	/* true for cells that need to be free()d */
156 	printTableFooter *footers;	/* Pointer to the first footer */
157 	printTableFooter *footer;	/* Pointer to the last added footer */
158 	char	   *aligns;			/* Array of alignment specifiers; 'l' or 'r',
159 								 * one per column */
160 	char	   *align;			/* Pointer to the last added alignment */
161 } printTableContent;
162 
163 typedef struct printQueryOpt
164 {
165 	printTableOpt topt;			/* the options above */
166 	char	   *nullPrint;		/* how to print null entities */
167 	char	   *title;			/* override title */
168 	char	  **footers;		/* override footer (default is "(xx rows)") */
169 	bool		translate_header;		/* do gettext on column headers */
170 	const bool *translate_columns;		/* translate_columns[i-1] => do
171 										 * gettext on col i */
172 	int			n_translate_columns;	/* length of translate_columns[] */
173 } printQueryOpt;
174 
175 
176 extern volatile bool cancel_pressed;
177 
178 extern const printTextFormat pg_asciiformat;
179 extern const printTextFormat pg_asciiformat_old;
180 extern printTextFormat pg_utf8format;	/* ideally would be const, but... */
181 
182 
183 extern void disable_sigpipe_trap(void);
184 extern void restore_sigpipe_trap(void);
185 extern void set_sigpipe_trap_state(bool ignore);
186 
187 extern FILE *PageOutput(int lines, const printTableOpt *topt);
188 extern void ClosePager(FILE *pagerpipe);
189 
190 extern void html_escaped_print(const char *in, FILE *fout);
191 
192 extern void printTableInit(printTableContent *const content,
193 			   const printTableOpt *opt, const char *title,
194 			   const int ncolumns, const int nrows);
195 extern void printTableAddHeader(printTableContent *const content,
196 					char *header, const bool translate, const char align);
197 extern void printTableAddCell(printTableContent *const content,
198 				  char *cell, const bool translate, const bool mustfree);
199 extern void printTableAddFooter(printTableContent *const content,
200 					const char *footer);
201 extern void printTableSetFooter(printTableContent *const content,
202 					const char *footer);
203 extern void printTableCleanup(printTableContent *const content);
204 extern void printTable(const printTableContent *cont,
205 		   FILE *fout, bool is_pager, FILE *flog);
206 extern void printQuery(const PGresult *result, const printQueryOpt *opt,
207 		   FILE *fout, bool is_pager, FILE *flog);
208 
209 extern char column_type_alignment(Oid);
210 
211 extern void setDecimalLocale(void);
212 extern const printTextFormat *get_line_style(const printTableOpt *opt);
213 extern void refresh_utf8format(const printTableOpt *opt);
214 
215 #endif   /* PRINT_H */
216