]> granicus.if.org Git - postgresql/commitdiff
Restore psql's former behavior that padding spaces to the right of the last
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 10 May 2008 03:31:58 +0000 (03:31 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 10 May 2008 03:31:58 +0000 (03:31 +0000)
output column are not emitted.  (That change already caused more noise in
the regression test output files than I would like.)  Provide some needed
editorial help for comments, clean up code formatting.

src/bin/psql/print.c

index 0e615d8cb8fdfbc3d8415c887919abab95873a13..68c675c06f80435509d682fabca3b54d12bb2f30 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2008, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.98 2008/05/08 17:04:26 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.99 2008/05/10 03:31:58 tgl Exp $
  */
 #include "postgres_fe.h"
 
@@ -28,8 +28,6 @@
 
 #include "mbprint.h"
 
-static int strlen_max_width(unsigned char *str, int *target_width, int encoding);
-
 /*
  * 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
@@ -45,6 +43,9 @@ static char *decimal_point;
 static char *grouping;
 static char *thousands_sep;
 
+/* Local functions */
+static int strlen_max_width(unsigned char *str, int *target_width, int encoding);
+
 
 static void *
 pg_local_malloc(size_t size)
@@ -400,7 +401,7 @@ _print_horizontal_line(const unsigned int col_count, const unsigned int *widths,
 
 
 /*
- *     Prety pretty boxes around cells.
+ *     Print pretty boxes around cells.
  */
 static void
 print_aligned_text(const char *title, const char *const * headers,
@@ -411,7 +412,7 @@ print_aligned_text(const char *title, const char *const * headers,
        bool            opt_tuples_only = opt->tuples_only;
        bool            opt_numeric_locale = opt->numericLocale;
        int                     encoding = opt->encoding;
-       unsigned short int opt_border = opt->border;
+       unsigned short opt_border = opt->border;
 
        unsigned int col_count = 0, cell_count = 0;
 
@@ -483,7 +484,8 @@ print_aligned_text(const char *title, const char *const * headers,
                                        nl_lines,
                                        bytes_required;
 
-               pg_wcssize((unsigned char *) headers[i], strlen(headers[i]), encoding, &width, &nl_lines, &bytes_required);
+               pg_wcssize((unsigned char *) headers[i], strlen(headers[i]), encoding,
+                                  &width, &nl_lines, &bytes_required);
                if (width > max_width[i])
                        max_width[i] = width;
                if (nl_lines > max_nl_lines[i])
@@ -502,7 +504,8 @@ print_aligned_text(const char *title, const char *const * headers,
                                        bytes_required;
 
                /* Get width, ignore nl_lines */
-               pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding, &width, &nl_lines, &bytes_required);
+               pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
+                                  &width, &nl_lines, &bytes_required);
                if (opt_numeric_locale && opt_align[i % col_count] == 'r')
                {
                        width += additional_numeric_locale_len(*ptr);
@@ -567,12 +570,14 @@ print_aligned_text(const char *title, const char *const * headers,
 
        if (opt->format == PRINT_WRAPPED)
        {
-               /* Get terminal width */
+               /*
+                * Choose target output width: \pset columns, or $COLUMNS, or ioctl
+                */
                if (opt->columns > 0)
                        output_columns = opt->columns;
                else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
                {
-                       if (opt->env_columns)
+                       if (opt->env_columns > 0)
                                output_columns = opt->env_columns;
 #ifdef TIOCGWINSZ
                        else
@@ -586,11 +591,11 @@ print_aligned_text(const char *title, const char *const * headers,
                }
 
                /*
-                * 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
+                * 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)
                {
@@ -610,10 +615,11 @@ print_aligned_text(const char *title, const char *const * headers,
                                {
                                        if (width_average[i] && width_wrap[i] > width_header[i])
                                        {
-                                               /* Penalize wide columns by +1% of their width (0.01) */
-                                               double ratio = (double)width_wrap[i] / width_average[i] +
-                                                                       max_width[i] * 0.01;
+                                               /* 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;
@@ -641,7 +647,8 @@ print_aligned_text(const char *title, const char *const * headers,
                {
                        int                     width, height;
 
-                       pg_wcssize((unsigned char *) title, strlen(title), encoding, &width, &height, NULL);
+                       pg_wcssize((unsigned char *) title, strlen(title), encoding,
+                                          &width, &height, NULL);
                        if (width >= width_total)
                                fprintf(fout, "%s\n", title);   /* Aligned */
                        else
@@ -723,12 +730,13 @@ print_aligned_text(const char *title, const char *const * headers,
                        break;
 
                /*
-                * Format each cell.  Format again, it is a numeric formatting locale
+                * Format each cell.  Format again, if it's a numeric formatting locale
                 * (e.g. 123,456 vs. 123456)
                 */
                for (j = 0; j < col_count; j++)
                {
-                       pg_wcsformat((unsigned char *) ptr[j], strlen(ptr[j]), encoding, col_lineptrs[j], max_nl_lines[j]);
+                       pg_wcsformat((unsigned char *) ptr[j], strlen(ptr[j]), encoding,
+                                                col_lineptrs[j], max_nl_lines[j]);
                        curr_nl_line[j] = 0;
 
                        if (opt_numeric_locale && opt_align[j % col_count] == 'r')
@@ -736,8 +744,8 @@ print_aligned_text(const char *title, const char *const * headers,
                                char       *my_cell;
 
                                my_cell = format_numeric_locale((char *) col_lineptrs[j]->ptr);
-                               strcpy((char *) col_lineptrs[j]->ptr, my_cell); /* Buffer IS large
-                                                                                                                                * enough... now */
+                               /* Buffer IS large enough... now */
+                               strcpy((char *) col_lineptrs[j]->ptr, my_cell);
                                free(my_cell);
                        }
                }
@@ -764,16 +772,22 @@ print_aligned_text(const char *title, const char *const * headers,
                        {
                                /* We have a valid array element, so index it */
                                struct lineptr *this_line = &col_lineptrs[j][curr_nl_line[j]];
-                               int             bytes_to_output,  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);
 
-                               /* Past newline lines so pad for other columns */
                                if (!this_line->ptr)
-                                       fprintf(fout, "%*s", width_wrap[j], "");
+                               {
+                                       /* Past newline lines so just pad for other columns */
+                                       if (finalspaces)
+                                               fprintf(fout, "%*s", chars_to_output, "");
+                               }
                                else
                                {
-                                       /* Get strlen() of the width_wrap character */
-                                       bytes_to_output = strlen_max_width(this_line->ptr +
-                                                                       bytes_output[j], &chars_to_output, encoding);
+                                       /* 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
@@ -796,13 +810,14 @@ print_aligned_text(const char *title, const char *const * headers,
                                                /* spaces second */
                                                fprintf(fout, "%.*s", bytes_to_output,
                                                                this_line->ptr + bytes_output[j]);
-                                               fprintf(fout, "%*s", width_wrap[j] - chars_to_output, "");
+                                               if (finalspaces)
+                                                       fprintf(fout, "%*s", width_wrap[j] - chars_to_output, "");
                                        }
 
                                        bytes_output[j] += bytes_to_output;
 
                                        /* Do we have more text to wrap? */
-                                       if (*(this_line->ptr + bytes_output[j]) != 0)
+                                       if (*(this_line->ptr + bytes_output[j]) != '\0')
                                                more_lines = true;
                                        else
                                        {
@@ -814,8 +829,8 @@ print_aligned_text(const char *title, const char *const * headers,
                                        }
                                }
 
-                               /* print a divider, middle columns only */
-                               if ((j + 1) % col_count)
+                               /* print a divider, if not the last column */
+                               if (j < col_count - 1)
                                {
                                        if (opt_border == 0)
                                                fputc(' ', fout);
@@ -832,10 +847,9 @@ print_aligned_text(const char *title, const char *const * headers,
                                        /* Ordinary line */
                                                fputs(" | ", fout);
                                }
-
                        }
 
-                       /* end of row border */
+                       /* end-of-row border */
                        if (opt_border == 2)
                                fputs(" |", fout);
                        fputc('\n', fout);
@@ -887,7 +901,7 @@ print_aligned_vertical(const char *title, const char *const * headers,
 {
        bool            opt_tuples_only = opt->tuples_only;
        bool            opt_numeric_locale = opt->numericLocale;
-       unsigned short int opt_border = opt->border;
+       unsigned short opt_border = opt->border;
        int                     encoding = opt->encoding;
        unsigned int col_count = 0;
        unsigned long record = opt->prior_records + 1;
@@ -927,7 +941,8 @@ print_aligned_vertical(const char *title, const char *const * headers,
                                        height,
                                        fs;
 
-               pg_wcssize((unsigned char *) headers[i], strlen(headers[i]), encoding, &width, &height, &fs);
+               pg_wcssize((unsigned char *) headers[i], strlen(headers[i]), encoding,
+                                  &width, &height, &fs);
                if (width > hwidth)
                        hwidth = width;
                if (height > hheight)
@@ -953,7 +968,8 @@ print_aligned_vertical(const char *title, const char *const * headers,
                else
                        numeric_locale_len = 0;
 
-               pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding, &width, &height, &fs);
+               pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
+                                  &width, &height, &fs);
                width += numeric_locale_len;
                if (width > dwidth)
                        dwidth = width;
@@ -1041,9 +1057,11 @@ print_aligned_vertical(const char *title, const char *const * headers,
 
                /* Format the header */
                pg_wcsformat((unsigned char *) headers[i % col_count],
-                               strlen(headers[i % col_count]), encoding, hlineptr, hheight);
+                                        strlen(headers[i % col_count]),
+                                        encoding, hlineptr, hheight);
                /* Format the data */
-               pg_wcsformat((unsigned char *) *ptr, strlen(*ptr), encoding, dlineptr, dheight);
+               pg_wcsformat((unsigned char *) *ptr, strlen(*ptr), encoding,
+                                        dlineptr, dheight);
 
                line_count = 0;
                dcomplete = hcomplete = 0;
@@ -1182,7 +1200,7 @@ print_html_text(const char *title, const char *const * headers,
 {
        bool            opt_tuples_only = opt->tuples_only;
        bool            opt_numeric_locale = opt->numericLocale;
-       unsigned short int opt_border = opt->border;
+       unsigned short opt_border = opt->border;
        const char *opt_table_attr = opt->tableAttr;
        unsigned int col_count = 0;
        unsigned int i;
@@ -1283,7 +1301,7 @@ print_html_vertical(const char *title, const char *const * headers,
 {
        bool            opt_tuples_only = opt->tuples_only;
        bool            opt_numeric_locale = opt->numericLocale;
-       unsigned short int opt_border = opt->border;
+       unsigned short opt_border = opt->border;
        const char *opt_table_attr = opt->tableAttr;
        unsigned int col_count = 0;
        unsigned long record = opt->prior_records + 1;
@@ -1421,7 +1439,7 @@ print_latex_text(const char *title, const char *const * headers,
 {
        bool            opt_tuples_only = opt->tuples_only;
        bool            opt_numeric_locale = opt->numericLocale;
-       unsigned short int opt_border = opt->border;
+       unsigned short opt_border = opt->border;
        unsigned int col_count = 0;
        unsigned int i;
        const char *const * ptr;
@@ -1534,7 +1552,7 @@ print_latex_vertical(const char *title, const char *const * headers,
 {
        bool            opt_tuples_only = opt->tuples_only;
        bool            opt_numeric_locale = opt->numericLocale;
-       unsigned short int opt_border = opt->border;
+       unsigned short opt_border = opt->border;
        unsigned int col_count = 0;
        unsigned long record = opt->prior_records + 1;
        unsigned int i;
@@ -1661,7 +1679,7 @@ print_troff_ms_text(const char *title, const char *const * headers,
 {
        bool            opt_tuples_only = opt->tuples_only;
        bool            opt_numeric_locale = opt->numericLocale;
-       unsigned short int opt_border = opt->border;
+       unsigned short opt_border = opt->border;
        unsigned int col_count = 0;
        unsigned int i;
        const char *const * ptr;
@@ -1764,7 +1782,7 @@ print_troff_ms_vertical(const char *title, const char *const * headers,
 {
        bool            opt_tuples_only = opt->tuples_only;
        bool            opt_numeric_locale = opt->numericLocale;
-       unsigned short int opt_border = opt->border;
+       unsigned short opt_border = opt->border;
        unsigned int col_count = 0;
        unsigned long record = opt->prior_records + 1;
        unsigned int i;
@@ -1970,7 +1988,7 @@ printTable(const char *title,
        static const char *default_footer[] = {NULL};
        FILE       *output;
        bool            is_pager = false;
-       
+
        if (cancel_pressed)
                return;
 
@@ -2216,17 +2234,18 @@ setDecimalLocale(void)
 }
 
 /*
- *     Returns the byte length to the end of the specified character
- *  and number of display characters processed (useful if the string
- *     is shorter then dpylen).
+ * 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 && curr_width < *target_width)
+       while (str < end)
        {
                int char_width = PQdsplen((char *) str, encoding);
 
@@ -2234,18 +2253,17 @@ strlen_max_width(unsigned char *str, int *target_width, int 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 (*width == 0), we have to accept it.
+                *      of the string (curr_width == 0), we have to accept it.
                 */
-               if (*target_width - curr_width < char_width && curr_width != 0)
+               if (*target_width < curr_width + char_width && curr_width != 0)
                        break;
-                       
-               str += PQmblen((char *)str, encoding);
 
                curr_width += char_width;
+                       
+               str += PQmblen((char *) str, encoding);
        }
 
        *target_width = curr_width;
        
-       /* last byte */
        return str - start;
 }