/*
 * psql - the PostgreSQL interactive terminal
 *
 * Copyright (c) 2000-2010, PostgreSQL Global Development Group
 *
 * src/bin/psql/print.c
 */
#include "postgres_fe.h"

#include <limits.h>
#include <math.h>
#include <signal.h>
#include <unistd.h>

#ifndef WIN32
#include <sys/ioctl.h>			/* for ioctl() */
#endif

#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif

#include <locale.h>

#include "catalog/pg_type.h"
#include "pqsignal.h"

#include "common.h"
#include "mbprint.h"
#include "print.h"

/*
 * We define the cancel_pressed flag in this file, rather than common.c where
 * it naturally belongs, because this file is also used by non-psql programs
 * (see the bin/scripts/ directory).  In those programs cancel_pressed will
 * never become set and will have no effect.
 *
 * Note: print.c's general strategy for when to check cancel_pressed is to do
 * so at completion of each row of output.
 */
volatile bool cancel_pressed = false;

static char *decimal_point;
static char *grouping;
static char *thousands_sep;

/* Line style control structures */
const printTextFormat pg_asciiformat =
{
	"ascii",
	{
		{"-", "+", "+", "+"},
		{"-", "+", "+", "+"},
		{"-", "+", "+", "+"},
		{"", "|", "|", "|"}
	},
	"|",
	"|",
	"|",
	" ",
	"+",
	" ",
	"+",
	".",
	".",
	true
};

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

const printTextFormat pg_utf8format =
{
	"unicode",
	{
		/* ─, ┌, ┬, ┐ */
		{"\342\224\200", "\342\224\214", "\342\224\254", "\342\224\220"},
		/* ─, ├, ┼, ┤ */
		{"\342\224\200", "\342\224\234", "\342\224\274", "\342\224\244"},
		/* ─, └, ┴, ┘ */
		{"\342\224\200", "\342\224\224", "\342\224\264", "\342\224\230"},
		/* N/A, │, │, │ */
		{"", "\342\224\202", "\342\224\202", "\342\224\202"}
	},
	/* │ */
	"\342\224\202",
	/* │ */
	"\342\224\202",
	/* │ */
	"\342\224\202",
	" ",
	/* ↵ */
	"\342\206\265",
	" ",
	/* ↵ */
	"\342\206\265",
	/* … */
	"\342\200\246",
	/* … */
	"\342\200\246",
	true
};


/* Local functions */
static int	strlen_max_width(unsigned char *str, int *target_width, int encoding);
static void IsPagerNeeded(const printTableContent *cont, const int extra_lines,
			  FILE **fout, bool *is_pager);


static void *
pg_local_malloc(size_t size)
{
	void	   *tmp;

	tmp = malloc(size);
	if (!tmp)
	{
		fprintf(stderr, _("out of memory\n"));
		exit(EXIT_FAILURE);
	}
	return tmp;
}

static void *
pg_local_calloc(int count, size_t size)
{
	void	   *tmp;

	tmp = calloc(count, size);
	if (!tmp)
	{
		fprintf(stderr, _("out of memory\n"));
		exit(EXIT_FAILURE);
	}
	return tmp;
}

static int
integer_digits(const char *my_str)
{
	int			frac_len;

	if (my_str[0] == '-')
		my_str++;

	frac_len = strchr(my_str, '.') ? strlen(strchr(my_str, '.')) : 0;

	return strlen(my_str) - frac_len;
}

/* Return additional length required for locale-aware numeric output */
static int
additional_numeric_locale_len(const char *my_str)
{
	int			int_len = integer_digits(my_str),
				len = 0;
	int			groupdigits = atoi(grouping);

	if (int_len > 0)
		/* Don't count a leading separator */
		len = (int_len / groupdigits - (int_len % groupdigits == 0)) *
			strlen(thousands_sep);

	if (strchr(my_str, '.') != NULL)
		len += strlen(decimal_point) - strlen(".");

	return len;
}

static int
strlen_with_numeric_locale(const char *my_str)
{
	return strlen(my_str) + additional_numeric_locale_len(my_str);
}

/*
 * Returns the appropriately formatted string in a new allocated block,
 * caller must free
 */
static char *
format_numeric_locale(const char *my_str)
{
	int			i,
				j,
				int_len = integer_digits(my_str),
				leading_digits;
	int			groupdigits = atoi(grouping);
	int			new_str_start = 0;
	char	   *new_str = new_str = pg_local_malloc(
									 strlen_with_numeric_locale(my_str) + 1);

	leading_digits = (int_len % groupdigits != 0) ?
		int_len % groupdigits : groupdigits;

	if (my_str[0] == '-')		/* skip over sign, affects grouping
								 * calculations */
	{
		new_str[0] = my_str[0];
		my_str++;
		new_str_start = 1;
	}

	for (i = 0, j = new_str_start;; i++, j++)
	{
		/* Hit decimal point? */
		if (my_str[i] == '.')
		{
			strcpy(&new_str[j], decimal_point);
			j += strlen(decimal_point);
			/* add fractional part */
			strcpy(&new_str[j], &my_str[i] + 1);
			break;
		}

		/* End of string? */
		if (my_str[i] == '\0')
		{
			new_str[j] = '\0';
			break;
		}

		/* Add separator? */
		if (i != 0 && (i - leading_digits) % groupdigits == 0)
		{
			strcpy(&new_str[j], thousands_sep);
			j += strlen(thousands_sep);
		}

		new_str[j] = my_str[i];
	}

	return new_str;
}


/*
 * fputnbytes: print exactly N bytes to a file
 *
 * We avoid using %.*s here because it can misbehave if the data
 * is not valid in what libc thinks is the prevailing encoding.
 */
static void
fputnbytes(FILE *f, const char *str, size_t n)
{
	while (n-- > 0)
		fputc(*str++, f);
}


/*************************/
/* Unaligned text		 */
/*************************/


static void
print_unaligned_text(const printTableContent *cont, FILE *fout)
{
	const char *opt_fieldsep = cont->opt->fieldSep;
	const char *opt_recordsep = cont->opt->recordSep;
	bool		opt_tuples_only = cont->opt->tuples_only;
	unsigned int i;
	const char *const * ptr;
	bool		need_recordsep = false;

	if (cancel_pressed)
		return;

	if (!opt_fieldsep)
		opt_fieldsep = "";
	if (!opt_recordsep)
		opt_recordsep = "";

	if (cont->opt->start_table)
	{
		/* print title */
		if (!opt_tuples_only && cont->title)
			fprintf(fout, "%s%s", cont->title, opt_recordsep);

		/* print headers */
		if (!opt_tuples_only)
		{
			for (ptr = cont->headers; *ptr; ptr++)
			{
				if (ptr != cont->headers)
					fputs(opt_fieldsep, fout);
				fputs(*ptr, fout);
			}
			need_recordsep = true;
		}
	}
	else
		/* assume continuing printout */
		need_recordsep = true;

	/* print cells */
	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
	{
		if (need_recordsep)
		{
			fputs(opt_recordsep, fout);
			need_recordsep = false;
			if (cancel_pressed)
				break;
		}
		fputs(*ptr, fout);

		if ((i + 1) % cont->ncolumns)
			fputs(opt_fieldsep, fout);
		else
			need_recordsep = true;
	}

	/* print footers */
	if (cont->opt->stop_table)
	{
		if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
		{
			printTableFooter *f;

			for (f = cont->footers; f; f = f->next)
			{
				if (need_recordsep)
				{
					fputs(opt_recordsep, fout);
					need_recordsep = false;
				}
				fputs(f->data, fout);
				need_recordsep = true;
			}
		}
		/* the last record needs to be concluded with a newline */
		if (need_recordsep)
			fputc('\n', fout);
	}
}


static void
print_unaligned_vertical(const printTableContent *cont, FILE *fout)
{
	const char *opt_fieldsep = cont->opt->fieldSep;
	const char *opt_recordsep = cont->opt->recordSep;
	bool		opt_tuples_only = cont->opt->tuples_only;
	unsigned int i;
	const char *const * ptr;
	bool		need_recordsep = false;

	if (cancel_pressed)
		return;

	if (!opt_fieldsep)
		opt_fieldsep = "";
	if (!opt_recordsep)
		opt_recordsep = "";

	if (cont->opt->start_table)
	{
		/* print title */
		if (!opt_tuples_only && cont->title)
		{
			fputs(cont->title, fout);
			need_recordsep = true;
		}
	}
	else
		/* assume continuing printout */
		need_recordsep = true;

	/* print records */
	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
	{
		if (need_recordsep)
		{
			/* record separator is 2 occurrences of recordsep in this mode */
			fputs(opt_recordsep, fout);
			fputs(opt_recordsep, fout);
			need_recordsep = false;
			if (cancel_pressed)
				break;
		}

		fputs(cont->headers[i % cont->ncolumns], fout);
		fputs(opt_fieldsep, fout);
		fputs(*ptr, fout);

		if ((i + 1) % cont->ncolumns)
			fputs(opt_recordsep, fout);
		else
			need_recordsep = true;
	}

	if (cont->opt->stop_table)
	{
		/* print footers */
		if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
		{
			printTableFooter *f;

			fputs(opt_recordsep, fout);
			for (f = cont->footers; f; f = f->next)
			{
				fputs(opt_recordsep, fout);
				fputs(f->data, fout);
			}
		}

		fputc('\n', fout);
	}
}


/********************/
/* Aligned text		*/
/********************/


/* draw "line" */
static void
_print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths,
					   unsigned short border, printTextRule pos,
					   const printTextFormat *format,
					   FILE *fout)
{
	const printTextLineFormat *lformat = &format->lrule[pos];
	unsigned int i,
				j;

	if (border == 1)
		fputs(lformat->hrule, fout);
	else if (border == 2)
		fprintf(fout, "%s%s", lformat->leftvrule, lformat->hrule);

	for (i = 0; i < ncolumns; i++)
	{
		for (j = 0; j < widths[i]; j++)
			fputs(lformat->hrule, fout);

		if (i < ncolumns - 1)
		{
			if (border == 0)
				fputc(' ', fout);
			else
				fprintf(fout, "%s%s%s", lformat->hrule,
						lformat->midvrule, lformat->hrule);
		}
	}

	if (border == 2)
		fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
	else if (border == 1)
		fputs(lformat->hrule, fout);

	fputc('\n', fout);
}


/*
 *	Print pretty boxes around cells.
 */
static void
print_aligned_text(const printTableContent *cont, FILE *fout)
{
	bool		opt_tuples_only = cont->opt->tuples_only;
	int			encoding = cont->opt->encoding;
	unsigned short opt_border = cont->opt->border;
	const printTextFormat *format = get_line_style(cont->opt);
	const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];

	unsigned int col_count = 0,
				cell_count = 0;

	unsigned int i,
				j;

	unsigned int *width_header,
			   *max_width,
			   *width_wrap,
			   *width_average;
	unsigned int *max_nl_lines, /* value split by newlines */
			   *curr_nl_line,
			   *max_bytes;
	unsigned char **format_buf;
	unsigned int width_total;
	unsigned int total_header_width;
	unsigned int extra_row_output_lines = 0;
	unsigned int extra_output_lines = 0;

	const char *const * ptr;

	struct lineptr **col_lineptrs;		/* pointers to line pointer per column */

	bool	   *header_done;	/* Have all header lines been output? */
	int		   *bytes_output;	/* Bytes output for column value */
	printTextLineWrap *wrap;	/* Wrap status for each column */
	int			output_columns = 0;		/* Width of interactive console */
	bool		is_pager = false;

	if (cancel_pressed)
		return;

	if (opt_border > 2)
		opt_border = 2;

	if (cont->ncolumns > 0)
	{
		col_count = cont->ncolumns;
		width_header = pg_local_calloc(col_count, sizeof(*width_header));
		width_average = pg_local_calloc(col_count, sizeof(*width_average));
		max_width = pg_local_calloc(col_count, sizeof(*max_width));
		width_wrap = pg_local_calloc(col_count, sizeof(*width_wrap));
		max_nl_lines = pg_local_calloc(col_count, sizeof(*max_nl_lines));
		curr_nl_line = pg_local_calloc(col_count, sizeof(*curr_nl_line));
		col_lineptrs = pg_local_calloc(col_count, sizeof(*col_lineptrs));
		max_bytes = pg_local_calloc(col_count, sizeof(*max_bytes));
		format_buf = pg_local_calloc(col_count, sizeof(*format_buf));
		header_done = pg_local_calloc(col_count, sizeof(*header_done));
		bytes_output = pg_local_calloc(col_count, sizeof(*bytes_output));
		wrap = pg_local_calloc(col_count, sizeof(*wrap));
	}
	else
	{
		width_header = NULL;
		width_average = NULL;
		max_width = NULL;
		width_wrap = NULL;
		max_nl_lines = NULL;
		curr_nl_line = NULL;
		col_lineptrs = NULL;
		max_bytes = NULL;
		format_buf = NULL;
		header_done = NULL;
		bytes_output = NULL;
		wrap = NULL;
	}

	/* scan all column headers, find maximum width and max max_nl_lines */
	for (i = 0; i < col_count; i++)
	{
		int			width,
					nl_lines,
					bytes_required;

		pg_wcssize((unsigned char *) cont->headers[i], strlen(cont->headers[i]),
				   encoding, &width, &nl_lines, &bytes_required);
		if (width > max_width[i])
			max_width[i] = width;
		if (nl_lines > max_nl_lines[i])
			max_nl_lines[i] = nl_lines;
		if (bytes_required > max_bytes[i])
			max_bytes[i] = bytes_required;
		if (nl_lines > extra_row_output_lines)
			extra_row_output_lines = nl_lines;

		width_header[i] = width;
	}
	/* Add height of tallest header column */
	extra_output_lines += extra_row_output_lines;
	extra_row_output_lines = 0;

	/* scan all cells, find maximum width, compute cell_count */
	for (i = 0, ptr = cont->cells; *ptr; ptr++, i++, cell_count++)
	{
		int			width,
					nl_lines,
					bytes_required;

		pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
				   &width, &nl_lines, &bytes_required);

		if (width > max_width[i % col_count])
			max_width[i % col_count] = width;
		if (nl_lines > max_nl_lines[i % col_count])
			max_nl_lines[i % col_count] = nl_lines;
		if (bytes_required > max_bytes[i % col_count])
			max_bytes[i % col_count] = bytes_required;

		width_average[i % col_count] += width;
	}

	/* If we have rows, compute average */
	if (col_count != 0 && cell_count != 0)
	{
		int			rows = cell_count / col_count;

		for (i = 0; i < col_count; i++)
			width_average[i] /= rows;
	}

	/* adjust the total display width based on border style */
	if (opt_border == 0)
		width_total = col_count;
	else if (opt_border == 1)
		width_total = col_count * 3 - 1;
	else
		width_total = col_count * 3 + 1;
	total_header_width = width_total;

	for (i = 0; i < col_count; i++)
	{
		width_total += max_width[i];
		total_header_width += width_header[i];
	}

	/*
	 * At this point: max_width[] contains the max width of each column,
	 * max_nl_lines[] contains the max number of lines in each column,
	 * max_bytes[] contains the maximum storage space for formatting strings,
	 * width_total contains the giant width sum.  Now we allocate some memory
	 * for line pointers.
	 */
	for (i = 0; i < col_count; i++)
	{
		/* Add entry for ptr == NULL array termination */
		col_lineptrs[i] = pg_local_calloc(max_nl_lines[i] + 1,
										  sizeof(**col_lineptrs));

		format_buf[i] = pg_local_malloc(max_bytes[i] + 1);

		col_lineptrs[i]->ptr = format_buf[i];
	}

	/* Default word wrap to the full width, i.e. no word wrap */
	for (i = 0; i < col_count; i++)
		width_wrap[i] = max_width[i];

	/*
	 * Choose target output width: \pset columns, or $COLUMNS, or ioctl
	 */
	if (cont->opt->columns > 0)
		output_columns = cont->opt->columns;
	else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
	{
		if (cont->opt->env_columns > 0)
			output_columns = cont->opt->env_columns;
#ifdef TIOCGWINSZ
		else
		{
			struct winsize screen_size;

			if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1)
				output_columns = screen_size.ws_col;
		}
#endif
	}

	if (cont->opt->format == PRINT_WRAPPED)
	{
		/*
		 * Optional optimized word wrap. Shrink columns with a high max/avg
		 * ratio.  Slighly bias against wider columns. (Increases chance a
		 * narrow column will fit in its cell.)  If available columns is
		 * positive...	and greater than the width of the unshrinkable column
		 * headers
		 */
		if (output_columns > 0 && output_columns >= total_header_width)
		{
			/* While there is still excess width... */
			while (width_total > output_columns)
			{
				double		max_ratio = 0;
				int			worst_col = -1;

				/*
				 * Find column that has the highest ratio of its maximum width
				 * compared to its average width.  This tells us which column
				 * will produce the fewest wrapped values if shortened.
				 * width_wrap starts as equal to max_width.
				 */
				for (i = 0; i < col_count; i++)
				{
					if (width_average[i] && width_wrap[i] > width_header[i])
					{
						/* Penalize wide columns by 1% of their width */
						double		ratio;

						ratio = (double) width_wrap[i] / width_average[i] +
							max_width[i] * 0.01;
						if (ratio > max_ratio)
						{
							max_ratio = ratio;
							worst_col = i;
						}
					}
				}

				/* Exit loop if we can't squeeze any more. */
				if (worst_col == -1)
					break;

				/* Decrease width of target column by one. */
				width_wrap[worst_col]--;
				width_total--;
			}
		}
	}

	/* If we wrapped beyond the display width, use the pager */
	if (!is_pager && fout == stdout && output_columns > 0 &&
		(output_columns < total_header_width || output_columns < width_total))
	{
		fout = PageOutput(INT_MAX, cont->opt->pager);	/* force pager */
		is_pager = true;
	}

	/* Check if newlines or our wrapping now need the pager */
	if (!is_pager)
	{
		/* scan all cells, find maximum width, compute cell_count */
		for (i = 0, ptr = cont->cells; *ptr; ptr++, cell_count++)
		{
			int			width,
						nl_lines,
						bytes_required;

			pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
					   &width, &nl_lines, &bytes_required);

			/*
			 * A row can have both wrapping and newlines that cause it to
			 * display across multiple lines.  We check for both cases below.
			 */
			if (width > 0 && width_wrap[i])
			{
				unsigned int extra_lines;

				extra_lines = (width - 1) / width_wrap[i] + nl_lines;
				if (extra_lines > extra_row_output_lines)
					extra_row_output_lines = extra_lines;
			}

			/* i is the current column number: increment with wrap */
			if (++i >= col_count)
			{
				i = 0;
				/* At last column of each row, add tallest column height */
				extra_output_lines += extra_row_output_lines;
				extra_row_output_lines = 0;
			}
		}
		IsPagerNeeded(cont, extra_output_lines, &fout, &is_pager);
	}

	/* time to output */
	if (cont->opt->start_table)
	{
		/* print title */
		if (cont->title && !opt_tuples_only)
		{
			int			width,
						height;

			pg_wcssize((unsigned char *) cont->title, strlen(cont->title),
					   encoding, &width, &height, NULL);
			if (width >= width_total)
				/* Aligned */
				fprintf(fout, "%s\n", cont->title);
			else
				/* Centered */
				fprintf(fout, "%-*s%s\n", (width_total - width) / 2, "",
						cont->title);
		}

		/* print headers */
		if (!opt_tuples_only)
		{
			int			more_col_wrapping;
			int			curr_nl_line;

			if (opt_border == 2)
				_print_horizontal_line(col_count, width_wrap, opt_border,
									   PRINT_RULE_TOP, format, fout);

			for (i = 0; i < col_count; i++)
				pg_wcsformat((unsigned char *) cont->headers[i],
							 strlen(cont->headers[i]), encoding,
							 col_lineptrs[i], max_nl_lines[i]);

			more_col_wrapping = col_count;
			curr_nl_line = 0;
			memset(header_done, false, col_count * sizeof(bool));
			while (more_col_wrapping)
			{
				if (opt_border == 2)
					fputs(dformat->leftvrule, fout);

				for (i = 0; i < cont->ncolumns; i++)
				{
					struct lineptr *this_line = col_lineptrs[i] + curr_nl_line;
					unsigned int nbspace;

					if (opt_border != 0 ||
						(format->wrap_right_border == false && i > 0))
						fputs(curr_nl_line ? format->header_nl_left : " ",
							  fout);

					if (!header_done[i])
					{
						nbspace = width_wrap[i] - this_line->width;

						/* centered */
						fprintf(fout, "%-*s%s%-*s",
								nbspace / 2, "", this_line->ptr, (nbspace + 1) / 2, "");

						if (!(this_line + 1)->ptr)
						{
							more_col_wrapping--;
							header_done[i] = 1;
						}
					}
					else
						fprintf(fout, "%*s", width_wrap[i], "");

					if (opt_border != 0 || format->wrap_right_border == true)
						fputs(!header_done[i] ? format->header_nl_right : " ",
							  fout);

					if (opt_border != 0 && i < col_count - 1)
						fputs(dformat->midvrule, fout);
				}
				curr_nl_line++;

				if (opt_border == 2)
					fputs(dformat->rightvrule, fout);
				fputc('\n', fout);
			}

			_print_horizontal_line(col_count, width_wrap, opt_border,
								   PRINT_RULE_MIDDLE, format, fout);
		}
	}

	/* print cells, one loop per row */
	for (i = 0, ptr = cont->cells; *ptr; i += col_count, ptr += col_count)
	{
		bool		more_lines;

		if (cancel_pressed)
			break;

		/*
		 * Format each cell.
		 */
		for (j = 0; j < col_count; j++)
		{
			pg_wcsformat((unsigned char *) ptr[j], strlen(ptr[j]), encoding,
						 col_lineptrs[j], max_nl_lines[j]);
			curr_nl_line[j] = 0;
		}

		memset(bytes_output, 0, col_count * sizeof(int));

		/*
		 * Each time through this loop, one display line is output. It can
		 * either be a full value or a partial value if embedded newlines
		 * exist or if 'format=wrapping' mode is enabled.
		 */
		do
		{
			more_lines = false;

			/* left border */
			if (opt_border == 2)
				fputs(dformat->leftvrule, fout);

			/* for each column */
			for (j = 0; j < col_count; j++)
			{
				/* We have a valid array element, so index it */
				struct lineptr *this_line = &col_lineptrs[j][curr_nl_line[j]];
				int			bytes_to_output;
				int			chars_to_output = width_wrap[j];
				bool		finalspaces = (opt_border == 2 || j < col_count - 1);

				/* Print left-hand wrap or newline mark */
				if (opt_border != 0)
				{
					if (wrap[j] == PRINT_LINE_WRAP_WRAP)
						fputs(format->wrap_left, fout);
					else if (wrap[j] == PRINT_LINE_WRAP_NEWLINE)
						fputs(format->nl_left, fout);
					else
						fputc(' ', fout);
				}

				if (!this_line->ptr)
				{
					/* Past newline lines so just pad for other columns */
					if (finalspaces)
						fprintf(fout, "%*s", chars_to_output, "");
				}
				else
				{
					/* Get strlen() of the characters up to width_wrap */
					bytes_to_output =
						strlen_max_width(this_line->ptr + bytes_output[j],
										 &chars_to_output, encoding);

					/*
					 * If we exceeded width_wrap, it means the display width
					 * of a single character was wider than our target width.
					 * In that case, we have to pretend we are only printing
					 * the target display width and make the best of it.
					 */
					if (chars_to_output > width_wrap[j])
						chars_to_output = width_wrap[j];

					if (cont->aligns[j] == 'r') /* Right aligned cell */
					{
						/* spaces first */
						fprintf(fout, "%*s", width_wrap[j] - chars_to_output, "");
						fputnbytes(fout,
								 (char *) (this_line->ptr + bytes_output[j]),
								   bytes_to_output);
					}
					else	/* Left aligned cell */
					{
						/* spaces second */
						fputnbytes(fout,
								 (char *) (this_line->ptr + bytes_output[j]),
								   bytes_to_output);
					}

					bytes_output[j] += bytes_to_output;

					/* Do we have more text to wrap? */
					if (*(this_line->ptr + bytes_output[j]) != '\0')
						more_lines = true;
					else
					{
						/* Advance to next newline line */
						curr_nl_line[j]++;
						if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
							more_lines = true;
						bytes_output[j] = 0;
					}
				}

				/* Determine next line's wrap status for this column */
				wrap[j] = PRINT_LINE_WRAP_NONE;
				if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
				{
					if (bytes_output[j] != 0)
						wrap[j] = PRINT_LINE_WRAP_WRAP;
					else if (curr_nl_line[j] != 0)
						wrap[j] = PRINT_LINE_WRAP_NEWLINE;
				}

				/*
				 * If left-aligned, pad out remaining space if needed (not
				 * last column, and/or wrap marks required).
				 */
				if (cont->aligns[j] != 'r')		/* Left aligned cell */
				{
					if (finalspaces ||
						wrap[j] == PRINT_LINE_WRAP_WRAP ||
						wrap[j] == PRINT_LINE_WRAP_NEWLINE)
						fprintf(fout, "%*s",
								width_wrap[j] - chars_to_output, "");
				}

				/* Print right-hand wrap or newline mark */
				if (wrap[j] == PRINT_LINE_WRAP_WRAP)
					fputs(format->wrap_right, fout);
				else if (wrap[j] == PRINT_LINE_WRAP_NEWLINE)
					fputs(format->nl_right, fout);
				else if (opt_border == 2 || j < col_count - 1)
					fputc(' ', fout);

				/* Print column divider, if not the last column */
				if (opt_border != 0 && j < col_count - 1)
				{
					if (wrap[j + 1] == PRINT_LINE_WRAP_WRAP)
						fputs(format->midvrule_wrap, fout);
					else if (wrap[j + 1] == PRINT_LINE_WRAP_NEWLINE)
						fputs(format->midvrule_nl, fout);
					else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL)
						fputs(format->midvrule_blank, fout);
					else
						fputs(dformat->midvrule, fout);
				}
			}

			/* end-of-row border */
			if (opt_border == 2)
				fputs(dformat->rightvrule, fout);
			fputc('\n', fout);

		} while (more_lines);
	}

	if (cont->opt->stop_table)
	{
		if (opt_border == 2 && !cancel_pressed)
			_print_horizontal_line(col_count, width_wrap, opt_border,
								   PRINT_RULE_BOTTOM, format, fout);

		/* print footers */
		if (cont->footers && !opt_tuples_only && !cancel_pressed)
		{
			printTableFooter *f;

			for (f = cont->footers; f; f = f->next)
				fprintf(fout, "%s\n", f->data);
		}

		fputc('\n', fout);
	}

	/* clean up */
	for (i = 0; i < col_count; i++)
	{
		free(col_lineptrs[i]);
		free(format_buf[i]);
	}
	free(width_header);
	free(width_average);
	free(max_width);
	free(width_wrap);
	free(max_nl_lines);
	free(curr_nl_line);
	free(col_lineptrs);
	free(max_bytes);
	free(format_buf);
	free(header_done);
	free(bytes_output);
	free(wrap);

	if (is_pager)
		ClosePager(fout);
}


static void
print_aligned_vertical_line(const printTableContent *cont,
							unsigned long record,
							unsigned int hwidth,
							unsigned int dwidth,
							printTextRule pos,
							FILE *fout)
{
	const printTextFormat *format = get_line_style(cont->opt);
	const printTextLineFormat *lformat = &format->lrule[pos];
	unsigned short opt_border = cont->opt->border;
	unsigned int i;
	int			reclen = 0;

	if (opt_border == 2)
		fprintf(fout, "%s%s", lformat->leftvrule, lformat->hrule);
	else if (opt_border == 1)
		fputs(lformat->hrule, fout);

	if (record)
	{
		if (opt_border == 0)
			reclen = fprintf(fout, "* Record %lu", record);
		else
			reclen = fprintf(fout, "[ RECORD %lu ]", record);
	}
	if (opt_border != 2)
		reclen++;
	if (reclen < 0)
		reclen = 0;
	for (i = reclen; i < hwidth; i++)
		fputs(opt_border > 0 ? lformat->hrule : " ", fout);
	reclen -= hwidth;

	if (opt_border > 0)
	{
		if (reclen-- <= 0)
			fputs(lformat->hrule, fout);
		if (reclen-- <= 0)
			fputs(lformat->midvrule, fout);
		if (reclen-- <= 0)
			fputs(lformat->hrule, fout);
	}
	else
	{
		if (reclen-- <= 0)
			fputc(' ', fout);
	}
	if (reclen < 0)
		reclen = 0;
	for (i = reclen; i < dwidth; i++)
		fputs(opt_border > 0 ? lformat->hrule : " ", fout);
	if (opt_border == 2)
		fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
	fputc('\n', fout);
}

static void
print_aligned_vertical(const printTableContent *cont, FILE *fout)
{
	bool		opt_tuples_only = cont->opt->tuples_only;
	unsigned short opt_border = cont->opt->border;
	const printTextFormat *format = get_line_style(cont->opt);
	const printTextLineFormat *dformat = &format->lrule[PRINT_RULE_DATA];
	int			encoding = cont->opt->encoding;
	unsigned long record = cont->opt->prior_records + 1;
	const char *const * ptr;
	unsigned int i,
				hwidth = 0,
				dwidth = 0,
				hheight = 1,
				dheight = 1,
				hformatsize = 0,
				dformatsize = 0;
	struct lineptr *hlineptr,
			   *dlineptr;

	if (cancel_pressed)
		return;

	if (opt_border > 2)
		opt_border = 2;

	if (cont->cells[0] == NULL && cont->opt->start_table &&
		cont->opt->stop_table)
	{
		fprintf(fout, _("(No rows)\n"));
		return;
	}

	/* Find the maximum dimensions for the headers */
	for (i = 0; i < cont->ncolumns; i++)
	{
		int			width,
					height,
					fs;

		pg_wcssize((unsigned char *) cont->headers[i], strlen(cont->headers[i]),
				   encoding, &width, &height, &fs);
		if (width > hwidth)
			hwidth = width;
		if (height > hheight)
			hheight = height;
		if (fs > hformatsize)
			hformatsize = fs;
	}

	/* find longest data cell */
	for (i = 0, ptr = cont->cells; *ptr; ptr++, i++)
	{
		int			width,
					height,
					fs;

		pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
				   &width, &height, &fs);
		if (width > dwidth)
			dwidth = width;
		if (height > dheight)
			dheight = height;
		if (fs > dformatsize)
			dformatsize = fs;
	}

	/*
	 * We now have all the information we need to setup the formatting
	 * structures
	 */
	dlineptr = pg_local_malloc(sizeof(*dlineptr) * (1+dheight));
	hlineptr = pg_local_malloc(sizeof(*hlineptr) * (1+hheight));

	dlineptr->ptr = pg_local_malloc(dformatsize);
	hlineptr->ptr = pg_local_malloc(hformatsize);

	if (cont->opt->start_table)
	{
		/* print title */
		if (!opt_tuples_only && cont->title)
			fprintf(fout, "%s\n", cont->title);
	}

	/* print records */
	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
	{
		printTextRule pos;
		int			line_count,
					dcomplete,
					hcomplete;

		if (cancel_pressed)
			break;

		if (i == 0)
			pos = PRINT_RULE_TOP;
		else if (!(*(ptr + 1)))
			pos = PRINT_RULE_BOTTOM;
		else
			pos = PRINT_RULE_MIDDLE;

		if (i % cont->ncolumns == 0)
		{
			if (!opt_tuples_only)
				print_aligned_vertical_line(cont, record++, hwidth, dwidth,
											pos, fout);
			else if (i != 0 || !cont->opt->start_table || opt_border == 2)
				print_aligned_vertical_line(cont, 0, hwidth, dwidth,
											pos, fout);
		}

		/* Format the header */
		pg_wcsformat((unsigned char *) cont->headers[i % cont->ncolumns],
					 strlen(cont->headers[i % cont->ncolumns]),
					 encoding, hlineptr, hheight);
		/* Format the data */
		pg_wcsformat((unsigned char *) *ptr, strlen(*ptr), encoding,
					 dlineptr, dheight);

		line_count = 0;
		dcomplete = hcomplete = 0;
		while (!dcomplete || !hcomplete)
		{
			if (opt_border == 2)
				fprintf(fout, "%s ", dformat->leftvrule);
			if (!hcomplete)
			{
				fprintf(fout, "%-s%*s", hlineptr[line_count].ptr,
						hwidth - hlineptr[line_count].width, "");

				if (!hlineptr[line_count + 1].ptr)
					hcomplete = 1;
			}
			else
				fprintf(fout, "%*s", hwidth, "");

			if (opt_border > 0)
				fprintf(fout, " %s ", dformat->midvrule);
			else
				fputc(' ', fout);

			if (!dcomplete)
			{
				if (opt_border < 2)
					fprintf(fout, "%s\n", dlineptr[line_count].ptr);
				else
					fprintf(fout, "%-s%*s %s\n", dlineptr[line_count].ptr,
							dwidth - dlineptr[line_count].width, "",
							dformat->rightvrule);

				if (!dlineptr[line_count + 1].ptr)
					dcomplete = 1;
			}
			else
			{
				if (opt_border < 2)
					fputc('\n', fout);
				else
					fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule);
			}
			line_count++;
		}
	}

	if (cont->opt->stop_table)
	{
		if (opt_border == 2 && !cancel_pressed)
			print_aligned_vertical_line(cont, 0, hwidth, dwidth,
										PRINT_RULE_BOTTOM, fout);

		/* print footers */
		if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
		{
			printTableFooter *f;

			if (opt_border < 2)
				fputc('\n', fout);
			for (f = cont->footers; f; f = f->next)
				fprintf(fout, "%s\n", f->data);
		}

		fputc('\n', fout);
	}

	free(hlineptr->ptr);
	free(dlineptr->ptr);
	free(hlineptr);
	free(dlineptr);
}


/**********************/
/* HTML printing ******/
/**********************/


void
html_escaped_print(const char *in, FILE *fout)
{
	const char *p;
	bool		leading_space = true;

	for (p = in; *p; p++)
	{
		switch (*p)
		{
			case '&':
				fputs("&amp;", fout);
				break;
			case '<':
				fputs("&lt;", fout);
				break;
			case '>':
				fputs("&gt;", fout);
				break;
			case '\n':
				fputs("<br />\n", fout);
				break;
			case '"':
				fputs("&quot;", fout);
				break;
			case ' ':
				/* protect leading space, for EXPLAIN output */
				if (leading_space)
					fputs("&nbsp;", fout);
				else
					fputs(" ", fout);
				break;
			default:
				fputc(*p, fout);
		}
		if (*p != ' ')
			leading_space = false;
	}
}


static void
print_html_text(const printTableContent *cont, FILE *fout)
{
	bool		opt_tuples_only = cont->opt->tuples_only;
	unsigned short opt_border = cont->opt->border;
	const char *opt_table_attr = cont->opt->tableAttr;
	unsigned int i;
	const char *const * ptr;

	if (cancel_pressed)
		return;

	if (cont->opt->start_table)
	{
		fprintf(fout, "<table border=\"%d\"", opt_border);
		if (opt_table_attr)
			fprintf(fout, " %s", opt_table_attr);
		fputs(">\n", fout);

		/* print title */
		if (!opt_tuples_only && cont->title)
		{
			fputs("  <caption>", fout);
			html_escaped_print(cont->title, fout);
			fputs("</caption>\n", fout);
		}

		/* print headers */
		if (!opt_tuples_only)
		{
			fputs("  <tr>\n", fout);
			for (ptr = cont->headers; *ptr; ptr++)
			{
				fputs("    <th align=\"center\">", fout);
				html_escaped_print(*ptr, fout);
				fputs("</th>\n", fout);
			}
			fputs("  </tr>\n", fout);
		}
	}

	/* print cells */
	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
	{
		if (i % cont->ncolumns == 0)
		{
			if (cancel_pressed)
				break;
			fputs("  <tr valign=\"top\">\n", fout);
		}

		fprintf(fout, "    <td align=\"%s\">", cont->aligns[(i) % cont->ncolumns] == 'r' ? "right" : "left");
		/* is string only whitespace? */
		if ((*ptr)[strspn(*ptr, " \t")] == '\0')
			fputs("&nbsp; ", fout);
		else
			html_escaped_print(*ptr, fout);

		fputs("</td>\n", fout);

		if ((i + 1) % cont->ncolumns == 0)
			fputs("  </tr>\n", fout);
	}

	if (cont->opt->stop_table)
	{
		fputs("</table>\n", fout);

		/* print footers */
		if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
		{
			printTableFooter *f;

			fputs("<p>", fout);
			for (f = cont->footers; f; f = f->next)
			{
				html_escaped_print(f->data, fout);
				fputs("<br />\n", fout);
			}
			fputs("</p>", fout);
		}

		fputc('\n', fout);
	}
}


static void
print_html_vertical(const printTableContent *cont, FILE *fout)
{
	bool		opt_tuples_only = cont->opt->tuples_only;
	unsigned short opt_border = cont->opt->border;
	const char *opt_table_attr = cont->opt->tableAttr;
	unsigned long record = cont->opt->prior_records + 1;
	unsigned int i;
	const char *const * ptr;

	if (cancel_pressed)
		return;

	if (cont->opt->start_table)
	{
		fprintf(fout, "<table border=\"%d\"", opt_border);
		if (opt_table_attr)
			fprintf(fout, " %s", opt_table_attr);
		fputs(">\n", fout);

		/* print title */
		if (!opt_tuples_only && cont->title)
		{
			fputs("  <caption>", fout);
			html_escaped_print(cont->title, fout);
			fputs("</caption>\n", fout);
		}
	}

	/* print records */
	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
	{
		if (i % cont->ncolumns == 0)
		{
			if (cancel_pressed)
				break;
			if (!opt_tuples_only)
				fprintf(fout,
						"\n  <tr><td colspan=\"2\" align=\"center\">Record %lu</td></tr>\n",
						record++);
			else
				fputs("\n  <tr><td colspan=\"2\">&nbsp;</td></tr>\n", fout);
		}
		fputs("  <tr valign=\"top\">\n"
			  "    <th>", fout);
		html_escaped_print(cont->headers[i % cont->ncolumns], fout);
		fputs("</th>\n", fout);

		fprintf(fout, "    <td align=\"%s\">", cont->aligns[i % cont->ncolumns] == 'r' ? "right" : "left");
		/* is string only whitespace? */
		if ((*ptr)[strspn(*ptr, " \t")] == '\0')
			fputs("&nbsp; ", fout);
		else
			html_escaped_print(*ptr, fout);

		fputs("</td>\n  </tr>\n", fout);
	}

	if (cont->opt->stop_table)
	{
		fputs("</table>\n", fout);

		/* print footers */
		if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
		{
			printTableFooter *f;

			fputs("<p>", fout);
			for (f = cont->footers; f; f = f->next)
			{
				html_escaped_print(f->data, fout);
				fputs("<br />\n", fout);
			}
			fputs("</p>", fout);
		}

		fputc('\n', fout);
	}
}


/*************************/
/* LaTeX				 */
/*************************/


static void
latex_escaped_print(const char *in, FILE *fout)
{
	const char *p;

	for (p = in; *p; p++)
		switch (*p)
		{
			case '&':
				fputs("\\&", fout);
				break;
			case '%':
				fputs("\\%", fout);
				break;
			case '$':
				fputs("\\$", fout);
				break;
			case '_':
				fputs("\\_", fout);
				break;
			case '{':
				fputs("\\{", fout);
				break;
			case '}':
				fputs("\\}", fout);
				break;
			case '\\':
				fputs("\\backslash", fout);
				break;
			case '\n':
				fputs("\\\\", fout);
				break;
			default:
				fputc(*p, fout);
		}
}


static void
print_latex_text(const printTableContent *cont, FILE *fout)
{
	bool		opt_tuples_only = cont->opt->tuples_only;
	unsigned short opt_border = cont->opt->border;
	unsigned int i;
	const char *const * ptr;

	if (cancel_pressed)
		return;

	if (opt_border > 2)
		opt_border = 2;

	if (cont->opt->start_table)
	{
		/* print title */
		if (!opt_tuples_only && cont->title)
		{
			fputs("\\begin{center}\n", fout);
			latex_escaped_print(cont->title, fout);
			fputs("\n\\end{center}\n\n", fout);
		}

		/* begin environment and set alignments and borders */
		fputs("\\begin{tabular}{", fout);

		if (opt_border == 2)
			fputs("| ", fout);
		for (i = 0; i < cont->ncolumns; i++)
		{
			fputc(*(cont->aligns + i), fout);
			if (opt_border != 0 && i < cont->ncolumns - 1)
				fputs(" | ", fout);
		}
		if (opt_border == 2)
			fputs(" |", fout);

		fputs("}\n", fout);

		if (!opt_tuples_only && opt_border == 2)
			fputs("\\hline\n", fout);

		/* print headers */
		if (!opt_tuples_only)
		{
			for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
			{
				if (i != 0)
					fputs(" & ", fout);
				fputs("\\textit{", fout);
				latex_escaped_print(*ptr, fout);
				fputc('}', fout);
			}
			fputs(" \\\\\n", fout);
			fputs("\\hline\n", fout);
		}
	}

	/* print cells */
	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
	{
		latex_escaped_print(*ptr, fout);

		if ((i + 1) % cont->ncolumns == 0)
		{
			fputs(" \\\\\n", fout);
			if (cancel_pressed)
				break;
		}
		else
			fputs(" & ", fout);
	}

	if (cont->opt->stop_table)
	{
		if (opt_border == 2)
			fputs("\\hline\n", fout);

		fputs("\\end{tabular}\n\n\\noindent ", fout);

		/* print footers */
		if (cont->footers && !opt_tuples_only && !cancel_pressed)
		{
			printTableFooter *f;

			for (f = cont->footers; f; f = f->next)
			{
				latex_escaped_print(f->data, fout);
				fputs(" \\\\\n", fout);
			}
		}

		fputc('\n', fout);
	}
}


static void
print_latex_vertical(const printTableContent *cont, FILE *fout)
{
	bool		opt_tuples_only = cont->opt->tuples_only;
	unsigned short opt_border = cont->opt->border;
	unsigned long record = cont->opt->prior_records + 1;
	unsigned int i;
	const char *const * ptr;

	if (cancel_pressed)
		return;

	if (opt_border > 2)
		opt_border = 2;

	if (cont->opt->start_table)
	{
		/* print title */
		if (!opt_tuples_only && cont->title)
		{
			fputs("\\begin{center}\n", fout);
			latex_escaped_print(cont->title, fout);
			fputs("\n\\end{center}\n\n", fout);
		}

		/* begin environment and set alignments and borders */
		fputs("\\begin{tabular}{", fout);
		if (opt_border == 0)
			fputs("cl", fout);
		else if (opt_border == 1)
			fputs("c|l", fout);
		else if (opt_border == 2)
			fputs("|c|l|", fout);
		fputs("}\n", fout);
	}

	/* print records */
	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
	{
		/* new record */
		if (i % cont->ncolumns == 0)
		{
			if (cancel_pressed)
				break;
			if (!opt_tuples_only)
			{
				if (opt_border == 2)
				{
					fputs("\\hline\n", fout);
					fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %lu}} \\\\\n", record++);
				}
				else
					fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %lu}} \\\\\n", record++);
			}
			if (opt_border >= 1)
				fputs("\\hline\n", fout);
		}

		latex_escaped_print(cont->headers[i % cont->ncolumns], fout);
		fputs(" & ", fout);
		latex_escaped_print(*ptr, fout);
		fputs(" \\\\\n", fout);
	}

	if (cont->opt->stop_table)
	{
		if (opt_border == 2)
			fputs("\\hline\n", fout);

		fputs("\\end{tabular}\n\n\\noindent ", fout);

		/* print footers */
		if (cont->footers && !opt_tuples_only && !cancel_pressed)
		{
			printTableFooter *f;

			for (f = cont->footers; f; f = f->next)
			{
				latex_escaped_print(f->data, fout);
				fputs(" \\\\\n", fout);
			}
		}

		fputc('\n', fout);
	}
}


/*************************/
/* Troff -ms		 */
/*************************/


static void
troff_ms_escaped_print(const char *in, FILE *fout)
{
	const char *p;

	for (p = in; *p; p++)
		switch (*p)
		{
			case '\\':
				fputs("\\(rs", fout);
				break;
			default:
				fputc(*p, fout);
		}
}


static void
print_troff_ms_text(const printTableContent *cont, FILE *fout)
{
	bool		opt_tuples_only = cont->opt->tuples_only;
	unsigned short opt_border = cont->opt->border;
	unsigned int i;
	const char *const * ptr;

	if (cancel_pressed)
		return;

	if (opt_border > 2)
		opt_border = 2;

	if (cont->opt->start_table)
	{
		/* print title */
		if (!opt_tuples_only && cont->title)
		{
			fputs(".LP\n.DS C\n", fout);
			troff_ms_escaped_print(cont->title, fout);
			fputs("\n.DE\n", fout);
		}

		/* begin environment and set alignments and borders */
		fputs(".LP\n.TS\n", fout);
		if (opt_border == 2)
			fputs("center box;\n", fout);
		else
			fputs("center;\n", fout);

		for (i = 0; i < cont->ncolumns; i++)
		{
			fputc(*(cont->aligns + i), fout);
			if (opt_border > 0 && i < cont->ncolumns - 1)
				fputs(" | ", fout);
		}
		fputs(".\n", fout);

		/* print headers */
		if (!opt_tuples_only)
		{
			for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
			{
				if (i != 0)
					fputc('\t', fout);
				fputs("\\fI", fout);
				troff_ms_escaped_print(*ptr, fout);
				fputs("\\fP", fout);
			}
			fputs("\n_\n", fout);
		}
	}

	/* print cells */
	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
	{
		troff_ms_escaped_print(*ptr, fout);

		if ((i + 1) % cont->ncolumns == 0)
		{
			fputc('\n', fout);
			if (cancel_pressed)
				break;
		}
		else
			fputc('\t', fout);
	}

	if (cont->opt->stop_table)
	{
		fputs(".TE\n.DS L\n", fout);

		/* print footers */
		if (cont->footers && !opt_tuples_only && !cancel_pressed)
		{
			printTableFooter *f;

			for (f = cont->footers; f; f = f->next)
			{
				troff_ms_escaped_print(f->data, fout);
				fputc('\n', fout);
			}
		}

		fputs(".DE\n", fout);
	}
}


static void
print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
{
	bool		opt_tuples_only = cont->opt->tuples_only;
	unsigned short opt_border = cont->opt->border;
	unsigned long record = cont->opt->prior_records + 1;
	unsigned int i;
	const char *const * ptr;
	unsigned short current_format = 0;	/* 0=none, 1=header, 2=body */

	if (cancel_pressed)
		return;

	if (opt_border > 2)
		opt_border = 2;

	if (cont->opt->start_table)
	{
		/* print title */
		if (!opt_tuples_only && cont->title)
		{
			fputs(".LP\n.DS C\n", fout);
			troff_ms_escaped_print(cont->title, fout);
			fputs("\n.DE\n", fout);
		}

		/* begin environment and set alignments and borders */
		fputs(".LP\n.TS\n", fout);
		if (opt_border == 2)
			fputs("center box;\n", fout);
		else
			fputs("center;\n", fout);

		/* basic format */
		if (opt_tuples_only)
			fputs("c l;\n", fout);
	}
	else
		current_format = 2;		/* assume tuples printed already */

	/* print records */
	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
	{
		/* new record */
		if (i % cont->ncolumns == 0)
		{
			if (cancel_pressed)
				break;
			if (!opt_tuples_only)
			{
				if (current_format != 1)
				{
					if (opt_border == 2 && record > 1)
						fputs("_\n", fout);
					if (current_format != 0)
						fputs(".T&\n", fout);
					fputs("c s.\n", fout);
					current_format = 1;
				}
				fprintf(fout, "\\fIRecord %lu\\fP\n", record++);
			}
			if (opt_border >= 1)
				fputs("_\n", fout);
		}

		if (!opt_tuples_only)
		{
			if (current_format != 2)
			{
				if (current_format != 0)
					fputs(".T&\n", fout);
				if (opt_border != 1)
					fputs("c l.\n", fout);
				else
					fputs("c | l.\n", fout);
				current_format = 2;
			}
		}

		troff_ms_escaped_print(cont->headers[i % cont->ncolumns], fout);
		fputc('\t', fout);
		troff_ms_escaped_print(*ptr, fout);

		fputc('\n', fout);
	}

	if (cont->opt->stop_table)
	{
		fputs(".TE\n.DS L\n", fout);

		/* print footers */
		if (cont->footers && !opt_tuples_only && !cancel_pressed)
		{
			printTableFooter *f;

			for (f = cont->footers; f; f = f->next)
			{
				troff_ms_escaped_print(f->data, fout);
				fputc('\n', fout);
			}
		}

		fputs(".DE\n", fout);
	}
}


/********************************/
/* Public functions		*/
/********************************/


/*
 * PageOutput
 *
 * Tests if pager is needed and returns appropriate FILE pointer.
 */
FILE *
PageOutput(int lines, unsigned short int pager)
{
	/* check whether we need / can / are supposed to use pager */
	if (pager && isatty(fileno(stdin)) && isatty(fileno(stdout)))
	{
		const char *pagerprog;
		FILE	   *pagerpipe;

#ifdef TIOCGWINSZ
		int			result;
		struct winsize screen_size;

		result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size);

		/* >= accounts for a one-line prompt */
		if (result == -1 || lines >= screen_size.ws_row || pager > 1)
		{
#endif
			pagerprog = getenv("PAGER");
			if (!pagerprog)
				pagerprog = DEFAULT_PAGER;
#ifndef WIN32
			pqsignal(SIGPIPE, SIG_IGN);
#endif
			pagerpipe = popen(pagerprog, "w");
			if (pagerpipe)
				return pagerpipe;
#ifdef TIOCGWINSZ
		}
#endif
	}

	return stdout;
}

/*
 * ClosePager
 *
 * Close previously opened pager pipe, if any
 */
void
ClosePager(FILE *pagerpipe)
{
	if (pagerpipe && pagerpipe != stdout)
	{
		/*
		 * If printing was canceled midstream, warn about it.
		 *
		 * Some pagers like less use Ctrl-C as part of their command set. Even
		 * so, we abort our processing and warn the user what we did.  If the
		 * pager quit as a result of the SIGINT, this message won't go
		 * anywhere ...
		 */
		if (cancel_pressed)
			fprintf(pagerpipe, _("Interrupted\n"));

		pclose(pagerpipe);
#ifndef WIN32
		pqsignal(SIGPIPE, SIG_DFL);
#endif
	}
}

/*
 * Initialise a table contents struct.
 *		Must be called before any other printTable method is used.
 *
 * The title is not duplicated; the caller must ensure that the buffer
 * is available for the lifetime of the printTableContent struct.
 *
 * If you call this, you must call printTableCleanup once you're done with the
 * table.
 */
void
printTableInit(printTableContent *const content, printTableOpt *opt,
			   const char *title, const int ncolumns, const int nrows)
{
	content->opt = opt;
	content->title = title;
	content->ncolumns = ncolumns;
	content->nrows = nrows;

	content->headers = pg_local_calloc(ncolumns + 1,
									   sizeof(*content->headers));

	content->cells = pg_local_calloc(ncolumns * nrows + 1,
									 sizeof(*content->cells));

	content->cellmustfree = NULL;
	content->footers = NULL;

	content->aligns = pg_local_calloc(ncolumns + 1,
									  sizeof(*content->align));

	content->header = content->headers;
	content->cell = content->cells;
	content->footer = content->footers;
	content->align = content->aligns;
	content->cellsadded = 0;
}

/*
 * Add a header to the table.
 *
 * Headers are not duplicated; you must ensure that the header string is
 * available for the lifetime of the printTableContent struct.
 *
 * If translate is true, the function will pass the header through gettext.
 * Otherwise, the header will not be translated.
 *
 * align is either 'l' or 'r', and specifies the alignment for cells in this
 * column.
 */
void
printTableAddHeader(printTableContent *const content, const char *header,
					const bool translate, const char align)
{
#ifndef ENABLE_NLS
	(void) translate;			/* unused parameter */
#endif

	if (content->header >= content->headers + content->ncolumns)
	{
		fprintf(stderr, _("Cannot add header to table content: "
						  "column count of %d exceeded.\n"),
				content->ncolumns);
		exit(EXIT_FAILURE);
	}

	*content->header = (char *) mbvalidate((unsigned char *) header,
										   content->opt->encoding);
#ifdef ENABLE_NLS
	if (translate)
		*content->header = _(*content->header);
#endif
	content->header++;

	*content->align = align;
	content->align++;
}

/*
 * Add a cell to the table.
 *
 * Cells are not duplicated; you must ensure that the cell string is available
 * for the lifetime of the printTableContent struct.
 *
 * If translate is true, the function will pass the cell through gettext.
 * Otherwise, the cell will not be translated.
 *
 * If mustfree is true, the cell string is freed by printTableCleanup().
 * Note: Automatic freeing of translatable strings is not supported.
 */
void
printTableAddCell(printTableContent *const content, const char *cell,
				  const bool translate, const bool mustfree)
{
#ifndef ENABLE_NLS
	(void) translate;			/* unused parameter */
#endif

	if (content->cellsadded >= content->ncolumns * content->nrows)
	{
		fprintf(stderr, _("Cannot add cell to table content: "
						  "total cell count of %d exceeded.\n"),
				content->ncolumns * content->nrows);
		exit(EXIT_FAILURE);
	}

	*content->cell = (char *) mbvalidate((unsigned char *) cell,
										 content->opt->encoding);

#ifdef ENABLE_NLS
	if (translate)
		*content->cell = _(*content->cell);
#endif

	if (mustfree)
	{
		if (content->cellmustfree == NULL)
			content->cellmustfree = pg_local_calloc(
					   content->ncolumns * content->nrows + 1, sizeof(bool));

		content->cellmustfree[content->cellsadded] = true;
	}
	content->cell++;
	content->cellsadded++;
}

/*
 * Add a footer to the table.
 *
 * Footers are added as elements of a singly-linked list, and the content is
 * strdup'd, so there is no need to keep the original footer string around.
 *
 * Footers are never translated by the function.  If you want the footer
 * translated you must do so yourself, before calling printTableAddFooter.	The
 * reason this works differently to headers and cells is that footers tend to
 * be made of up individually translated components, rather than being
 * translated as a whole.
 */
void
printTableAddFooter(printTableContent *const content, const char *footer)
{
	printTableFooter *f;

	f = pg_local_calloc(1, sizeof(*f));
	f->data = pg_strdup(footer);

	if (content->footers == NULL)
		content->footers = f;
	else
		content->footer->next = f;

	content->footer = f;
}

/*
 * Change the content of the last-added footer.
 *
 * The current contents of the last-added footer are freed, and replaced by the
 * content given in *footer.  If there was no previous footer, add a new one.
 *
 * The content is strdup'd, so there is no need to keep the original string
 * around.
 */
void
printTableSetFooter(printTableContent *const content, const char *footer)
{
	if (content->footers != NULL)
	{
		free(content->footer->data);
		content->footer->data = pg_strdup(footer);
	}
	else
		printTableAddFooter(content, footer);
}

/*
 * Free all memory allocated to this struct.
 *
 * Once this has been called, the struct is unusable unless you pass it to
 * printTableInit() again.
 */
void
printTableCleanup(printTableContent *const content)
{
	if (content->cellmustfree)
	{
		int			i;

		for (i = 0; i < content->nrows * content->ncolumns; i++)
		{
			if (content->cellmustfree[i])
				free((char *) content->cells[i]);
		}
		free(content->cellmustfree);
		content->cellmustfree = NULL;
	}
	free(content->headers);
	free(content->cells);
	free(content->aligns);

	content->opt = NULL;
	content->title = NULL;
	content->headers = NULL;
	content->cells = NULL;
	content->aligns = NULL;
	content->header = NULL;
	content->cell = NULL;
	content->align = NULL;

	if (content->footers)
	{
		for (content->footer = content->footers; content->footer;)
		{
			printTableFooter *f;

			f = content->footer;
			content->footer = f->next;
			free(f->data);
			free(f);
		}
	}
	content->footers = NULL;
	content->footer = NULL;
}

/*
 * IsPagerNeeded
 *
 * Setup pager if required
 */
static void
IsPagerNeeded(const printTableContent *cont, const int extra_lines, FILE **fout,
			  bool *is_pager)
{
	if (*fout == stdout)
	{
		int			lines;

		if (cont->opt->expanded)
			lines = (cont->ncolumns + 1) * cont->nrows;
		else
			lines = cont->nrows + 1;

		if (!cont->opt->tuples_only)
		{
			printTableFooter *f;

			/*
			 * FIXME -- this is slightly bogus: it counts the number of
			 * footers, not the number of lines in them.
			 */
			for (f = cont->footers; f; f = f->next)
				lines++;
		}

		*fout = PageOutput(lines + extra_lines, cont->opt->pager);
		*is_pager = (*fout != stdout);
	}
	else
		*is_pager = false;
}

/*
 * Use this to print just any table in the supported formats.
 */
void
printTable(const printTableContent *cont, FILE *fout, FILE *flog)
{
	bool		is_pager = false;

	if (cancel_pressed)
		return;

	if (cont->opt->format == PRINT_NOTHING)
		return;

	/* print_aligned_text() handles the pager itself */
	if ((cont->opt->format != PRINT_ALIGNED &&
		 cont->opt->format != PRINT_WRAPPED) ||
		cont->opt->expanded)
		IsPagerNeeded(cont, 0, &fout, &is_pager);

	/* print the stuff */

	if (flog)
		print_aligned_text(cont, flog);

	switch (cont->opt->format)
	{
		case PRINT_UNALIGNED:
			if (cont->opt->expanded)
				print_unaligned_vertical(cont, fout);
			else
				print_unaligned_text(cont, fout);
			break;
		case PRINT_ALIGNED:
		case PRINT_WRAPPED:
			if (cont->opt->expanded)
				print_aligned_vertical(cont, fout);
			else
				print_aligned_text(cont, fout);
			break;
		case PRINT_HTML:
			if (cont->opt->expanded)
				print_html_vertical(cont, fout);
			else
				print_html_text(cont, fout);
			break;
		case PRINT_LATEX:
			if (cont->opt->expanded)
				print_latex_vertical(cont, fout);
			else
				print_latex_text(cont, fout);
			break;
		case PRINT_TROFF_MS:
			if (cont->opt->expanded)
				print_troff_ms_vertical(cont, fout);
			else
				print_troff_ms_text(cont, fout);
			break;
		default:
			fprintf(stderr, _("invalid output format (internal error): %d"),
					cont->opt->format);
			exit(EXIT_FAILURE);
	}

	if (is_pager)
		ClosePager(fout);
}

/*
 * Use this to print query results
 *
 * It calls printTable with all the things set straight.
 */
void
printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *flog)
{
	printTableContent cont;
	int			i,
				r,
				c;

	if (cancel_pressed)
		return;

	printTableInit(&cont, (printTableOpt *) &opt->topt, opt->title,
				   PQnfields(result), PQntuples(result));

	for (i = 0; i < cont.ncolumns; i++)
	{
		char		align;
		Oid			ftype = PQftype(result, i);

		switch (ftype)
		{
			case INT2OID:
			case INT4OID:
			case INT8OID:
			case FLOAT4OID:
			case FLOAT8OID:
			case NUMERICOID:
			case OIDOID:
			case XIDOID:
			case CIDOID:
			case CASHOID:
				align = 'r';
				break;
			default:
				align = 'l';
				break;
		}

		printTableAddHeader(&cont, PQfname(result, i),
							opt->translate_header, align);
	}

	/* set cells */
	for (r = 0; r < cont.nrows; r++)
	{
		for (c = 0; c < cont.ncolumns; c++)
		{
			char	   *cell;
			bool		mustfree = false;
			bool		translate;

			if (PQgetisnull(result, r, c))
				cell = opt->nullPrint ? opt->nullPrint : "";
			else
			{
				cell = PQgetvalue(result, r, c);
				if (cont.aligns[c] == 'r' && opt->topt.numericLocale)
				{
					cell = format_numeric_locale(cell);
					mustfree = true;
				}
			}

			translate = (opt->translate_columns && opt->translate_columns[c]);
			printTableAddCell(&cont, cell, translate, mustfree);
		}
	}

	/* set footers */
	if (opt->footers)
	{
		char	  **footer;

		for (footer = opt->footers; *footer; footer++)
			printTableAddFooter(&cont, *footer);
	}
	else if (!opt->topt.expanded && opt->default_footer)
	{
		unsigned long total_records;
		char		default_footer[100];

		total_records = opt->topt.prior_records + cont.nrows;
		snprintf(default_footer, sizeof(default_footer),
				 ngettext("(%lu row)", "(%lu rows)", total_records),
				 total_records);

		printTableAddFooter(&cont, default_footer);
	}

	printTable(&cont, fout, flog);
	printTableCleanup(&cont);
}


void
setDecimalLocale(void)
{
	struct lconv *extlconv;

	extlconv = localeconv();

	if (*extlconv->decimal_point)
		decimal_point = pg_strdup(extlconv->decimal_point);
	else
		decimal_point = ".";	/* SQL output standard */
	if (*extlconv->grouping && atoi(extlconv->grouping) > 0)
		grouping = pg_strdup(extlconv->grouping);
	else
		grouping = "3";			/* most common */

	/* similar code exists in formatting.c */
	if (*extlconv->thousands_sep)
		thousands_sep = pg_strdup(extlconv->thousands_sep);
	/* Make sure thousands separator doesn't match decimal point symbol. */
	else if (strcmp(decimal_point, ",") != 0)
		thousands_sep = ",";
	else
		thousands_sep = ".";
}

/* get selected or default line style */
const printTextFormat *
get_line_style(const printTableOpt *opt)
{
	/*
	 * Note: this function mainly exists to preserve the convention that a
	 * printTableOpt struct can be initialized to zeroes to get default
	 * behavior.
	 */
	if (opt->line_style != NULL)
		return opt->line_style;
	else
		return &pg_asciiformat_old;   /* GPDB: Use old-ascii format for regression test compatibility */
}

/*
 * Compute the byte distance to the end of the string or *target_width
 * display character positions, whichever comes first.	Update *target_width
 * to be the number of display character positions actually filled.
 */
static int
strlen_max_width(unsigned char *str, int *target_width, int encoding)
{
	unsigned char *start = str;
	unsigned char *end = str + strlen((char *) str);
	int			curr_width = 0;

	while (str < end)
	{
		int			char_width = PQdsplen((char *) str, encoding);

		/*
		 * If the display width of the new character causes the string to
		 * exceed its target width, skip it and return.  However, if this is
		 * the first character of the string (curr_width == 0), we have to
		 * accept it.
		 */
		if (*target_width < curr_width + char_width && curr_width != 0)
			break;

		curr_width += char_width;

		str += PQmblen((char *) str, encoding);
	}

	*target_width = curr_width;

	return str - start;
}
