Re: [PATCH] psql formatting patch (round 2) - Mailing list pgsql-patches (2024)

Home>mailing lists

From Bruce Momjian
Subject Re: [PATCH] psql formatting patch (round 2)
Date February 9,2006
Msg-id 200602100036.k1A0aqG18383@candle.pha.pa.us
Whole thread Raw
Inresponseto [PATCH] psql formatting patch (round 2) (Martijn van Oosterhout <kleptog@svana.org>)
List pgsql-patches
Modified patch attached and applied. I made some style changes and hadsome merge conflicts because wchar.c has changed since 8.1.The change to libpq's PQdsplen() seems like a good one and I willmention it in the release notes.---------------------------------------------------------------------------Martijn van Oosterhout wrote:-- Start of PGP signed section.> [Please CC any replies, thanks]>> This patch has the same effect as the last one except it now uses the> PQmblen and PQdsplen functions exported by libpq as suggested by Tom.> This clears a lot of stuff from psql's mbprint.c which is a good thing.> This means it should work for all for encodings (though I can't say I> tested them all).>> The PQdsplen function in libpq has been improved so it can actually> work and provide the necessary information for formatting. That file> (wchar.c) is actually shared with the backend but the backend doesn't> use the dsplen functions, so it does add some dead code (on top of what> was already there).>> Note: this changes the PQdsplen function, it can now return zero or> minus one which was not possible before. It doesn't appear anyone is> actually using the functions other than psql but it is a change. The> functions are not actually documentated anywhere so it's not like we're> breaking a defined interface. The new semantics follow the Unicode> standard.>> The other uses of PQdsplen in psql (in ReportSyntaxErrorPosition) would> seem to be slightly affected by the change, except it's not clear how> psql should react to control characters in the string it's trying to> print...>> Patch available at:> http://svana.org/kleptog/pgsql/psql-format.patch>> Comments welcome,>> Have a nice day,> --> Martijn van Oosterhout <kleptog@svana.org> http://svana.org/kleptog/> > Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a> > tool for doing 5% of the work and then sitting around waiting for someone> > else to do the other 95% so you can sue them.[ Attachment, skipping... ]-- End of PGP section, PGP failed!-- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073Index: src/backend/utils/mb/wchar.c===================================================================RCS file: /cvsroot/pgsql/src/backend/utils/mb/wchar.c,vretrieving revision 1.52diff -c -c -r1.52 wchar.c*** src/backend/utils/mb/wchar.c 26 Dec 2005 19:30:44 -0000 1.52--- src/backend/utils/mb/wchar.c 10 Feb 2006 00:23:32 -0000****************** 23,28 ****--- 23,35 ---- * for the particular encoding. Note that if the encoding is only * supported in the client, you don't need to define * mb2wchar_with_len() function (SJIS is the case).+ *+ * Note: for the display output of psql to work properly, the return values+ * of these functions must conform to the Unicode standard. In particular+ * the NUL character is zero width and control characters are generally+ * width -1. It is recommended that non-ASCII encodings refer their ASCII+ * subset to the ASCII routines to ensure consistancy.+ * */ /******************* 53,58 ****--- 60,70 ---- static int pg_ascii_dsplen(const unsigned char *s) {+ if (*s == '\0')+ return 0;+ if (*s < 0x20 || *s == 0x7f)+ return -1;+ return 1; }****************** 125,131 **** else if (IS_HIGHBIT_SET(*s)) len = 2; else! len = 1; return len; }--- 137,143 ---- else if (IS_HIGHBIT_SET(*s)) len = 2; else! len = pg_ascii_dsplen(s); return len; }****************** 156,162 **** else if (IS_HIGHBIT_SET(*s)) len = 2; else! len = 1; return len; }--- 168,174 ---- else if (IS_HIGHBIT_SET(*s)) len = 2; else! len = pg_ascii_dsplen(s); return len; }****************** 244,250 **** if (IS_HIGHBIT_SET(*s)) len = 2; else! len = 1; return len; }--- 256,262 ---- if (IS_HIGHBIT_SET(*s)) len = 2; else! len = pg_ascii_dsplen(s); return len; }****************** 304,310 **** else if (IS_HIGHBIT_SET(*s)) len = 2; else! len = 1; return len; }--- 316,322 ---- else if (IS_HIGHBIT_SET(*s)) len = 2; else! len = pg_ascii_dsplen(s); return len; }****************** 320,326 **** else if (IS_HIGHBIT_SET(*s)) len = 2; else! len = 1; return len; }--- 332,338 ---- else if (IS_HIGHBIT_SET(*s)) len = 2; else! len = pg_ascii_dsplen(s); return len; }****************** 419,428 **** return len; } static int pg_utf_dsplen(const unsigned char *s) {! return 1; /* XXX fix me! */ } /*--- 431,609 ---- return len; }+ /*+ * This is an implementation of wcwidth() and wcswidth() as defined in+ * "The Single UNIX Specification, Version 2, The Open Group, 1997"+ * <http://www.UNIX-systems.org/online.html>+ *+ * Markus Kuhn -- 2001-09-08 -- public domain+ *+ * customised for PostgreSQL+ *+ * original available at : http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c+ */++ struct mbinterval+ {+ unsigned short first;+ unsigned short last;+ };++ /* auxiliary function for binary search in interval table */+ static int+ mbbisearch(pg_wchar ucs, const struct mbinterval *table, int max)+ {+ int min = 0;+ int mid;++ if (ucs < table[0].first || ucs > table[max].last)+ return 0;+ while (max >= min)+ {+ mid = (min + max) / 2;+ if (ucs > table[mid].last)+ min = mid + 1;+ else if (ucs < table[mid].first)+ max = mid - 1;+ else+ return 1;+ }++ return 0;+ }+++ /* The following functions define the column width of an ISO 10646+ * character as follows:+ *+ * - The null character (U+0000) has a column width of 0.+ *+ * - Other C0/C1 control characters and DEL will lead to a return+ * value of -1.+ *+ * - Non-spacing and enclosing combining characters (general+ * category code Mn or Me in the Unicode database) have a+ * column width of 0.+ *+ * - Other format characters (general category code Cf in the Unicode+ * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.+ *+ * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)+ * have a column width of 0.+ *+ * - Spacing characters in the East Asian Wide (W) or East Asian+ * FullWidth (F) category as defined in Unicode Technical+ * Report #11 have a column width of 2.+ *+ * - All remaining characters (including all printable+ * ISO 8859-1 and WGL4 characters, Unicode control characters,+ * etc.) have a column width of 1.+ *+ * This implementation assumes that wchar_t characters are encoded+ * in ISO 10646.+ */++ static int+ ucs_wcwidth(pg_wchar ucs)+ {+ /* sorted list of non-overlapping intervals of non-spacing characters */+ static const struct mbinterval combining[] = {+ {0x0300, 0x034E}, {0x0360, 0x0362}, {0x0483, 0x0486},+ {0x0488, 0x0489}, {0x0591, 0x05A1}, {0x05A3, 0x05B9},+ {0x05BB, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2},+ {0x05C4, 0x05C4}, {0x064B, 0x0655}, {0x0670, 0x0670},+ {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED},+ {0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A},+ {0x07A6, 0x07B0}, {0x0901, 0x0902}, {0x093C, 0x093C},+ {0x0941, 0x0948}, {0x094D, 0x094D}, {0x0951, 0x0954},+ {0x0962, 0x0963}, {0x0981, 0x0981}, {0x09BC, 0x09BC},+ {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, {0x09E2, 0x09E3},+ {0x0A02, 0x0A02}, {0x0A3C, 0x0A3C}, {0x0A41, 0x0A42},+ {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A70, 0x0A71},+ {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, {0x0AC1, 0x0AC5},+ {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, {0x0B01, 0x0B01},+ {0x0B3C, 0x0B3C}, {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43},+ {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B82, 0x0B82},+ {0x0BC0, 0x0BC0}, {0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40},+ {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},+ {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD},+ {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, {0x0DCA, 0x0DCA},+ {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0E31, 0x0E31},+ {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, {0x0EB1, 0x0EB1},+ {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, {0x0EC8, 0x0ECD},+ {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, {0x0F37, 0x0F37},+ {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, {0x0F80, 0x0F84},+ {0x0F86, 0x0F87}, {0x0F90, 0x0F97}, {0x0F99, 0x0FBC},+ {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, {0x1032, 0x1032},+ {0x1036, 0x1037}, {0x1039, 0x1039}, {0x1058, 0x1059},+ {0x1160, 0x11FF}, {0x17B7, 0x17BD}, {0x17C6, 0x17C6},+ {0x17C9, 0x17D3}, {0x180B, 0x180E}, {0x18A9, 0x18A9},+ {0x200B, 0x200F}, {0x202A, 0x202E}, {0x206A, 0x206F},+ {0x20D0, 0x20E3}, {0x302A, 0x302F}, {0x3099, 0x309A},+ {0xFB1E, 0xFB1E}, {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF},+ {0xFFF9, 0xFFFB}+ };++ /* test for 8-bit control characters */+ if (ucs == 0)+ return 0;++ if (ucs < 0x20 || (ucs >= 0x7f && ucs < 0xa0) || ucs > 0x0010ffff)+ return -1;++ /* binary search in table of non-spacing characters */+ if (mbbisearch(ucs, combining,+ sizeof(combining) / sizeof(struct mbinterval) - 1))+ return 0;++ /*+ * if we arrive here, ucs is not a combining or C0/C1 control character+ */++ return 1 ++ (ucs >= 0x1100 &&+ (ucs <= 0x115f || /* Hangul Jamo init. consonants */+ (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a &&+ ucs != 0x303f) || /* CJK ... Yi */+ (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */+ (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility+ * Ideographs */+ (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */+ (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */+ (ucs >= 0xffe0 && ucs <= 0xffe6) ||+ (ucs >= 0x20000 && ucs <= 0x2ffff)));+ }++ static pg_wchar+ utf2ucs(const unsigned char *c)+ {+ /*+ * one char version of pg_utf2wchar_with_len. no control here, c must+ * point to a large enough string+ */+ if ((*c & 0x80) == 0)+ return (pg_wchar) c[0];+ else if ((*c & 0xe0) == 0xc0)+ return (pg_wchar) (((c[0] & 0x1f) << 6) |+ (c[1] & 0x3f));+ else if ((*c & 0xf0) == 0xe0)+ return (pg_wchar) (((c[0] & 0x0f) << 12) |+ ((c[1] & 0x3f) << 6) |+ (c[2] & 0x3f));+ else if ((*c & 0xf0) == 0xf0)+ return (pg_wchar) (((c[0] & 0x07) << 18) |+ ((c[1] & 0x3f) << 12) |+ ((c[2] & 0x3f) << 6) |+ (c[3] & 0x3f));+ else+ /* that is an invalid code on purpose */+ return 0xffffffff;+ }+ static int pg_utf_dsplen(const unsigned char *s) {! return ucs_wcwidth(utf2ucs(s)); } /******************* 499,505 **** static int pg_mule_dsplen(const unsigned char *s) {! return 1; /* XXX fix me! */ } /*--- 680,686 ---- static int pg_mule_dsplen(const unsigned char *s) {! return pg_ascii_dsplen(s); /* XXX fix me! */ } /******************* 529,535 **** static int pg_latin1_dsplen(const unsigned char *s) {! return 1; } /*--- 710,716 ---- static int pg_latin1_dsplen(const unsigned char *s) {! return pg_ascii_dsplen(s); } /******************* 559,565 **** else if (IS_HIGHBIT_SET(*s)) len = 2; /* kanji? */ else! len = 1; /* should be ASCII */ return len; }--- 740,746 ---- else if (IS_HIGHBIT_SET(*s)) len = 2; /* kanji? */ else! len = pg_ascii_dsplen(s); /* should be ASCII */ return len; }****************** 586,592 **** if (IS_HIGHBIT_SET(*s)) len = 2; /* kanji? */ else! len = 1; /* should be ASCII */ return len; }--- 767,773 ---- if (IS_HIGHBIT_SET(*s)) len = 2; /* kanji? */ else! len = pg_ascii_dsplen(s); /* should be ASCII */ return len; }****************** 613,619 **** if (IS_HIGHBIT_SET(*s)) len = 2; /* kanji? */ else! len = 1; /* should be ASCII */ return len; }--- 794,800 ---- if (IS_HIGHBIT_SET(*s)) len = 2; /* kanji? */ else! len = pg_ascii_dsplen(s); /* should be ASCII */ return len; }****************** 640,646 **** if (IS_HIGHBIT_SET(*s)) len = 2; /* 2byte? */ else! len = 1; /* should be ASCII */ return len; }--- 821,827 ---- if (IS_HIGHBIT_SET(*s)) len = 2; /* 2byte? */ else! len = pg_ascii_dsplen(s); /* should be ASCII */ return len; }****************** 672,681 **** { int len;! if (!IS_HIGHBIT_SET(*s))! len = 1; /* ASCII */! else len = 2; return len; }--- 853,862 ---- { int len;! if (IS_HIGHBIT_SET(*s)) len = 2;+ else+ len = pg_ascii_dsplen(s); /* ASCII */ return len; }Index: src/bin/psql/mbprint.c===================================================================RCS file: /cvsroot/pgsql/src/bin/psql/mbprint.c,vretrieving revision 1.18diff -c -c -r1.18 mbprint.c*** src/bin/psql/mbprint.c 15 Oct 2005 02:49:40 -0000 1.18--- src/bin/psql/mbprint.c 10 Feb 2006 00:23:33 -0000****************** 14,162 **** #include "mb/pg_wchar.h"- /*- * This is an implementation of wcwidth() and wcswidth() as defined in- * "The Single UNIX Specification, Version 2, The Open Group, 1997"- * <http://www.UNIX-systems.org/online.html>- *- * Markus Kuhn -- 2001-09-08 -- public domain- *- * customised for PostgreSQL- *- * original available at : http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c- */-- struct mbinterval- {- unsigned short first;- unsigned short last;- };-- /* auxiliary function for binary search in interval table */- static int- mbbisearch(pg_wchar ucs, const struct mbinterval * table, int max)- {- int min = 0;- int mid;-- if (ucs < table[0].first || ucs > table[max].last)- return 0;- while (max >= min)- {- mid = (min + max) / 2;- if (ucs > table[mid].last)- min = mid + 1;- else if (ucs < table[mid].first)- max = mid - 1;- else- return 1;- }-- return 0;- }--- /* The following functions define the column width of an ISO 10646- * character as follows:- *- * - The null character (U+0000) has a column width of 0.- *- * - Other C0/C1 control characters and DEL will lead to a return- * value of -1.- *- * - Non-spacing and enclosing combining characters (general- * category code Mn or Me in the Unicode database) have a- * column width of 0.- *- * - Other format characters (general category code Cf in the Unicode- * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.- *- * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)- * have a column width of 0.- *- * - Spacing characters in the East Asian Wide (W) or East Asian- * FullWidth (F) category as defined in Unicode Technical- * Report #11 have a column width of 2.- *- * - All remaining characters (including all printable- * ISO 8859-1 and WGL4 characters, Unicode control characters,- * etc.) have a column width of 1.- *- * This implementation assumes that wchar_t characters are encoded- * in ISO 10646.- */-- static int- ucs_wcwidth(pg_wchar ucs)- {- /* sorted list of non-overlapping intervals of non-spacing characters */- static const struct mbinterval combining[] = {- {0x0300, 0x034E}, {0x0360, 0x0362}, {0x0483, 0x0486},- {0x0488, 0x0489}, {0x0591, 0x05A1}, {0x05A3, 0x05B9},- {0x05BB, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2},- {0x05C4, 0x05C4}, {0x064B, 0x0655}, {0x0670, 0x0670},- {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED},- {0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A},- {0x07A6, 0x07B0}, {0x0901, 0x0902}, {0x093C, 0x093C},- {0x0941, 0x0948}, {0x094D, 0x094D}, {0x0951, 0x0954},- {0x0962, 0x0963}, {0x0981, 0x0981}, {0x09BC, 0x09BC},- {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, {0x09E2, 0x09E3},- {0x0A02, 0x0A02}, {0x0A3C, 0x0A3C}, {0x0A41, 0x0A42},- {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A70, 0x0A71},- {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, {0x0AC1, 0x0AC5},- {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, {0x0B01, 0x0B01},- {0x0B3C, 0x0B3C}, {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43},- {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B82, 0x0B82},- {0x0BC0, 0x0BC0}, {0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40},- {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},- {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD},- {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, {0x0DCA, 0x0DCA},- {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0E31, 0x0E31},- {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, {0x0EB1, 0x0EB1},- {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, {0x0EC8, 0x0ECD},- {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, {0x0F37, 0x0F37},- {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, {0x0F80, 0x0F84},- {0x0F86, 0x0F87}, {0x0F90, 0x0F97}, {0x0F99, 0x0FBC},- {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, {0x1032, 0x1032},- {0x1036, 0x1037}, {0x1039, 0x1039}, {0x1058, 0x1059},- {0x1160, 0x11FF}, {0x17B7, 0x17BD}, {0x17C6, 0x17C6},- {0x17C9, 0x17D3}, {0x180B, 0x180E}, {0x18A9, 0x18A9},- {0x200B, 0x200F}, {0x202A, 0x202E}, {0x206A, 0x206F},- {0x20D0, 0x20E3}, {0x302A, 0x302F}, {0x3099, 0x309A},- {0xFB1E, 0xFB1E}, {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF},- {0xFFF9, 0xFFFB}- };-- /* test for 8-bit control characters */- if (ucs == 0)- return 0;-- if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0) || ucs > 0x0010ffff)- return -1;-- /* binary search in table of non-spacing characters */- if (mbbisearch(ucs, combining,- sizeof(combining) / sizeof(struct mbinterval) - 1))- return 0;-- /*- * if we arrive here, ucs is not a combining or C0/C1 control character- */-- return 1 +- (ucs >= 0x1100 &&- (ucs <= 0x115f || /* Hangul Jamo init. consonants */- (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a &&- ucs != 0x303f) || /* CJK ... Yi */- (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */- (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility- * Ideographs */- (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */- (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */- (ucs >= 0xffe0 && ucs <= 0xffe6) ||- (ucs >= 0x20000 && ucs <= 0x2ffff)));- }- static pg_wchar utf2ucs(const unsigned char *c) {--- 14,19 ----****************** 191,225 **** } }- /* mb_utf_wcwidth : calculate column length for the utf8 string pwcs- */- static int- mb_utf_wcswidth(const unsigned char *pwcs, size_t len)- {- int w,- l = 0;- int width = 0;-- for (; *pwcs && len > 0; pwcs += l)- {- l = pg_utf_mblen(pwcs);- if ((len < (size_t) l) || ((w = ucs_wcwidth(utf2ucs(pwcs))) < 0))- return width;- len -= l;- width += w;- }- return width;- } static int utf_charcheck(const unsigned char *c) {- /*- * Unicode 3.1 compliant validation : for each category, it checks the- * combination of each byte to make sur it maps to a valid range. It also- * returns -1 for the following UCS values: ucs > 0x10ffff ucs & 0xfffe =- * 0xfffe 0xfdd0 < ucs < 0xfdef ucs & 0xdb00 = 0xd800 (surrogates)- */ if ((*c & 0x80) == 0) return 1; else if ((*c & 0xe0) == 0xc0)--- 48,63 ---- } }+ /*+ * Unicode 3.1 compliant validation : for each category, it checks the+ * combination of each byte to make sure it maps to a valid range. It also+ * returns -1 for the following UCS values: ucs > 0x10ffff ucs & 0xfffe =+ * 0xfffe 0xfdd0 < ucs < 0xfdef ucs & 0xdb00 = 0xd800 (surrogates)+ */ static int utf_charcheck(const unsigned char *c) { if ((*c & 0x80) == 0) return 1; else if ((*c & 0xe0) == 0xc0)****************** 270,275 ****--- 108,114 ---- return -1; }+ static void mb_utf_validate(unsigned char *pwcs) {****************** 277,304 **** while (*pwcs) {! int l;! if ((l = utf_charcheck(pwcs)) > 0) { if (p != pwcs) { int i;! for (i = 0; i < l; i++) *p++ = *pwcs++; } else {! pwcs += l;! p += l; } } else- { /* we skip the char */ pwcs++;- } } if (p != pwcs) *p = '\0';--- 116,141 ---- while (*pwcs) {! int len;! if ((len = utf_charcheck(pwcs)) > 0) { if (p != pwcs) { int i;! for (i = 0; i < len; i++) *p++ = *pwcs++; } else {! pwcs += len;! p += len; } } else /* we skip the char */ pwcs++; } if (p != pwcs) *p = '\0';****************** 308,330 **** * public functions : wcswidth and mbvalidate */ int! pg_wcswidth(const char *pwcs, size_t len, int encoding) {! if (encoding == PG_UTF8)! return mb_utf_wcswidth((const unsigned char *) pwcs, len);! else {! /*! * obviously, other encodings may want to fix this, but I don't know! * them myself, unfortunately.! */! return len; } }! char *! mbvalidate(char *pwcs, int encoding) { if (encoding == PG_UTF8) mb_utf_validate((unsigned char *) pwcs);--- 145,337 ---- * public functions : wcswidth and mbvalidate */+ /*+ * pg_wcswidth is the dumb width function. It assumes that everything will+ * only appear on one line. OTOH it is easier to use if this applies to you.+ */ int! pg_wcswidth(const unsigned char *pwcs, size_t len, int encoding) {! int width = 0;!! while (len > 0) {! int chlen, chwidth;!! chlen = PQmblen(pwcs, encoding);! if (chlen > len)! break; /* Invalid string */!! chwidth = PQdsplen(pwcs, encoding);!! if (chwidth > 0)! width += chwidth;! pwcs += chlen;! }! return width;! }!! /*! * pg_wcssize takes the given string in the given encoding and returns three! * values:! * result_width: Width in display character of longest line in string! * result_hieght: Number of lines in display output! * result_format_size: Number of bytes required to store formatted representation of string! */! int! pg_wcssize(unsigned char *pwcs, size_t len, int encoding, int *result_width,! int *result_height, int *result_format_size)! {! int w,! chlen = 0,! linewidth = 0;! int width = 0;! int height = 1;! int format_size = 0;!! for (; *pwcs && len > 0; pwcs += chlen)! {! chlen = PQmblen(pwcs, encoding);! if (len < (size_t)chlen)! break;! w = PQdsplen(pwcs, encoding);!! if (chlen == 1) /* ASCII char */! {! if (*pwcs == '\n') /* Newline */! {! if (linewidth > width)! width = linewidth;! linewidth = 0;! height += 1;! format_size += 1; /* For NUL char */! }! else if (*pwcs == '\r') /* Linefeed */! {! linewidth += 2;! format_size += 2;! }! else if (w <= 0) /* Other control char */! {! linewidth += 4;! format_size += 4;! }! else /* Output itself */! {! linewidth++;! format_size += 1;! }! }! else if (w <= 0) /* Non-ascii control char */! {! linewidth += 6; /* \u0000 */! format_size += 6;! }! else /* All other chars */! {! linewidth += w;! format_size += chlen;! }! len -= chlen;! }! if (linewidth > width)! width = linewidth;! format_size += 1;!! /* Set results */! if (result_width)! *result_width = width;! if (result_height)! *result_height = height;! if (result_format_size)! *result_format_size = format_size;!! return width;! }!! void! pg_wcsformat(unsigned char *pwcs, size_t len, int encoding,! struct lineptr *lines, int count)! {! int w,! chlen = 0;! int linewidth = 0;!! char *ptr = lines->ptr; /* Pointer to data area */!! for (; *pwcs && len > 0; pwcs += chlen)! {! chlen = PQmblen(pwcs,encoding);! if (len < (size_t)chlen)! break;! w = PQdsplen(pwcs,encoding);!! if (chlen == 1) /* single byte char char */! {! if (*pwcs == '\n') /* Newline */! {! *ptr++ = 0; /* NULL char */! lines->width = linewidth;! linewidth = 0;! lines++;! count--;! if (count == 0)! exit(1); /* Screwup */!! lines->ptr = ptr;! }! else if (*pwcs == '\r') /* Linefeed */! {! strcpy(ptr, "\\r");! linewidth += 2;! ptr += 2;! }! else if (w <= 0) /* Other control char */! {! sprintf(ptr, "\\x%02X", *pwcs);! linewidth += 4;! ptr += 4;! }! else /* Output itself */! {! linewidth++;! *ptr++ = *pwcs;! }! }! else if (w <= 0) /* Non-ascii control char */! {! if (encoding == PG_UTF8)! sprintf(ptr, "\\u%04X", utf2ucs(pwcs));! else! /* This case cannot happen in the current! * code because only UTF-8 signals multibyte! * control characters. But we may need to! * support it at some stage */! sprintf(ptr, "\\u????");!! ptr += 6;! linewidth += 6;! }! else /* All other chars */! {! int i;! for (i=0; i < chlen; i++)! *ptr++ = pwcs[i];! linewidth += w;! }! len -= chlen; }+ *ptr++ = 0;+ lines->width = linewidth;+ lines++;+ count--;+ if (count > 0)+ lines->ptr = NULL;+ return; }! unsigned char *! mbvalidate(unsigned char *pwcs, int encoding) { if (encoding == PG_UTF8) mb_utf_validate((unsigned char *) pwcs);Index: src/bin/psql/mbprint.h===================================================================RCS file: /cvsroot/pgsql/src/bin/psql/mbprint.h,vretrieving revision 1.8diff -c -c -r1.8 mbprint.h*** src/bin/psql/mbprint.h 24 Sep 2005 17:53:27 -0000 1.8--- src/bin/psql/mbprint.h 10 Feb 2006 00:23:33 -0000****************** 4,11 **** #include "mb/pg_wchar.h"! extern char *mbvalidate(char *pwcs, int encoding);! extern int pg_wcswidth(const char *pwcs, size_t len, int encoding); #endif /* MBPRINT_H */--- 4,18 ---- #include "mb/pg_wchar.h"! struct lineptr {! unsigned char *ptr;! int width;! };! extern unsigned char *mbvalidate(unsigned char *pwcs, int encoding);!! extern int pg_wcswidth(const unsigned char *pwcs, size_t len, int encoding);! extern void pg_wcsformat(unsigned char *pwcs, size_t len, int encoding, struct lineptr *lines, int count);! extern int pg_wcssize(unsigned char *pwcs, size_t len, int encoding, int *width, int *height, int *format_size); #endif /* MBPRINT_H */Index: src/bin/psql/print.c===================================================================RCS file: /cvsroot/pgsql/src/bin/psql/print.c,vretrieving revision 1.79diff -c -c -r1.79 print.c*** src/bin/psql/print.c 27 Oct 2005 13:34:47 -0000 1.79--- src/bin/psql/print.c 10 Feb 2006 00:23:33 -0000****************** 49,54 ****--- 49,68 ---- 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) {****************** 87,92 ****--- 101,107 ---- 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) {****************** 342,354 **** { unsigned int col_count = 0; unsigned int cell_count = 0;- unsigned int *head_w,- *cell_w; unsigned int i, tmp; unsigned int *widths, total_w;! const char *const * ptr; /* count columns */ for (ptr = headers; *ptr; ptr++)--- 357,376 ---- { unsigned int col_count = 0; unsigned int cell_count = 0; unsigned int i, tmp; unsigned int *widths, total_w;! unsigned int *heights;! unsigned int *format_space;! unsigned char **format_buf;!! const char *const *ptr;!! struct lineptr **col_lineptrs; /* pointers to line pointer for each column */! struct lineptr *lineptr_list; /* complete list of linepointers */!! int *complete; /* Array remembering which columns have completed output */ /* count columns */ for (ptr = headers; *ptr; ptr++)****************** 356,419 **** if (col_count > 0) {! widths = calloc(col_count, sizeof(*widths));! if (!widths)! {! fprintf(stderr, _("out of memory\n"));! exit(EXIT_FAILURE);! }!! head_w = calloc(col_count, sizeof(*head_w));! if (!head_w)! {! fprintf(stderr, _("out of memory\n"));! exit(EXIT_FAILURE);! } } else { widths = NULL;! head_w = NULL; }! /* count cells (rows * cols) */ for (ptr = cells; *ptr; ptr++) cell_count++;- if (cell_count > 0)- {- cell_w = calloc(cell_count, sizeof(*cell_w));- if (!cell_w)- {- fprintf(stderr, _("out of memory\n"));- exit(EXIT_FAILURE);- }- }- else- cell_w = NULL;- /* calc column widths */ for (i = 0; i < col_count; i++) {! tmp = pg_wcswidth(headers[i], strlen(headers[i]), encoding); if (tmp > widths[i]) widths[i] = tmp;! head_w[i] = tmp; } for (i = 0, ptr = cells; *ptr; ptr++, i++) {! int add_numeric_locale_len; if (opt_align[i % col_count] == 'r' && opt_numeric_locale)! add_numeric_locale_len = additional_numeric_locale_len(*ptr);! else! add_numeric_locale_len = 0;!! tmp = pg_wcswidth(*ptr, strlen(*ptr), encoding) + add_numeric_locale_len; if (tmp > widths[i % col_count]) widths[i % col_count] = tmp;! cell_w[i] = tmp; } if (opt_border == 0)--- 378,438 ---- if (col_count > 0) {! widths = pg_local_calloc(col_count, sizeof(*widths));! heights = pg_local_calloc(col_count, sizeof(*heights));! col_lineptrs = pg_local_calloc(col_count, sizeof(*col_lineptrs));! format_space = pg_local_calloc(col_count, sizeof(*format_space));! format_buf = pg_local_calloc(col_count, sizeof(*format_buf));! complete = pg_local_calloc(col_count, sizeof(*complete));! } else { widths = NULL;! heights = NULL;! col_lineptrs = NULL;! format_space = NULL;! format_buf = NULL;! complete = NULL; }! /* count cells (rows * cols) */ for (ptr = cells; *ptr; ptr++) cell_count++; /* calc column widths */ for (i = 0; i < col_count; i++) {! /* Get width & height */! int height, space;! pg_wcssize((unsigned char *) headers[i], strlen(headers[i]), encoding, &tmp, &height, &space); if (tmp > widths[i]) widths[i] = tmp;! if (height > heights[i])! heights[i] = height;! if (space > format_space[i])! format_space[i] = space; } for (i = 0, ptr = cells; *ptr; ptr++, i++) {! int numeric_locale_len;! int height, space; if (opt_align[i % col_count] == 'r' && opt_numeric_locale)! numeric_locale_len = additional_numeric_locale_len(*ptr);! else! numeric_locale_len = 0;!! /* Get width, ignore height */! pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding, &tmp, &height, &space);! tmp += numeric_locale_len; if (tmp > widths[i % col_count]) widths[i % col_count] = tmp;! if (height > heights[i % col_count])! heights[i % col_count] = height;! if (space > format_space[i % col_count])! format_space[i % col_count] = space; } if (opt_border == 0)****************** 426,435 **** for (i = 0; i < col_count; i++) total_w += widths[i]; /* print title */ if (title && !opt_tuples_only) {! tmp = pg_wcswidth(title, strlen(title), encoding); if (tmp >= total_w) fprintf(fout, "%s\n", title); else--- 445,482 ---- for (i = 0; i < col_count; i++) total_w += widths[i];+ /* At this point:+ * widths contains the max width of each column+ * heights contains the max height of a cell of each column+ * format_space contains maximum space required to store formatted string+ * so we prepare the formatting structures+ */+ {+ int heights_total = 0;+ struct lineptr *lineptr;++ for (i = 0; i < col_count; i++)+ heights_total += heights[i];++ lineptr = lineptr_list = pg_local_calloc(heights_total, sizeof(*lineptr_list));++ for (i = 0; i < col_count; i++)+ {+ col_lineptrs[i] = lineptr;+ lineptr += heights[i];++ format_buf[i] = pg_local_malloc(format_space[i]);++ col_lineptrs[i]->ptr = format_buf[i];+ }+ }+ /* print title */ if (title && !opt_tuples_only) {! /* Get width & height */! int height;! pg_wcssize((unsigned char *)title, strlen(title), encoding, &tmp, &height, NULL); if (tmp >= total_w) fprintf(fout, "%s\n", title); else****************** 439,528 **** /* print headers */ if (!opt_tuples_only) { if (opt_border == 2) _print_horizontal_line(col_count, widths, opt_border, fout);- if (opt_border == 2)- fputs("| ", fout);- else if (opt_border == 1)- fputc(' ', fout);- for (i = 0; i < col_count; i++) {! unsigned int nbspace;! nbspace = widths[i] - head_w[i];! /* centered */! fprintf(fout, "%-*s%s%-*s",! nbspace / 2, "", headers[i], (nbspace + 1) / 2, "");! if (i < col_count - 1)! {! if (opt_border == 0)! fputc(' ', fout); else! fputs(" | ", fout); } }- if (opt_border == 2)- fputs(" |", fout);- else if (opt_border == 1)- fputc(' ', fout);;- fputc('\n', fout); _print_horizontal_line(col_count, widths, opt_border, fout); } /* print cells */! for (i = 0, ptr = cells; *ptr; i++, ptr++) {! /* beginning of line */! if (i % col_count == 0) { if (opt_border == 2) fputs("| ", fout); else if (opt_border == 1) fputc(' ', fout);- }! /* content */! if (opt_align[i % col_count] == 'r')! {! if (opt_numeric_locale) {! char *my_cell = format_numeric_locale(*ptr);! fprintf(fout, "%*s%s", widths[i % col_count] - cell_w[i], "", my_cell);! free(my_cell); }- else- fprintf(fout, "%*s%s", widths[i % col_count] - cell_w[i], "", *ptr);- }- else- {- if ((i + 1) % col_count == 0 && opt_border != 2)- fputs(cells[i], fout);- else- fprintf(fout, "%-s%*s", cells[i],- widths[i % col_count] - cell_w[i], "");- }-- /* divider */- if ((i + 1) % col_count)- {- if (opt_border == 0)- fputc(' ', fout);- else- fputs(" | ", fout);- }- /* end of line */- else- { if (opt_border == 2) fputs(" |", fout); fputc('\n', fout); } }--- 486,623 ---- /* print headers */ if (!opt_tuples_only) {+ int cols_todo;+ int line_count;+ if (opt_border == 2) _print_horizontal_line(col_count, widths, opt_border, fout); for (i = 0; i < col_count; i++)+ pg_wcsformat((unsigned char *)headers[i], strlen(headers[i]), encoding, col_lineptrs[i], heights[i]);++ cols_todo = col_count;+ line_count = 0;+ memset(complete, 0, col_count*sizeof(int));+ while (cols_todo) {! if (opt_border == 2)! fprintf(fout, "|%c", line_count ? '+' : ' ');! else if (opt_border == 1)! fputc(line_count ? '+' : ' ', fout);! for (i = 0; i < col_count; i++)! {! unsigned int nbspace;! struct lineptr *this_line = col_lineptrs[i] + line_count;! if (!complete[i])! {! nbspace = widths[i] - this_line->width;! /* centered */! fprintf(fout, "%-*s%s%-*s",! nbspace / 2, "", this_line->ptr, (nbspace + 1) / 2, "");!! if (line_count == (heights[i]-1) || !(this_line+1)->ptr)! {! cols_todo--;! complete[i] = 1;! }! } else! fprintf(fout, "%*s", widths[i], "");! if (i < col_count - 1)! {! if (opt_border == 0)! fputc(line_count ? '+' : ' ', fout);! else! fprintf(fout, " |%c", line_count ? '+' : ' ');! } }+ line_count++;++ if (opt_border == 2)+ fputs(" |", fout);+ else if (opt_border == 1)+ fputc(' ', fout);;+ fputc('\n', fout); } _print_horizontal_line(col_count, widths, opt_border, fout); } /* print cells */! for (i = 0, ptr = cells; *ptr; i+=col_count, ptr+=col_count) {! int j;! int cols_todo = col_count;! int line_count; /* Number of lines output so far in row */!! for (j = 0; j < col_count; j++)! pg_wcsformat((unsigned char*)ptr[j], strlen(ptr[j]), encoding, col_lineptrs[j], heights[j]);!! line_count = 0;! memset(complete, 0, col_count*sizeof(int));! while (cols_todo) {+ /* beginning of line */ if (opt_border == 2) fputs("| ", fout); else if (opt_border == 1) fputc(' ', fout);! for (j = 0; j < col_count; j++) {! struct lineptr *this_line = col_lineptrs[j] + line_count;! if (complete[j]) /* Just print spaces... */! fprintf(fout, "%*s", widths[j], "");! else! {! /* content */! if (opt_align[j] == 'r')! {! if (opt_numeric_locale)! {! /* Assumption: This code used only on strings! * without multibyte characters, otherwise! * this_line->width < strlen(this_ptr) and we! * get an overflow */!! char *my_cell = format_numeric_locale(this_line->ptr);! fprintf(fout, "%*s%s", widths[i % col_count] - strlen(my_cell), "", my_cell);! free(my_cell);! }! else! fprintf(fout, "%*s%s", widths[j] - this_line->width, "", this_line->ptr);! }! else! fprintf(fout, "%-s%*s", this_line->ptr,! widths[j] - this_line->width, "");! /* If at the right height, done this col */! if (line_count == heights[j]-1 || !this_line[1].ptr)! {! complete[j] = 1;! cols_todo--;! }! }!! /* divider */! if ((j + 1) % col_count)! {! if (opt_border == 0)! fputc(' ', fout);! else if (line_count == 0)! fputs(" | ", fout);! else! fprintf(fout, " %c ", complete[j+1] ? ' ' : ':');! } } if (opt_border == 2) fputs(" |", fout); fputc('\n', fout);+ line_count++; } }****************** 543,551 **** #endif /* clean up */- free(cell_w);- free(head_w); free(widths); }--- 638,652 ---- #endif /* clean up */ free(widths);+ free(heights);+ free(col_lineptrs);+ free(format_space);+ free(complete);+ free(lineptr_list);+ for (i= 0; i < col_count; i++)+ free(format_buf[i]);+ free(format_buf); }****************** 563,574 **** unsigned int i, tmp = 0, hwidth = 0,! dwidth = 0; char *divider; unsigned int cell_count = 0;! unsigned int *cell_w,! *head_w;! if (cells[0] == NULL) { fprintf(fout, _("(No rows)\n"));--- 664,678 ---- unsigned int i, tmp = 0, hwidth = 0,! dwidth = 0,! hheight = 1,! dheight = 1,! hformatsize = 0,! dformatsize = 0; char *divider; unsigned int cell_count = 0;! struct lineptr *hlineptr, *dlineptr;! if (cells[0] == NULL) { fprintf(fout, _("(No rows)\n"));****************** 578,635 **** /* count headers and find longest one */ for (ptr = headers; *ptr; ptr++) col_count++;- if (col_count > 0)- {- head_w = calloc(col_count, sizeof(*head_w));- if (!head_w)- {- fprintf(stderr, _("out of memory\n"));- exit(EXIT_FAILURE);- }- }- else- head_w = NULL; for (i = 0; i < col_count; i++) {! tmp = pg_wcswidth(headers[i], strlen(headers[i]), encoding); if (tmp > hwidth) hwidth = tmp;! head_w[i] = tmp; } /* Count cells, find their lengths */ for (ptr = cells; *ptr; ptr++) cell_count++;- if (cell_count > 0)- {- cell_w = calloc(cell_count, sizeof(*cell_w));- if (!cell_w)- {- fprintf(stderr, _("out of memory\n"));- exit(EXIT_FAILURE);- }- }- else- cell_w = NULL;- /* find longest data cell */ for (i = 0, ptr = cells; *ptr; ptr++, i++) {! int add_numeric_locale_len; if (opt_align[i % col_count] == 'r' && opt_numeric_locale)! add_numeric_locale_len = additional_numeric_locale_len(*ptr);! else! add_numeric_locale_len = 0;! tmp = pg_wcswidth(*ptr, strlen(*ptr), encoding) + add_numeric_locale_len; if (tmp > dwidth) dwidth = tmp;! cell_w[i] = tmp;! }! /* print title */ if (!opt_tuples_only && title) fprintf(fout, "%s\n", title);--- 682,733 ---- /* count headers and find longest one */ for (ptr = headers; *ptr; ptr++) col_count++;+ /* Find the maximum dimensions for the headers */ for (i = 0; i < col_count; i++) {! int height, fs;! pg_wcssize((unsigned char *) headers[i], strlen(headers[i]), encoding, &tmp, &height, &fs); if (tmp > hwidth) hwidth = tmp;! if (height > hheight)! hheight = height;! if (fs > hformatsize)! hformatsize = fs; } /* Count cells, find their lengths */ for (ptr = cells; *ptr; ptr++) cell_count++; /* find longest data cell */ for (i = 0, ptr = cells; *ptr; ptr++, i++) {! int numeric_locale_len;! int height, fs; if (opt_align[i % col_count] == 'r' && opt_numeric_locale)! numeric_locale_len = additional_numeric_locale_len(*ptr);! else! numeric_locale_len = 0;! pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding, &tmp, &height, &fs);! tmp += numeric_locale_len; if (tmp > dwidth) dwidth = tmp;! 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) * dheight);! hlineptr = pg_local_malloc(sizeof(*hlineptr) * hheight);!! dlineptr->ptr = pg_local_malloc(dformatsize);! hlineptr->ptr = pg_local_malloc(hformatsize);! /* print title */ if (!opt_tuples_only && title) fprintf(fout, "%s\n", title);****************** 653,658 ****--- 751,758 ---- /* print records */ for (i = 0, ptr = cells; *ptr; i++, ptr++) {+ int line_count, dcomplete, hcomplete;+ if (i % col_count == 0) { if (!opt_tuples_only)****************** 688,720 **** fprintf(fout, "%s\n", divider); }! if (opt_border == 2)! fputs("| ", fout);! fprintf(fout, "%-s%*s", headers[i % col_count],! hwidth - head_w[i % col_count], "");!! if (opt_border > 0)! fputs(" | ", fout);! else! fputs(" ", fout);!! if (opt_align[i % col_count] == 'r' && opt_numeric_locale) {! char *my_cell = format_numeric_locale(*ptr);!! if (opt_border < 2)! fprintf(fout, "%s\n", my_cell); else! fprintf(fout, "%-s%*s |\n", my_cell, dwidth - cell_w[i], "");! free(my_cell);! }! else! {! if (opt_border < 2)! fprintf(fout, "%s\n", *ptr); else! fprintf(fout, "%-s%*s |\n", *ptr, dwidth - cell_w[i], "");! } } if (opt_border == 2)--- 788,853 ---- fprintf(fout, "%s\n", divider); }! /* Format the header */! pg_wcsformat((unsigned char*)headers[i % col_count],! strlen(headers[i % col_count]), 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)! fputs("| ", fout);! if (!hcomplete)! {! fprintf(fout, "%-s%*s", hlineptr[line_count].ptr,! hwidth - hlineptr[line_count].width, "");!! if (line_count == (hheight-1) || !hlineptr[line_count+1].ptr)! hcomplete = 1;! } else! fprintf(fout, "%*s", hwidth, "");!! if (opt_border > 0)! fprintf(fout, " %c ", (line_count==0)?'|':':'); else! fputs(" ", fout);!! if (!dcomplete)! {! if (opt_align[i % col_count] == 'r' && opt_numeric_locale)! {! char *my_cell = format_numeric_locale(dlineptr[line_count].ptr);! if (opt_border < 2)! fprintf(fout, "%s\n", my_cell);! else! fprintf(fout, "%-s%*s |\n", my_cell, dwidth - strlen(my_cell), "");! free(my_cell);! }! else! {! if (opt_border < 2)! fprintf(fout, "%s\n", dlineptr[line_count].ptr);! else! fprintf(fout, "%-s%*s |\n", dlineptr[line_count].ptr,! dwidth - dlineptr[line_count].width, "");! }!! if (line_count == dheight - 1 || !dlineptr[line_count+1].ptr)! dcomplete = 1;! }! else! {! if (opt_border < 2)! fputc('\n', fout);! else! fprintf(fout, "%*s |\n", dwidth, "");! }! line_count++;! } } if (opt_border == 2)****************** 732,740 **** fputc('\n', fout); free(divider);!! free(cell_w);! free(head_w); }--- 865,874 ---- fputc('\n', fout); free(divider);! free(hlineptr->ptr);! free(dlineptr->ptr);! free(hlineptr);! free(dlineptr); }****************** 1613,1636 **** /* extract headers */ nfields = PQnfields(result);! headers = calloc(nfields + 1, sizeof(*headers));! if (!headers)! {! fprintf(stderr, _("out of memory\n"));! exit(EXIT_FAILURE);! } for (i = 0; i < nfields; i++) headers[i] = mbvalidate(PQfname(result, i), opt->topt.encoding); /* set cells */ ncells = PQntuples(result) * nfields;! cells = calloc(ncells + 1, sizeof(*cells));! if (!cells)! {! fprintf(stderr, _("out of memory\n"));! exit(EXIT_FAILURE);! } for (i = 0; i < ncells; i++) {--- 1747,1760 ---- /* extract headers */ nfields = PQnfields(result);! headers = pg_local_calloc(nfields + 1, sizeof(*headers)); for (i = 0; i < nfields; i++) headers[i] = mbvalidate(PQfname(result, i), opt->topt.encoding); /* set cells */ ncells = PQntuples(result) * nfields;! cells = pg_local_calloc(ncells + 1, sizeof(*cells)); for (i = 0; i < ncells; i++) {****************** 1646,1657 **** footers = opt->footers; else if (!opt->topt.expanded && opt->default_footer) {! footers = calloc(2, sizeof(*footers));! if (!footers)! {! fprintf(stderr, _("out of memory\n"));! exit(EXIT_FAILURE);! } footers[0] = pg_local_malloc(100); if (PQntuples(result) == 1)--- 1770,1776 ---- footers = opt->footers; else if (!opt->topt.expanded && opt->default_footer) {! footers = pg_local_calloc(2, sizeof(*footers)); footers[0] = pg_local_malloc(100); if (PQntuples(result) == 1)****************** 1663,1674 **** footers = NULL; /* set alignment */! align = calloc(nfields + 1, sizeof(*align));! if (!align)! {! fprintf(stderr, _("out of memory\n"));! exit(EXIT_FAILURE);! } for (i = 0; i < nfields; i++) {--- 1782,1788 ---- footers = NULL; /* set alignment */! align = pg_local_calloc(nfields + 1, sizeof(*align)); for (i = 0; i < nfields; i++) {

pgsql-patches by date:

Previous

From:Tom Lane
Date:
Subject:Re: contrib/xinetops for 8.1 "patch"

Next

From:Bruce Momjian
Date:
Subject:Re: [PATCH] psql formatting patch (round 2)

By continuing to browse this website, you agree to the use of cookies. Go to Privacy Policy.

Re: [PATCH] psql formatting patch (round 2) - Mailing list pgsql-patches (2024)
Top Articles
Latest Posts
Article information

Author: Jeremiah Abshire

Last Updated:

Views: 6521

Rating: 4.3 / 5 (54 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: Jeremiah Abshire

Birthday: 1993-09-14

Address: Apt. 425 92748 Jannie Centers, Port Nikitaville, VT 82110

Phone: +8096210939894

Job: Lead Healthcare Manager

Hobby: Watching movies, Watching movies, Knapping, LARPing, Coffee roasting, Lacemaking, Gaming

Introduction: My name is Jeremiah Abshire, I am a outstanding, kind, clever, hilarious, curious, hilarious, outstanding person who loves writing and wants to share my knowledge and understanding with you.