LCOV - differential code coverage report
Current view: top level - src/interfaces/libpq - fe-print.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 42.5 % 334 142 3 10 103 76 13 55 5 69 100 56 3 7
Current Date: 2023-04-08 17:13:01 Functions: 57.1 % 7 4 3 3 1 1 3 2
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (180,240] days: 0.0 % 1 0 1
Legend: Lines: hit not hit (240..) days: 42.6 % 333 142 2 10 103 76 13 55 5 69 100 56
Function coverage date bins:
(240..) days: 36.4 % 11 4 3 3 1 1 3

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * fe-print.c
                                  4                 :  *    functions for pretty-printing query results
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :  *
                                  9                 :  * These functions were formerly part of fe-exec.c, but they
                                 10                 :  * didn't really belong there.
                                 11                 :  *
                                 12                 :  * IDENTIFICATION
                                 13                 :  *    src/interfaces/libpq/fe-print.c
                                 14                 :  *
                                 15                 :  *-------------------------------------------------------------------------
                                 16                 :  */
                                 17                 : #include "postgres_fe.h"
                                 18                 : 
                                 19                 : #include <signal.h>
                                 20                 : 
                                 21                 : #ifdef WIN32
                                 22                 : #include "win32.h"
                                 23                 : #else
                                 24                 : #include <unistd.h>
                                 25                 : #include <sys/ioctl.h>
                                 26                 : #endif
                                 27                 : 
                                 28                 : #ifdef HAVE_TERMIOS_H
                                 29                 : #include <termios.h>
                                 30                 : #else
                                 31                 : #ifndef WIN32
                                 32                 : #include <sys/termios.h>
                                 33                 : #endif
                                 34                 : #endif
                                 35                 : 
                                 36                 : #include "libpq-fe.h"
                                 37                 : #include "libpq-int.h"
                                 38                 : 
                                 39                 : 
                                 40                 : static bool do_field(const PQprintOpt *po, const PGresult *res,
                                 41                 :                      const int i, const int j, const int fs_len,
                                 42                 :                      char **fields,
                                 43                 :                      const int nFields, const char **fieldNames,
                                 44                 :                      unsigned char *fieldNotNum, int *fieldMax,
                                 45                 :                      const int fieldMaxLen, FILE *fout);
                                 46                 : static char *do_header(FILE *fout, const PQprintOpt *po, const int nFields,
                                 47                 :                        int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum,
                                 48                 :                        const int fs_len, const PGresult *res);
                                 49                 : static void output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
                                 50                 :                        unsigned char *fieldNotNum, int *fieldMax, char *border,
                                 51                 :                        const int row_index);
                                 52                 : static void fill(int length, int max, char filler, FILE *fp);
                                 53                 : 
                                 54                 : /*
                                 55                 :  * PQprint()
                                 56                 :  *
                                 57                 :  * Format results of a query for printing.
                                 58                 :  *
                                 59                 :  * PQprintOpt is a typedef (structure) that contains
                                 60                 :  * various flags and options. consult libpq-fe.h for
                                 61                 :  * details
                                 62                 :  *
                                 63                 :  * This function should probably be removed sometime since psql
                                 64                 :  * doesn't use it anymore. It is unclear to what extent this is used
                                 65                 :  * by external clients, however.
                                 66                 :  */
                                 67                 : void
 6510 neilc                      68 CBC        3592 : PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
                                 69                 : {
                                 70                 :     int         nFields;
                                 71                 : 
 9103 bruce                      72            3592 :     nFields = PQnfields(res);
                                 73                 : 
                                 74            3592 :     if (nFields > 0)
                                 75                 :     {                           /* only print rows with at least 1 field.  */
                                 76                 :         int         i,
                                 77                 :                     j;
                                 78                 :         int         nTups;
                                 79            3592 :         int        *fieldMax = NULL;    /* in case we don't use them */
                                 80            3592 :         unsigned char *fieldNotNum = NULL;
                                 81            3592 :         char       *border = NULL;
                                 82            3592 :         char      **fields = NULL;
  650 tgl                        83            3592 :         const char **fieldNames = NULL;
 9103 bruce                      84            3592 :         int         fieldMaxLen = 0;
                                 85                 :         int         numFieldName;
                                 86            3592 :         int         fs_len = strlen(po->fieldSep);
                                 87            3592 :         int         total_line_length = 0;
  650 tgl                        88            3592 :         bool        usePipe = false;
                                 89                 :         char       *pagerenv;
                                 90                 : 
                                 91                 : #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
                                 92                 :         sigset_t    osigset;
 6702 bruce                      93            3592 :         bool        sigpipe_masked = false;
                                 94                 :         bool        sigpipe_pending;
                                 95                 : #endif
                                 96                 : #if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
                                 97                 :         pqsigfunc   oldsigpipehandler = NULL;
                                 98                 : #endif
                                 99                 : 
                                100                 : #ifdef TIOCGWINSZ
                                101                 :         struct winsize screen_size;
                                102                 : #else
                                103                 :         struct winsize
                                104                 :         {
                                105                 :             int         ws_row;
                                106                 :             int         ws_col;
                                107                 :         }           screen_size;
                                108                 : #endif
                                109                 : 
 9103                           110            3592 :         nTups = PQntuples(res);
  650 tgl                       111            3592 :         fieldNames = (const char **) calloc(nFields, sizeof(char *));
                                112            3592 :         fieldNotNum = (unsigned char *) calloc(nFields, 1);
                                113            3592 :         fieldMax = (int *) calloc(nFields, sizeof(int));
                                114            3592 :         if (!fieldNames || !fieldNotNum || !fieldMax)
                                115                 :         {
 6725 peter_e                   116 UBC           0 :             fprintf(stderr, libpq_gettext("out of memory\n"));
  650 tgl                       117               0 :             goto exit;
                                118                 :         }
 9103 bruce                     119 CBC        3592 :         for (numFieldName = 0;
                                120            3592 :              po->fieldName && po->fieldName[numFieldName];
 9103 bruce                     121 UBC           0 :              numFieldName++)
                                122                 :             ;
 9103 bruce                     123 CBC        9282 :         for (j = 0; j < nFields; j++)
                                124                 :         {
                                125                 :             int         len;
 8397                           126            5690 :             const char *s = (j < numFieldName && po->fieldName[j][0]) ?
 9103                           127            5690 :             po->fieldName[j] : PQfname(res, j);
                                128                 : 
                                129            5690 :             fieldNames[j] = s;
                                130            5690 :             len = s ? strlen(s) : 0;
                                131            5690 :             fieldMax[j] = len;
                                132            5690 :             len += fs_len;
                                133            5690 :             if (len > fieldMaxLen)
                                134            4815 :                 fieldMaxLen = len;
                                135            5690 :             total_line_length += len;
                                136                 :         }
                                137                 : 
                                138            3592 :         total_line_length += nFields * strlen(po->fieldSep) + 1;
                                139                 : 
                                140            3592 :         if (fout == NULL)
 9103 bruce                     141 UBC           0 :             fout = stdout;
 5440 bruce                     142 CBC        3592 :         if (po->pager && fout == stdout && isatty(fileno(stdin)) &&
 5440 bruce                     143 UBC           0 :             isatty(fileno(stdout)))
                                144                 :         {
                                145                 :             /*
                                146                 :              * If we think there'll be more than one screen of output, try to
                                147                 :              * pipe to the pager program.
                                148                 :              */
                                149                 : #ifdef TIOCGWINSZ
 9103                           150               0 :             if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
                                151               0 :                 screen_size.ws_col == 0 ||
                                152               0 :                 screen_size.ws_row == 0)
                                153                 :             {
                                154               0 :                 screen_size.ws_row = 24;
                                155               0 :                 screen_size.ws_col = 80;
                                156                 :             }
                                157                 : #else
                                158                 :             screen_size.ws_row = 24;
                                159                 :             screen_size.ws_col = 80;
                                160                 : #endif
                                161                 : 
                                162                 :             /*
                                163                 :              * Since this function is no longer used by psql, we don't examine
                                164                 :              * PSQL_PAGER.  It's possible that the hypothetical external users
                                165                 :              * of the function would like that to happen, but in the name of
                                166                 :              * backwards compatibility, we'll stick to just examining PAGER.
                                167                 :              */
                                168               0 :             pagerenv = getenv("PAGER");
                                169                 :             /* if PAGER is unset, empty or all-white-space, don't use pager */
                                170               0 :             if (pagerenv != NULL &&
 2314 tgl                       171               0 :                 strspn(pagerenv, " \t\r\n") != strlen(pagerenv) &&
 9103 bruce                     172               0 :                 !po->html3 &&
                                173               0 :                 ((po->expanded &&
                                174               0 :                   nTups * (nFields + 1) >= screen_size.ws_row) ||
                                175               0 :                  (!po->expanded &&
                                176               0 :                   nTups * (total_line_length / screen_size.ws_col + 1) *
 8831                           177               0 :                   (1 + (po->standard != 0)) >= screen_size.ws_row -
 9103                           178               0 :                   (po->header != 0) *
                                179               0 :                   (total_line_length / screen_size.ws_col + 1) * 2
 2118 tgl                       180               0 :                   - (po->header != 0) * 2    /* row count and newline */
                                181                 :                   )))
                                182                 :             {
  223 tgl                       183 UNC           0 :                 fflush(NULL);
 9103 bruce                     184 UBC           0 :                 fout = popen(pagerenv, "w");
                                185               0 :                 if (fout)
 9103 bruce                     186 EUB             :                 {
  650 tgl                       187 UIC           0 :                     usePipe = true;
 6438 bruce                     188 EUB             : #ifndef WIN32
                                189                 : #ifdef ENABLE_THREAD_SAFETY
 6702 tgl                       190 UIC           0 :                     if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
 6702 tgl                       191 UBC           0 :                         sigpipe_masked = true;
 7030 bruce                     192 EUB             : #else
                                193                 :                     oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
                                194                 : #endif                          /* ENABLE_THREAD_SAFETY */
                                195                 : #endif                          /* WIN32 */
                                196                 :                 }
                                197                 :                 else
 9103 bruce                     198 UIC           0 :                     fout = stdout;
 9103 bruce                     199 EUB             :             }
                                200                 :         }
                                201                 : 
 9103 bruce                     202 GIC        3592 :         if (!po->expanded && (po->align || po->html3))
 9103 bruce                     203 ECB             :         {
  650 tgl                       204 GIC        3592 :             fields = (char **) calloc((size_t) nTups + 1,
  650 tgl                       205 ECB             :                                       nFields * sizeof(char *));
  650 tgl                       206 GIC        3592 :             if (!fields)
 9103 bruce                     207 ECB             :             {
 6725 peter_e                   208 UIC           0 :                 fprintf(stderr, libpq_gettext("out of memory\n"));
  650 tgl                       209 UBC           0 :                 goto exit;
 9103 bruce                     210 EUB             :             }
                                211                 :         }
 9103 bruce                     212 UIC           0 :         else if (po->header && !po->html3)
 9103 bruce                     213 EUB             :         {
 9103 bruce                     214 UIC           0 :             if (po->expanded)
 9103 bruce                     215 EUB             :             {
 9103 bruce                     216 UIC           0 :                 if (po->align)
 6620 bruce                     217 UBC           0 :                     fprintf(fout, libpq_gettext("%-*s%s Value\n"),
                                218               0 :                             fieldMaxLen - fs_len, libpq_gettext("Field"), po->fieldSep);
 9103 bruce                     219 EUB             :                 else
 6620 bruce                     220 UIC           0 :                     fprintf(fout, libpq_gettext("%s%sValue\n"), libpq_gettext("Field"), po->fieldSep);
 9103 bruce                     221 EUB             :             }
                                222                 :             else
                                223                 :             {
 9103 bruce                     224 UIC           0 :                 int         len = 0;
 9103 bruce                     225 EUB             : 
 9103 bruce                     226 UIC           0 :                 for (j = 0; j < nFields; j++)
 9103 bruce                     227 EUB             :                 {
 8397 bruce                     228 UIC           0 :                     const char *s = fieldNames[j];
 9103 bruce                     229 EUB             : 
 9103 bruce                     230 UIC           0 :                     fputs(s, fout);
 9103 bruce                     231 UBC           0 :                     len += strlen(s) + fs_len;
                                232               0 :                     if ((j + 1) < nFields)
                                233               0 :                         fputs(po->fieldSep, fout);
 9103 bruce                     234 EUB             :                 }
 9103 bruce                     235 UIC           0 :                 fputc('\n', fout);
 9103 bruce                     236 UBC           0 :                 for (len -= fs_len; len--; fputc('-', fout));
                                237               0 :                 fputc('\n', fout);
 9103 bruce                     238 EUB             :             }
                                239                 :         }
 9103 bruce                     240 GIC        3592 :         if (po->expanded && po->html3)
 9103 bruce                     241 ECB             :         {
 9103 bruce                     242 UIC           0 :             if (po->caption)
 6271 bruce                     243 UBC           0 :                 fprintf(fout, "<center><h2>%s</h2></center>\n", po->caption);
 9103 bruce                     244 EUB             :             else
 9103 bruce                     245 UIC           0 :                 fprintf(fout,
 6271 bruce                     246 EUB             :                         "<center><h2>"
                                247                 :                         "Query retrieved %d rows * %d fields"
                                248                 :                         "</h2></center>\n",
                                249                 :                         nTups, nFields);
                                250                 :         }
 9103 bruce                     251 GIC        8585 :         for (i = 0; i < nTups; i++)
 9103 bruce                     252 ECB             :         {
 9103 bruce                     253 GIC        4993 :             if (po->expanded)
 9103 bruce                     254 ECB             :             {
 9103 bruce                     255 UIC           0 :                 if (po->html3)
 9103 bruce                     256 UBC           0 :                     fprintf(fout,
 6270 bruce                     257 EUB             :                             "<table %s><caption align=\"top\">%d</caption>\n",
 9103 bruce                     258 UIC           0 :                             po->tableOpt ? po->tableOpt : "", i);
 9103 bruce                     259 EUB             :                 else
 6620 bruce                     260 UIC           0 :                     fprintf(fout, libpq_gettext("-- RECORD %d --\n"), i);
 9103 bruce                     261 EUB             :             }
 9103 bruce                     262 GIC       13683 :             for (j = 0; j < nFields; j++)
  650 tgl                       263 ECB             :             {
  650 tgl                       264 GIC        8690 :                 if (!do_field(po, res, i, j, fs_len, fields, nFields,
  650 tgl                       265 ECB             :                               fieldNames, fieldNotNum,
                                266                 :                               fieldMax, fieldMaxLen, fout))
  650 tgl                       267 UIC           0 :                     goto exit;
  650 tgl                       268 EUB             :             }
 9103 bruce                     269 GIC        4993 :             if (po->html3 && po->expanded)
 9103 bruce                     270 LBC           0 :                 fputs("</table>\n", fout);
 9103 bruce                     271 EUB             :         }
 9103 bruce                     272 GIC        3592 :         if (!po->expanded && (po->align || po->html3))
 9103 bruce                     273 ECB             :         {
 9103 bruce                     274 GIC        3592 :             if (po->html3)
 9103 bruce                     275 ECB             :             {
 9103 bruce                     276 UIC           0 :                 if (po->header)
 9103 bruce                     277 EUB             :                 {
 9103 bruce                     278 UIC           0 :                     if (po->caption)
 9103 bruce                     279 UBC           0 :                         fprintf(fout,
 2118 tgl                       280 EUB             :                                 "<table %s><caption align=\"top\">%s</caption>\n",
 9103 bruce                     281 UIC           0 :                                 po->tableOpt ? po->tableOpt : "",
 9103 bruce                     282 UBC           0 :                                 po->caption);
 9103 bruce                     283 EUB             :                     else
 9103 bruce                     284 UIC           0 :                         fprintf(fout,
 6270 bruce                     285 EUB             :                                 "<table %s><caption align=\"top\">"
                                286                 :                                 "Retrieved %d rows * %d fields"
                                287                 :                                 "</caption>\n",
 2118 tgl                       288 UIC           0 :                                 po->tableOpt ? po->tableOpt : "", nTups, nFields);
 9103 bruce                     289 EUB             :                 }
                                290                 :                 else
 9103 bruce                     291 UIC           0 :                     fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : "");
 9103 bruce                     292 EUB             :             }
 9103 bruce                     293 GIC        3592 :             if (po->header)
 9103 bruce                     294 CBC        3592 :                 border = do_header(fout, po, nFields, fieldMax, fieldNames,
 9103 bruce                     295 ECB             :                                    fieldNotNum, fs_len, res);
 9103 bruce                     296 GIC        8585 :             for (i = 0; i < nTups; i++)
 9103 bruce                     297 CBC        4993 :                 output_row(fout, po, nFields, fields,
 9103 bruce                     298 ECB             :                            fieldNotNum, fieldMax, border, i);
                                299                 :         }
 9103 bruce                     300 GIC        3592 :         if (po->header && !po->html3)
 9103 bruce                     301 CBC        3592 :             fprintf(fout, "(%d row%s)\n\n", PQntuples(res),
  708                           302            3592 :                     (PQntuples(res) == 1) ? "" : "s");
 1584 tgl                       303            3592 :         if (po->html3 && !po->expanded)
 1584 tgl                       304 LBC           0 :             fputs("</table>\n", fout);
  650 tgl                       305 EUB             : 
  650 tgl                       306 GIC        3592 : exit:
  297 peter                     307 GNC        3592 :         free(fieldMax);
                                308            3592 :         free(fieldNotNum);
                                309            3592 :         free(border);
  650 tgl                       310 GIC        3592 :         if (fields)
  650 tgl                       311 ECB             :         {
                                312                 :             /* if calloc succeeded, this shouldn't overflow size_t */
  650 tgl                       313 CBC        3592 :             size_t      numfields = ((size_t) nTups + 1) * (size_t) nFields;
  650 tgl                       314 ECB             : 
  650 tgl                       315 CBC       17972 :             while (numfields-- > 0)
  297 peter                     316 GNC       14380 :                 free(fields[numfields]);
  650 tgl                       317 GIC        3592 :             free(fields);
                                318                 :         }
  297 peter                     319 GNC        3592 :         free(fieldNames);
 9103 bruce                     320 GIC        3592 :         if (usePipe)
                                321                 :         {
                                322                 : #ifdef WIN32
 9046 bruce                     323 EUB             :             _pclose(fout);
                                324                 : #else
 9103 bruce                     325 UIC           0 :             pclose(fout);
                                326                 : 
                                327                 : #ifdef ENABLE_THREAD_SAFETY
                                328                 :             /* we can't easily verify if EPIPE occurred, so say it did */
 6702                           329               0 :             if (sigpipe_masked)
      tgl                       330               0 :                 pq_reset_sigpipe(&osigset, sigpipe_pending, true);
 7030 bruce                     331 ECB             : #else
                                332                 :             pqsignal(SIGPIPE, oldsigpipehandler);
                                333                 : #endif                          /* ENABLE_THREAD_SAFETY */
                                334                 : #endif                          /* WIN32 */
 9103                           335                 :         }
                                336                 :     }
 9103 bruce                     337 GIC        3592 : }
                                338                 : 
                                339                 : 
                                340                 : static bool
 8550                           341            8690 : do_field(const PQprintOpt *po, const PGresult *res,
                                342                 :          const int i, const int j, const int fs_len,
                                343                 :          char **fields,
                                344                 :          const int nFields, char const **fieldNames,
                                345                 :          unsigned char *fieldNotNum, int *fieldMax,
                                346                 :          const int fieldMaxLen, FILE *fout)
 9103 bruce                     347 ECB             : {
 8397                           348                 :     const char *pval,
                                349                 :                *p;
 9103                           350                 :     int         plen;
                                351                 :     bool        skipit;
                                352                 : 
 9103 bruce                     353 CBC        8690 :     plen = PQgetlength(res, i, j);
 9103 bruce                     354 GIC        8690 :     pval = PQgetvalue(res, i, j);
                                355                 : 
 9103 bruce                     356 GBC        8690 :     if (plen < 1 || !pval || !*pval)
 9103 bruce                     357 EUB             :     {
 9103 bruce                     358 GIC         595 :         if (po->align || po->expanded)
                                359             595 :             skipit = true;
                                360                 :         else
 9103 bruce                     361 ECB             :         {
 9103 bruce                     362 UIC           0 :             skipit = false;
 9103 bruce                     363 LBC           0 :             goto efield;
                                364                 :         }
 9103 bruce                     365 ECB             :     }
                                366                 :     else
 9103 bruce                     367 GIC        8095 :         skipit = false;
 9103 bruce                     368 ECB             : 
 9103 bruce                     369 GIC        8690 :     if (!skipit)
 9103 bruce                     370 ECB             :     {
 8397 bruce                     371 GIC        8095 :         if (po->align && !fieldNotNum[j])
 8622 tgl                       372 ECB             :         {
                                373                 :             /* Detect whether field contains non-numeric data */
 8622 tgl                       374 CBC        7247 :             char        ch = '0';
 8720 bruce                     375 ECB             : 
  671 tgl                       376 CBC       22242 :             for (p = pval; *p; p += PQmblenBounded(p, res->client_encoding))
                                377                 :             {
 8622 tgl                       378 GIC       16656 :                 ch = *p;
 8397 bruce                     379           19633 :                 if (!((ch >= '0' && ch <= '9') ||
 8397 bruce                     380 CBC        2980 :                       ch == '.' ||
                                381            2977 :                       ch == 'E' ||
 8397 bruce                     382 GIC        2977 :                       ch == 'e' ||
                                383                 :                       ch == ' ' ||
                                384                 :                       ch == '-'))
                                385                 :                 {
 8622 tgl                       386            1661 :                     fieldNotNum[j] = 1;
                                387            1661 :                     break;
                                388                 :                 }
                                389                 :             }
 8397 bruce                     390 ECB             : 
 8953 tgl                       391                 :             /*
 6385 bruce                     392                 :              * Above loop will believe E in first column is numeric; also, we
                                393                 :              * insist on a digit in the last column for a numeric. This test
                                394                 :              * is still not bulletproof but it handles most cases.
 8953 tgl                       395                 :              */
 8622 tgl                       396 GIC        7247 :             if (*pval == 'E' || *pval == 'e' ||
 8622 tgl                       397 CBC        7229 :                 !(ch >= '0' && ch <= '9'))
 9103 bruce                     398            1661 :                 fieldNotNum[j] = 1;
 9103 bruce                     399 ECB             :         }
                                400                 : 
 9103 bruce                     401 GBC        8095 :         if (!po->expanded && (po->align || po->html3))
 9103 bruce                     402 EUB             :         {
 8622 tgl                       403 GIC        8095 :             if (plen > fieldMax[j])
 8622 tgl                       404 CBC        1153 :                 fieldMax[j] = plen;
 8622 tgl                       405 GIC        8095 :             if (!(fields[i * nFields + j] = (char *) malloc(plen + 1)))
                                406                 :             {
 6725 peter_e                   407 UIC           0 :                 fprintf(stderr, libpq_gettext("out of memory\n"));
  650 tgl                       408 UBC           0 :                 return false;
                                409                 :             }
 8622 tgl                       410 GBC        8095 :             strcpy(fields[i * nFields + j], pval);
 9103 bruce                     411 EUB             :         }
                                412                 :         else
                                413                 :         {
 9103 bruce                     414 UBC           0 :             if (po->expanded)
 9103 bruce                     415 EUB             :             {
 9103 bruce                     416 UIC           0 :                 if (po->html3)
                                417               0 :                     fprintf(fout,
                                418                 :                             "<tr><td align=\"left\"><b>%s</b></td>"
 6270 bruce                     419 EUB             :                             "<td align=\"%s\">%s</td></tr>\n",
 9103 bruce                     420 UBC           0 :                             fieldNames[j],
 9103 bruce                     421 UIC           0 :                             fieldNotNum[j] ? "left" : "right",
 8622 tgl                       422 EUB             :                             pval);
 9103 bruce                     423                 :                 else
                                424                 :                 {
 9103 bruce                     425 UIC           0 :                     if (po->align)
 9103 bruce                     426 UBC           0 :                         fprintf(fout,
                                427                 :                                 "%-*s%s %s\n",
 8622 tgl                       428               0 :                                 fieldMaxLen - fs_len, fieldNames[j],
 8622 tgl                       429 UIC           0 :                                 po->fieldSep,
                                430                 :                                 pval);
                                431                 :                     else
                                432               0 :                         fprintf(fout,
 8622 tgl                       433 EUB             :                                 "%s%s%s\n",
 8622 tgl                       434 UIC           0 :                                 fieldNames[j], po->fieldSep, pval);
 9103 bruce                     435 EUB             :                 }
                                436                 :             }
                                437                 :             else
                                438                 :             {
 9103 bruce                     439 UIC           0 :                 if (!po->html3)
 9103 bruce                     440 EUB             :                 {
 8622 tgl                       441 UIC           0 :                     fputs(pval, fout);
 9103 bruce                     442               0 :             efield:
                                443               0 :                     if ((j + 1) < nFields)
                                444               0 :                         fputs(po->fieldSep, fout);
 9103 bruce                     445 ECB             :                     else
 9103 bruce                     446 UIC           0 :                         fputc('\n', fout);
                                447                 :                 }
                                448                 :             }
                                449                 :         }
 9103 bruce                     450 ECB             :     }
  650 tgl                       451 GIC        8690 :     return true;
                                452                 : }
                                453                 : 
                                454                 : 
 9103 bruce                     455 ECB             : static char *
 8550 bruce                     456 GIC        3592 : do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax,
 8550 bruce                     457 ECB             :           const char **fieldNames, unsigned char *fieldNotNum,
 8550 bruce                     458 EUB             :           const int fs_len, const PGresult *res)
                                459                 : {
                                460                 :     int         j;              /* for loop index */
 9103 bruce                     461 CBC        3592 :     char       *border = NULL;
 9103 bruce                     462 ECB             : 
 9103 bruce                     463 CBC        3592 :     if (po->html3)
 9103 bruce                     464 UIC           0 :         fputs("<tr>", fout);
 9103 bruce                     465 ECB             :     else
                                466                 :     {
 9103 bruce                     467 CBC        3592 :         int         tot = 0;
 9103 bruce                     468 GBC        3592 :         int         n = 0;
 9103 bruce                     469 CBC        3592 :         char       *p = NULL;
 9103 bruce                     470 ECB             : 
 9103 bruce                     471 GIC        9282 :         for (; n < nFields; n++)
 9103 bruce                     472 GBC        5690 :             tot += fieldMax[n] + fs_len + (po->standard ? 2 : 0);
                                473            3592 :         if (po->standard)
 9103 bruce                     474 UIC           0 :             tot += fs_len * 2 + 2;
 9103 bruce                     475 CBC        3592 :         border = malloc(tot + 1);
                                476            3592 :         if (!border)
                                477                 :         {
 6725 peter_e                   478 UBC           0 :             fprintf(stderr, libpq_gettext("out of memory\n"));
  650 tgl                       479 UIC           0 :             return NULL;
 9103 bruce                     480 EUB             :         }
 9103 bruce                     481 GBC        3592 :         p = border;
 9103 bruce                     482 GIC        3592 :         if (po->standard)
 9103 bruce                     483 ECB             :         {
 8829 bruce                     484 UIC           0 :             char       *fs = po->fieldSep;
                                485                 : 
 9103                           486               0 :             while (*fs++)
 9103 bruce                     487 LBC           0 :                 *p++ = '+';
 9103 bruce                     488 ECB             :         }
 9103 bruce                     489 GIC        9282 :         for (j = 0; j < nFields; j++)
 9103 bruce                     490 ECB             :         {
                                491                 :             int         len;
                                492                 : 
 9103 bruce                     493 CBC       55281 :             for (len = fieldMax[j] + (po->standard ? 2 : 0); len--; *p++ = '-');
 9103 bruce                     494 GIC        5690 :             if (po->standard || (j + 1) < nFields)
                                495                 :             {
 8829 bruce                     496 CBC        2098 :                 char       *fs = po->fieldSep;
 9103 bruce                     497 ECB             : 
 9103 bruce                     498 GBC        4196 :                 while (*fs++)
 9103 bruce                     499 GIC        2098 :                     *p++ = '+';
 9103 bruce                     500 ECB             :             }
 9103 bruce                     501 EUB             :         }
 9103 bruce                     502 CBC        3592 :         *p = '\0';
 9103 bruce                     503 GIC        3592 :         if (po->standard)
 9103 bruce                     504 LBC           0 :             fprintf(fout, "%s\n", border);
                                505                 :     }
 9103 bruce                     506 CBC        3592 :     if (po->standard)
 9103 bruce                     507 UIC           0 :         fputs(po->fieldSep, fout);
 9103 bruce                     508 GBC        9282 :     for (j = 0; j < nFields; j++)
 9103 bruce                     509 EUB             :     {
 8397 bruce                     510 GIC        5690 :         const char *s = PQfname(res, j);
                                511                 : 
 9103                           512            5690 :         if (po->html3)
 9103 bruce                     513 ECB             :         {
 6270 bruce                     514 UIC           0 :             fprintf(fout, "<th align=\"%s\">%s</th>",
 9103 bruce                     515 LBC           0 :                     fieldNotNum[j] ? "left" : "right", fieldNames[j]);
 9103 bruce                     516 EUB             :         }
 9103 bruce                     517 ECB             :         else
 9103 bruce                     518 EUB             :         {
 9103 bruce                     519 GBC        5690 :             int         n = strlen(s);
 9103 bruce                     520 EUB             : 
 9103 bruce                     521 GIC        5690 :             if (n > fieldMax[j])
 9103 bruce                     522 LBC           0 :                 fieldMax[j] = n;
 9103 bruce                     523 CBC        5690 :             if (po->standard)
 9103 bruce                     524 LBC           0 :                 fprintf(fout,
 9103 bruce                     525 UIC           0 :                         fieldNotNum[j] ? " %-*s " : " %*s ",
                                526               0 :                         fieldMax[j], s);
 9103 bruce                     527 ECB             :             else
 9103 bruce                     528 GBC        5690 :                 fprintf(fout, fieldNotNum[j] ? "%-*s" : "%*s", fieldMax[j], s);
 9103 bruce                     529 GIC        5690 :             if (po->standard || (j + 1) < nFields)
 9103 bruce                     530 CBC        2098 :                 fputs(po->fieldSep, fout);
 9103 bruce                     531 ECB             :         }
                                532                 :     }
 9103 bruce                     533 GIC        3592 :     if (po->html3)
 9103 bruce                     534 UIC           0 :         fputs("</tr>\n", fout);
                                535                 :     else
 9103 bruce                     536 CBC        3592 :         fprintf(fout, "\n%s\n", border);
 9103 bruce                     537 GIC        3592 :     return border;
                                538                 : }
                                539                 : 
                                540                 : 
                                541                 : static void
 8550 bruce                     542 CBC        4993 : output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
 8986 bruce                     543 EUB             :            unsigned char *fieldNotNum, int *fieldMax, char *border,
 9103 bruce                     544 ECB             :            const int row_index)
 9103 bruce                     545 EUB             : {
 9103 bruce                     546 ECB             :     int         field_index;    /* for loop index */
                                547                 : 
 9103 bruce                     548 CBC        4993 :     if (po->html3)
 9103 bruce                     549 UIC           0 :         fputs("<tr>", fout);
 9103 bruce                     550 CBC        4993 :     else if (po->standard)
 9103 bruce                     551 UBC           0 :         fputs(po->fieldSep, fout);
 9103 bruce                     552 GBC       13683 :     for (field_index = 0; field_index < nFields; field_index++)
                                553                 :     {
 9103 bruce                     554 GIC        8690 :         char       *p = fields[row_index * nFields + field_index];
 9103 bruce                     555 ECB             : 
 9103 bruce                     556 CBC        8690 :         if (po->html3)
 6270 bruce                     557 LBC           0 :             fprintf(fout, "<td align=\"%s\">%s</td>",
 6385                           558               0 :                     fieldNotNum[field_index] ? "left" : "right", p ? p : "");
 9103 bruce                     559 ECB             :         else
                                560                 :         {
 9103 bruce                     561 CBC       17380 :             fprintf(fout,
                                562            8690 :                     fieldNotNum[field_index] ?
 9103 bruce                     563 GIC        8690 :                     (po->standard ? " %-*s " : "%-*s") :
                                564            6176 :                     (po->standard ? " %*s " : "%*s"),
 9103 bruce                     565 CBC        8690 :                     fieldMax[field_index],
 9103 bruce                     566 EUB             :                     p ? p : "");
 9103 bruce                     567 CBC        8690 :             if (po->standard || field_index + 1 < nFields)
 9103 bruce                     568 GBC        3697 :                 fputs(po->fieldSep, fout);
 9103 bruce                     569 ECB             :         }
                                570                 :     }
 9103 bruce                     571 GIC        4993 :     if (po->html3)
 9103 bruce                     572 UIC           0 :         fputs("</tr>", fout);
 9103 bruce                     573 GIC        4993 :     else if (po->standard)
 9103 bruce                     574 UIC           0 :         fprintf(fout, "\n%s", border);
 9103 bruce                     575 GIC        4993 :     fputc('\n', fout);
                                576            4993 : }
                                577                 : 
                                578                 : 
 9103 bruce                     579 EUB             : 
                                580                 : /*
                                581                 :  * really old printing routines
                                582                 :  */
                                583                 : 
                                584                 : void
 8471 peter_e                   585 UIC           0 : PQdisplayTuples(const PGresult *res,
                                586                 :                 FILE *fp,       /* where to send the output */
                                587                 :                 int fillAlign,  /* pad the fields with spaces */
                                588                 :                 const char *fieldSep,   /* field separator */
                                589                 :                 int printHeader,    /* display headers? */
                                590                 :                 int quiet
                                591                 : )
                                592                 : {
 8471 peter_e                   593 EUB             : #define DEFAULT_FIELD_SEP " "
                                594                 : 
                                595                 :     int         i,
                                596                 :                 j;
                                597                 :     int         nFields;
                                598                 :     int         nTuples;
 8471 peter_e                   599 UBC           0 :     int        *fLength = NULL;
 8471 peter_e                   600 EUB             : 
 8471 peter_e                   601 UIC           0 :     if (fieldSep == NULL)
 8471 peter_e                   602 UBC           0 :         fieldSep = DEFAULT_FIELD_SEP;
 8471 peter_e                   603 EUB             : 
                                604                 :     /* Get some useful info about the results */
 8471 peter_e                   605 UIC           0 :     nFields = PQnfields(res);
                                606               0 :     nTuples = PQntuples(res);
 8471 peter_e                   607 EUB             : 
 8471 peter_e                   608 UIC           0 :     if (fp == NULL)
 8471 peter_e                   609 UBC           0 :         fp = stdout;
 8471 peter_e                   610 EUB             : 
                                611                 :     /* Figure the field lengths to align to */
                                612                 :     /* will be somewhat time consuming for very large results */
 8471 peter_e                   613 UBC           0 :     if (fillAlign)
                                614                 :     {
 8471 peter_e                   615 UIC           0 :         fLength = (int *) malloc(nFields * sizeof(int));
 6510 neilc                     616 UBC           0 :         if (!fLength)
                                617                 :         {
                                618               0 :             fprintf(stderr, libpq_gettext("out of memory\n"));
  650 tgl                       619               0 :             return;
                                620                 :         }
 6510 neilc                     621 EUB             : 
 8471 peter_e                   622 UIC           0 :         for (j = 0; j < nFields; j++)
 8471 peter_e                   623 EUB             :         {
 8471 peter_e                   624 UBC           0 :             fLength[j] = strlen(PQfname(res, j));
 8471 peter_e                   625 UIC           0 :             for (i = 0; i < nTuples; i++)
                                626                 :             {
 8397 bruce                     627               0 :                 int         flen = PQgetlength(res, i, j);
                                628                 : 
 8471 peter_e                   629 UBC           0 :                 if (flen > fLength[j])
 8471 peter_e                   630 UIC           0 :                     fLength[j] = flen;
                                631                 :             }
 8471 peter_e                   632 EUB             :         }
                                633                 :     }
                                634                 : 
 8471 peter_e                   635 UBC           0 :     if (printHeader)
 8471 peter_e                   636 EUB             :     {
                                637                 :         /* first, print out the attribute names */
 8471 peter_e                   638 UIC           0 :         for (i = 0; i < nFields; i++)
 8471 peter_e                   639 EUB             :         {
 8471 peter_e                   640 UIC           0 :             fputs(PQfname(res, i), fp);
                                641               0 :             if (fillAlign)
 8471 peter_e                   642 UBC           0 :                 fill(strlen(PQfname(res, i)), fLength[i], ' ', fp);
 8471 peter_e                   643 UIC           0 :             fputs(fieldSep, fp);
 8471 peter_e                   644 EUB             :         }
 8471 peter_e                   645 UBC           0 :         fprintf(fp, "\n");
 8471 peter_e                   646 EUB             : 
                                647                 :         /* Underline the attribute names */
 8471 peter_e                   648 UBC           0 :         for (i = 0; i < nFields; i++)
                                649                 :         {
 8471 peter_e                   650 UIC           0 :             if (fillAlign)
                                651               0 :                 fill(0, fLength[i], '-', fp);
 8471 peter_e                   652 UBC           0 :             fputs(fieldSep, fp);
                                653                 :         }
                                654               0 :         fprintf(fp, "\n");
                                655                 :     }
 8471 peter_e                   656 EUB             : 
                                657                 :     /* next, print out the instances */
 8471 peter_e                   658 UBC           0 :     for (i = 0; i < nTuples; i++)
 8471 peter_e                   659 EUB             :     {
 8471 peter_e                   660 UIC           0 :         for (j = 0; j < nFields; j++)
 8471 peter_e                   661 EUB             :         {
 8471 peter_e                   662 UIC           0 :             fprintf(fp, "%s", PQgetvalue(res, i, j));
                                663               0 :             if (fillAlign)
 8471 peter_e                   664 UBC           0 :                 fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp);
                                665               0 :             fputs(fieldSep, fp);
 8471 peter_e                   666 EUB             :         }
 8471 peter_e                   667 UIC           0 :         fprintf(fp, "\n");
 8471 peter_e                   668 EUB             :     }
                                669                 : 
 8471 peter_e                   670 UBC           0 :     if (!quiet)
 8471 peter_e                   671 UIC           0 :         fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res),
  708 bruce                     672               0 :                 (PQntuples(res) == 1) ? "" : "s");
                                673                 : 
 8471 peter_e                   674               0 :     fflush(fp);
                                675                 : 
  297 peter                     676 UNC           0 :     free(fLength);
                                677                 : }
                                678                 : 
                                679                 : 
                                680                 : 
                                681                 : void
 8471 peter_e                   682 UIC           0 : PQprintTuples(const PGresult *res,
                                683                 :               FILE *fout,       /* output stream */
                                684                 :               int PrintAttNames,    /* print attribute names or not */
                                685                 :               int TerseOutput,  /* delimiter bars or not? */
                                686                 :               int colWidth      /* width of column, if 0, use variable width */
 8471 peter_e                   687 EUB             : )
                                688                 : {
                                689                 :     int         nFields;
                                690                 :     int         nTups;
                                691                 :     int         i,
                                692                 :                 j;
                                693                 :     char        formatString[80];
 8471 peter_e                   694 UIC           0 :     char       *tborder = NULL;
 8471 peter_e                   695 EUB             : 
 8471 peter_e                   696 UIC           0 :     nFields = PQnfields(res);
 8471 peter_e                   697 UBC           0 :     nTups = PQntuples(res);
                                698                 : 
 8471 peter_e                   699 UIC           0 :     if (colWidth > 0)
 8471 peter_e                   700 UBC           0 :         sprintf(formatString, "%%s %%-%ds", colWidth);
                                701                 :     else
 8471 peter_e                   702 UIC           0 :         sprintf(formatString, "%%s %%s");
                                703                 : 
 8471 peter_e                   704 UBC           0 :     if (nFields > 0)
 8471 peter_e                   705 EUB             :     {                           /* only print rows with at least 1 field.  */
                                706                 : 
 8471 peter_e                   707 UIC           0 :         if (!TerseOutput)
 8471 peter_e                   708 EUB             :         {
                                709                 :             int         width;
                                710                 : 
 8471 peter_e                   711 UBC           0 :             width = nFields * 14;
 3731 tgl                       712               0 :             tborder = (char *) malloc(width + 1);
 6510 neilc                     713               0 :             if (!tborder)
 6510 neilc                     714 EUB             :             {
 6510 neilc                     715 UIC           0 :                 fprintf(stderr, libpq_gettext("out of memory\n"));
  650 tgl                       716               0 :                 return;
 6510 neilc                     717 EUB             :             }
 3731 tgl                       718 UIC           0 :             for (i = 0; i < width; i++)
 8471 peter_e                   719 UBC           0 :                 tborder[i] = '-';
 3731 tgl                       720 UIC           0 :             tborder[width] = '\0';
 8471 peter_e                   721 UBC           0 :             fprintf(fout, "%s\n", tborder);
                                722                 :         }
                                723                 : 
 8471 peter_e                   724 UIC           0 :         for (i = 0; i < nFields; i++)
                                725                 :         {
                                726               0 :             if (PrintAttNames)
 8471 peter_e                   727 EUB             :             {
 8471 peter_e                   728 UIC           0 :                 fprintf(fout, formatString,
 8471 peter_e                   729 EUB             :                         TerseOutput ? "" : "|",
                                730                 :                         PQfname(res, i));
                                731                 :             }
                                732                 :         }
                                733                 : 
 8471 peter_e                   734 UIC           0 :         if (PrintAttNames)
 8471 peter_e                   735 EUB             :         {
 8471 peter_e                   736 UIC           0 :             if (TerseOutput)
 8471 peter_e                   737 UBC           0 :                 fprintf(fout, "\n");
                                738                 :             else
                                739               0 :                 fprintf(fout, "|\n%s\n", tborder);
                                740                 :         }
 8471 peter_e                   741 EUB             : 
 8471 peter_e                   742 UIC           0 :         for (i = 0; i < nTups; i++)
                                743                 :         {
                                744               0 :             for (j = 0; j < nFields; j++)
 8471 peter_e                   745 EUB             :             {
 8397 bruce                     746 UBC           0 :                 const char *pval = PQgetvalue(res, i, j);
                                747                 : 
 8471 peter_e                   748               0 :                 fprintf(fout, formatString,
                                749                 :                         TerseOutput ? "" : "|",
                                750                 :                         pval ? pval : "");
                                751                 :             }
                                752               0 :             if (TerseOutput)
 8471 peter_e                   753 UIC           0 :                 fprintf(fout, "\n");
                                754                 :             else
                                755               0 :                 fprintf(fout, "|\n%s\n", tborder);
                                756                 :         }
                                757                 :     }
                                758                 : 
  297 peter                     759 UNC           0 :     free(tborder);
                                760                 : }
                                761                 : 
 8462 peter_e                   762 EUB             : 
                                763                 : /* simply send out max-length number of filler characters to fp */
 8397 bruce                     764                 : 
 8462 peter_e                   765                 : static void
 8462 peter_e                   766 UIC           0 : fill(int length, int max, char filler, FILE *fp)
                                767                 : {
                                768                 :     int         count;
                                769                 : 
 8397 bruce                     770               0 :     count = max - length;
                                771               0 :     while (count-- >= 0)
                                772               0 :         putc(filler, fp);
 8462 peter_e                   773               0 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a