On Mon, Oct 26, 2009 at 01:33:19PM -0400, Tom Lane wrote:
> Greg Stark <gsst...@mit.edu> writes:
> > While i agree this looks nicer I wonder what it does to things like
> > excel/gnumeric/ooffice auto-recognizing table layouts and importing
> > files. I'm not sure our old format was so great for this so maybe this
> > is actually an improvement I'm asking for.
> 
> Yeah.  We can do what we like with the UTF8 format but I'm considerably
> more worried about the aspect of making random changes to the
> plain-ASCII output.  On the other hand, we changed that just a release
> or so ago (to put in the multiline output in the first place) and
> I didn't hear complaints about it that time.

The attached updated patch makes sure that the ASCII display remains
the same (bar trailing whitespace used for padding).

I'm tempted to add an additional ascii format such as "ascii-clean"
which cleans up the inconsistencies in the formatting as for the
unicode format, while the existing ascii format would remain the
default for backwards compatibility.


Regards,
Roger

-- 
  .''`.  Roger Leigh
 : :' :  Debian GNU/Linux             http://people.debian.org/~rleigh/
 `. `'   Printing on GNU/Linux?       http://gutenprint.sourceforge.net/
   `-    GPG Public Key: 0x25BFB848   Please GPG sign your mail.
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 026e043..3f61293 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -56,7 +56,14 @@ const printTextFormat pg_asciiformat =
 	},
 	":",
 	";",
-	" "
+	" ",
+	"+",
+	" ",
+	" ",
+	" ",
+	" ",
+	" ",
+	false
 };
 
 const printTextFormat pg_utf8format =
@@ -72,12 +79,23 @@ const printTextFormat pg_utf8format =
 		/* N/A, │, │, │ */
 		{ "", "\342\224\202", "\342\224\202", "\342\224\202" }
 	},
-	/* ╎ */
-	"\342\225\216",
-	/* ┊ */
-	"\342\224\212",
-	/* ╷ */
-	"\342\225\267"
+	/* │ */
+	"\342\224\202",
+	/* │ */
+	"\342\224\202",
+	/* │ */
+	"\342\224\202",
+	" ",
+	/* ↵ */
+	"\342\206\265",
+	" ",
+	/* ↵ */
+	"\342\206\265",
+	/* … */
+	"\342\200\246",
+	/* … */
+	"\342\200\246",
+	true
 };
 
 
@@ -479,6 +497,8 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 	int			output_columns = 0;		/* Width of interactive console */
 	bool		is_pager = false;
 
+	printTextLineWrap *wrap;
+
 	if (cancel_pressed)
 		return;
 
@@ -499,6 +519,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 		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
 	{
@@ -513,6 +534,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 		format_buf = NULL;
 		header_done = NULL;
 		bytes_output = NULL;
+		wrap = NULL;
 	}
 
 	/* scan all column headers, find maximum width and max max_nl_lines */
@@ -575,7 +597,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 
 	/* adjust the total display width based on border style */
 	if (opt_border == 0)
-		width_total = col_count - 1;
+		width_total = col_count;
 	else if (opt_border == 1)
 		width_total = col_count * 3 - 1;
 	else
@@ -770,16 +792,16 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 			while (more_col_wrapping)
 			{
 				if (opt_border == 2)
-					fprintf(fout, "%s%c", dformat->leftvrule,
-							curr_nl_line ? '+' : ' ');
-				else if (opt_border == 1)
-					fputc(curr_nl_line ? '+' : ' ', fout);
+					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->cont_right_border == false && i > 0))
+						fputs(curr_nl_line ? format->header_cont_left : " ", fout);
+
 					if (!header_done[i])
 					{
 						nbspace = width_wrap[i] - this_line->width;
@@ -796,21 +818,17 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 					}
 					else
 						fprintf(fout, "%*s", width_wrap[i], "");
-					if (i < col_count - 1)
-					{
-						if (opt_border == 0)
-							fputc(curr_nl_line ? '+' : ' ', fout);
-						else
-							fprintf(fout, " %s%c", dformat->midvrule,
-									curr_nl_line ? '+' : ' ');
-					}
+
+					if (opt_border != 0 || format->cont_right_border == true)
+						fputs(!header_done[i] ? format->header_cont_right : " ", fout);
+
+					if (opt_border != 0 && i < col_count - 1)
+						fputs(dformat->midvrule, fout);
 				}
 				curr_nl_line++;
 
 				if (opt_border == 2)
-					fprintf(fout, " %s", dformat->rightvrule);
-				else if (opt_border == 1)
-					fputc(' ', fout);
+					fputs(dformat->rightvrule, fout);
 				fputc('\n', fout);
 			}
 
@@ -861,19 +879,28 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 
 			/* left border */
 			if (opt_border == 2)
-				fprintf(fout, "%s ", dformat->leftvrule);
-			else if (opt_border == 1)
-				fputc(' ', fout);
+				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];
+				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_CONT)
+						fputs(format->cont_left, fout);
+					else
+						fputc(' ', fout);
+				}
+
 				if (!this_line->ptr)
 				{
 					/* Past newline lines so just pad for other columns */
@@ -908,7 +935,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 						/* spaces second */
 						fprintf(fout, "%.*s", bytes_to_output,
 								this_line->ptr + bytes_output[j]);
-						if (finalspaces)
+						if (finalspaces || col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
 							fprintf(fout, "%*s", width_wrap[j] - chars_to_output, "");
 					}
 
@@ -927,29 +954,40 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 					}
 				}
 
-				/* print a divider, if not the last column */
-				if (j < col_count - 1)
+				/* Determine if next line for this column is wrapped or a newline */
+				wrap[j] = PRINT_LINE_WRAP_NONE;
+				if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
 				{
-					if (opt_border == 0)
-						fputc(' ', fout);
-					/* Next value is beyond past newlines? */
+					if (bytes_output[j] != 0)
+						wrap[j] = PRINT_LINE_WRAP_WRAP;
+					else if (curr_nl_line[j] != 0)
+						wrap[j] = PRINT_LINE_WRAP_CONT;
+				}
+
+				/* 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_CONT)
+					fputs(format->cont_right, fout);
+				else if (!(opt_border == 0 && j == col_count - 1))
+					fputc(' ', fout);
+
+				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_CONT)
+						fputs(format->midvrule_cont, fout);
 					else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL)
-						fprintf(fout, " %s ", format->midvrule_blank);
-					/* In wrapping of value? */
-					else if (bytes_output[j + 1] != 0)
-						fprintf(fout, " %s ", format->midvrule_wrap);
-					/* After first newline value */
-					else if (curr_nl_line[j + 1] != 0)
-						fprintf(fout, " %s ", format->midvrule_cont);
-					/* Ordinary line */
+						fputs(format->midvrule_blank, fout);
 					else
-						fprintf(fout, " %s ", dformat->midvrule);
+						fputs(dformat->midvrule, fout);
 				}
 			}
 
 			/* end-of-row border */
 			if (opt_border == 2)
-				fprintf(fout, " %s", dformat->rightvrule);
+				fputs(dformat->rightvrule, fout);
 			fputc('\n', fout);
 
 		} while (more_lines);
@@ -1196,9 +1234,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
 				fprintf(fout, "%*s", hwidth, "");
 
 			if (opt_border > 0)
-				fprintf(fout, " %s ",
-						(line_count == 0) ?
-						format->midvrule_cont : dformat->midvrule);
+				fprintf(fout, " %s ", dformat->midvrule);
 			else
 				fputc(' ', fout);
 
diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h
index 056aaa6..1007466 100644
--- a/src/bin/psql/print.h
+++ b/src/bin/psql/print.h
@@ -41,14 +41,30 @@ typedef enum printTextRule
 	PRINT_RULE_DATA				/* data line (hrule is unused here) */
 } printTextRule;
 
+typedef enum printTextLineWrap
+{
+	/* Types of line continuation and wrapping */
+	PRINT_LINE_WRAP_NONE  = 0, /* No wrapping */
+	PRINT_LINE_WRAP_WRAP  = 1, /* Line is wrapped */
+	PRINT_LINE_WRAP_CONT  = 2, /* Continuation after newline */
+	PRINT_LINE_WRAP_BLANK = 3  /* Blank line after end of data */
+} printTextLineWrap;
+
 typedef struct printTextFormat
 {
 	/* A complete line style */
-	const char *name;				/* for display purposes */
+	const char *name;		/* for display purposes */
 	printTextLineFormat lrule[4];	/* indexed by enum printTextRule */
 	const char *midvrule_cont;	/* 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_cont_left;		/* continue after newline */
+	const char *header_cont_right;		/* continue after newline */
+	const char *cont_left;		/* continue after newline */
+	const char *cont_right;		/* continue after newline */
+	const char *wrap_left;		/* wrapped data */
+	const char *wrap_right;		/* wrapped data */
+	bool cont_right_border;		/* use right-hand border for continuation marks when border=0 */
 } printTextFormat;
 
 typedef struct printTableOpt

Attachment: signature.asc
Description: Digital signature

Reply via email to