PostgreSQL Source Code  git master
fe-print.c File Reference
#include "postgres_fe.h"
#include <signal.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/termios.h>
#include "libpq-fe.h"
#include "libpq-int.h"
Include dependency graph for fe-print.c:

Go to the source code of this file.

Macros

#define DEFAULT_FIELD_SEP   " "
 

Functions

static bool do_field (const PQprintOpt *po, const PGresult *res, const int i, const int j, const int fs_len, char **fields, const int nFields, const char **fieldNames, unsigned char *fieldNotNum, int *fieldMax, const int fieldMaxLen, FILE *fout)
 
static char * do_header (FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum, const int fs_len, const PGresult *res)
 
static void output_row (FILE *fout, const PQprintOpt *po, const int nFields, char **fields, unsigned char *fieldNotNum, int *fieldMax, char *border, const int row_index)
 
static void fill (int length, int max, char filler, FILE *fp)
 
void PQprint (FILE *fout, const PGresult *res, const PQprintOpt *po)
 
void PQdisplayTuples (const PGresult *res, FILE *fp, int fillAlign, const char *fieldSep, int printHeader, int quiet)
 
void PQprintTuples (const PGresult *res, FILE *fout, int PrintAttNames, int TerseOutput, int colWidth)
 

Macro Definition Documentation

◆ DEFAULT_FIELD_SEP

#define DEFAULT_FIELD_SEP   " "

Function Documentation

◆ do_field()

static bool do_field ( const PQprintOpt po,
const PGresult res,
const int  i,
const int  j,
const int  fs_len,
char **  fields,
const int  nFields,
const char **  fieldNames,
unsigned char *  fieldNotNum,
int *  fieldMax,
const int  fieldMaxLen,
FILE *  fout 
)
static

Definition at line 341 of file fe-print.c.

347 {
348  const char *pval,
349  *p;
350  int plen;
351  bool skipit;
352 
353  plen = PQgetlength(res, i, j);
354  pval = PQgetvalue(res, i, j);
355 
356  if (plen < 1 || !pval || !*pval)
357  {
358  if (po->align || po->expanded)
359  skipit = true;
360  else
361  {
362  skipit = false;
363  goto efield;
364  }
365  }
366  else
367  skipit = false;
368 
369  if (!skipit)
370  {
371  if (po->align && !fieldNotNum[j])
372  {
373  /* Detect whether field contains non-numeric data */
374  char ch = '0';
375 
376  for (p = pval; *p; p += PQmblenBounded(p, res->client_encoding))
377  {
378  ch = *p;
379  if (!((ch >= '0' && ch <= '9') ||
380  ch == '.' ||
381  ch == 'E' ||
382  ch == 'e' ||
383  ch == ' ' ||
384  ch == '-'))
385  {
386  fieldNotNum[j] = 1;
387  break;
388  }
389  }
390 
391  /*
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.
395  */
396  if (*pval == 'E' || *pval == 'e' ||
397  !(ch >= '0' && ch <= '9'))
398  fieldNotNum[j] = 1;
399  }
400 
401  if (!po->expanded && (po->align || po->html3))
402  {
403  if (plen > fieldMax[j])
404  fieldMax[j] = plen;
405  if (!(fields[i * nFields + j] = (char *) malloc(plen + 1)))
406  {
407  fprintf(stderr, libpq_gettext("out of memory\n"));
408  return false;
409  }
410  strcpy(fields[i * nFields + j], pval);
411  }
412  else
413  {
414  if (po->expanded)
415  {
416  if (po->html3)
417  fprintf(fout,
418  "<tr><td align=\"left\"><b>%s</b></td>"
419  "<td align=\"%s\">%s</td></tr>\n",
420  fieldNames[j],
421  fieldNotNum[j] ? "left" : "right",
422  pval);
423  else
424  {
425  if (po->align)
426  fprintf(fout,
427  "%-*s%s %s\n",
428  fieldMaxLen - fs_len, fieldNames[j],
429  po->fieldSep,
430  pval);
431  else
432  fprintf(fout,
433  "%s%s%s\n",
434  fieldNames[j], po->fieldSep, pval);
435  }
436  }
437  else
438  {
439  if (!po->html3)
440  {
441  fputs(pval, fout);
442  efield:
443  if ((j + 1) < nFields)
444  fputs(po->fieldSep, fout);
445  else
446  fputc('\n', fout);
447  }
448  }
449  }
450  }
451  return true;
452 }
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3716
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3705
int PQmblenBounded(const char *s, int encoding)
Definition: fe-misc.c:1187
#define malloc(a)
Definition: header.h:50
int j
Definition: isn.c:74
int i
Definition: isn.c:73
#define libpq_gettext(x)
Definition: libpq-int.h:882
#define fprintf
Definition: port.h:242
pqbool align
Definition: libpq-fe.h:206
pqbool html3
Definition: libpq-fe.h:208
pqbool expanded
Definition: libpq-fe.h:209
char * fieldSep
Definition: libpq-fe.h:211
int client_encoding
Definition: libpq-int.h:191

References _PQprintOpt::align, pg_result::client_encoding, _PQprintOpt::expanded, _PQprintOpt::fieldSep, fprintf, _PQprintOpt::html3, i, j, libpq_gettext, malloc, PQgetlength(), PQgetvalue(), PQmblenBounded(), and res.

Referenced by PQprint().

◆ do_header()

static char * do_header ( FILE *  fout,
const PQprintOpt po,
const int  nFields,
int *  fieldMax,
const char **  fieldNames,
unsigned char *  fieldNotNum,
const int  fs_len,
const PGresult res 
)
static

Definition at line 456 of file fe-print.c.

459 {
460  int j; /* for loop index */
461  char *border = NULL;
462 
463  if (po->html3)
464  fputs("<tr>", fout);
465  else
466  {
467  int tot = 0;
468  int n = 0;
469  char *p = NULL;
470 
471  for (; n < nFields; n++)
472  tot += fieldMax[n] + fs_len + (po->standard ? 2 : 0);
473  if (po->standard)
474  tot += fs_len * 2 + 2;
475  border = malloc(tot + 1);
476  if (!border)
477  {
478  fprintf(stderr, libpq_gettext("out of memory\n"));
479  return NULL;
480  }
481  p = border;
482  if (po->standard)
483  {
484  char *fs = po->fieldSep;
485 
486  while (*fs++)
487  *p++ = '+';
488  }
489  for (j = 0; j < nFields; j++)
490  {
491  int len;
492 
493  for (len = fieldMax[j] + (po->standard ? 2 : 0); len--; *p++ = '-');
494  if (po->standard || (j + 1) < nFields)
495  {
496  char *fs = po->fieldSep;
497 
498  while (*fs++)
499  *p++ = '+';
500  }
501  }
502  *p = '\0';
503  if (po->standard)
504  fprintf(fout, "%s\n", border);
505  }
506  if (po->standard)
507  fputs(po->fieldSep, fout);
508  for (j = 0; j < nFields; j++)
509  {
510  const char *s = PQfname(res, j);
511 
512  if (po->html3)
513  {
514  fprintf(fout, "<th align=\"%s\">%s</th>",
515  fieldNotNum[j] ? "left" : "right", fieldNames[j]);
516  }
517  else
518  {
519  int n = strlen(s);
520 
521  if (n > fieldMax[j])
522  fieldMax[j] = n;
523  if (po->standard)
524  fprintf(fout,
525  fieldNotNum[j] ? " %-*s " : " %*s ",
526  fieldMax[j], s);
527  else
528  fprintf(fout, fieldNotNum[j] ? "%-*s" : "%*s", fieldMax[j], s);
529  if (po->standard || (j + 1) < nFields)
530  fputs(po->fieldSep, fout);
531  }
532  }
533  if (po->html3)
534  fputs("</tr>\n", fout);
535  else
536  fprintf(fout, "\n%s\n", border);
537  return border;
538 }
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3396
const void size_t len
pqbool standard
Definition: libpq-fe.h:207

References _PQprintOpt::fieldSep, fprintf, _PQprintOpt::html3, j, len, libpq_gettext, malloc, PQfname(), res, and _PQprintOpt::standard.

Referenced by PQprint().

◆ fill()

static void fill ( int  length,
int  max,
char  filler,
FILE *  fp 
)
static

Definition at line 766 of file fe-print.c.

767 {
768  int count;
769 
770  count = max - length;
771  while (count-- >= 0)
772  putc(filler, fp);
773 }

Referenced by PQdisplayTuples().

◆ output_row()

static void output_row ( FILE *  fout,
const PQprintOpt po,
const int  nFields,
char **  fields,
unsigned char *  fieldNotNum,
int *  fieldMax,
char *  border,
const int  row_index 
)
static

Definition at line 542 of file fe-print.c.

545 {
546  int field_index; /* for loop index */
547 
548  if (po->html3)
549  fputs("<tr>", fout);
550  else if (po->standard)
551  fputs(po->fieldSep, fout);
552  for (field_index = 0; field_index < nFields; field_index++)
553  {
554  char *p = fields[row_index * nFields + field_index];
555 
556  if (po->html3)
557  fprintf(fout, "<td align=\"%s\">%s</td>",
558  fieldNotNum[field_index] ? "left" : "right", p ? p : "");
559  else
560  {
561  fprintf(fout,
562  fieldNotNum[field_index] ?
563  (po->standard ? " %-*s " : "%-*s") :
564  (po->standard ? " %*s " : "%*s"),
565  fieldMax[field_index],
566  p ? p : "");
567  if (po->standard || field_index + 1 < nFields)
568  fputs(po->fieldSep, fout);
569  }
570  }
571  if (po->html3)
572  fputs("</tr>", fout);
573  else if (po->standard)
574  fprintf(fout, "\n%s", border);
575  fputc('\n', fout);
576 }

References _PQprintOpt::fieldSep, fprintf, _PQprintOpt::html3, and _PQprintOpt::standard.

Referenced by PQprint().

◆ PQdisplayTuples()

void PQdisplayTuples ( const PGresult res,
FILE *  fp,
int  fillAlign,
const char *  fieldSep,
int  printHeader,
int  quiet 
)

Definition at line 585 of file fe-print.c.

592 {
593 #define DEFAULT_FIELD_SEP " "
594 
595  int i,
596  j;
597  int nFields;
598  int nTuples;
599  int *fLength = NULL;
600 
601  if (fieldSep == NULL)
602  fieldSep = DEFAULT_FIELD_SEP;
603 
604  /* Get some useful info about the results */
605  nFields = PQnfields(res);
606  nTuples = PQntuples(res);
607 
608  if (fp == NULL)
609  fp = stdout;
610 
611  /* Figure the field lengths to align to */
612  /* will be somewhat time consuming for very large results */
613  if (fillAlign)
614  {
615  fLength = (int *) malloc(nFields * sizeof(int));
616  if (!fLength)
617  {
618  fprintf(stderr, libpq_gettext("out of memory\n"));
619  return;
620  }
621 
622  for (j = 0; j < nFields; j++)
623  {
624  fLength[j] = strlen(PQfname(res, j));
625  for (i = 0; i < nTuples; i++)
626  {
627  int flen = PQgetlength(res, i, j);
628 
629  if (flen > fLength[j])
630  fLength[j] = flen;
631  }
632  }
633  }
634 
635  if (printHeader)
636  {
637  /* first, print out the attribute names */
638  for (i = 0; i < nFields; i++)
639  {
640  fputs(PQfname(res, i), fp);
641  if (fillAlign)
642  fill(strlen(PQfname(res, i)), fLength[i], ' ', fp);
643  fputs(fieldSep, fp);
644  }
645  fprintf(fp, "\n");
646 
647  /* Underline the attribute names */
648  for (i = 0; i < nFields; i++)
649  {
650  if (fillAlign)
651  fill(0, fLength[i], '-', fp);
652  fputs(fieldSep, fp);
653  }
654  fprintf(fp, "\n");
655  }
656 
657  /* next, print out the instances */
658  for (i = 0; i < nTuples; i++)
659  {
660  for (j = 0; j < nFields; j++)
661  {
662  fprintf(fp, "%s", PQgetvalue(res, i, j));
663  if (fillAlign)
664  fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp);
665  fputs(fieldSep, fp);
666  }
667  fprintf(fp, "\n");
668  }
669 
670  if (!quiet)
671  fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res),
672  (PQntuples(res) == 1) ? "" : "s");
673 
674  fflush(fp);
675 
676  free(fLength);
677 }
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3310
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3318
static void fill(int length, int max, char filler, FILE *fp)
Definition: fe-print.c:766
#define DEFAULT_FIELD_SEP
#define free(a)
Definition: header.h:65
static void const char fflush(stdout)

References DEFAULT_FIELD_SEP, fflush(), fill(), fprintf, free, i, j, libpq_gettext, malloc, PQfname(), PQgetlength(), PQgetvalue(), PQnfields(), PQntuples(), res, and generate_unaccent_rules::stdout.

◆ PQprint()

void PQprint ( FILE *  fout,
const PGresult res,
const PQprintOpt po 
)

Definition at line 68 of file fe-print.c.

69 {
70  int nFields;
71 
72  nFields = PQnfields(res);
73 
74  if (nFields > 0)
75  { /* only print rows with at least 1 field. */
76  int i,
77  j;
78  int nTups;
79  int *fieldMax = NULL; /* in case we don't use them */
80  unsigned char *fieldNotNum = NULL;
81  char *border = NULL;
82  char **fields = NULL;
83  const char **fieldNames = NULL;
84  int fieldMaxLen = 0;
85  int numFieldName;
86  int fs_len = strlen(po->fieldSep);
87  int total_line_length = 0;
88  bool usePipe = false;
89  char *pagerenv;
90 
91 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
92  sigset_t osigset;
93  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 
110  nTups = PQntuples(res);
111  fieldNames = (const char **) calloc(nFields, sizeof(char *));
112  fieldNotNum = (unsigned char *) calloc(nFields, 1);
113  fieldMax = (int *) calloc(nFields, sizeof(int));
114  if (!fieldNames || !fieldNotNum || !fieldMax)
115  {
116  fprintf(stderr, libpq_gettext("out of memory\n"));
117  goto exit;
118  }
119  for (numFieldName = 0;
120  po->fieldName && po->fieldName[numFieldName];
121  numFieldName++)
122  ;
123  for (j = 0; j < nFields; j++)
124  {
125  int len;
126  const char *s = (j < numFieldName && po->fieldName[j][0]) ?
127  po->fieldName[j] : PQfname(res, j);
128 
129  fieldNames[j] = s;
130  len = s ? strlen(s) : 0;
131  fieldMax[j] = len;
132  len += fs_len;
133  if (len > fieldMaxLen)
134  fieldMaxLen = len;
135  total_line_length += len;
136  }
137 
138  total_line_length += nFields * strlen(po->fieldSep) + 1;
139 
140  if (fout == NULL)
141  fout = stdout;
142  if (po->pager && fout == stdout && isatty(fileno(stdin)) &&
143  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
150  if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
151  screen_size.ws_col == 0 ||
152  screen_size.ws_row == 0)
153  {
154  screen_size.ws_row = 24;
155  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  pagerenv = getenv("PAGER");
169  /* if PAGER is unset, empty or all-white-space, don't use pager */
170  if (pagerenv != NULL &&
171  strspn(pagerenv, " \t\r\n") != strlen(pagerenv) &&
172  !po->html3 &&
173  ((po->expanded &&
174  nTups * (nFields + 1) >= screen_size.ws_row) ||
175  (!po->expanded &&
176  nTups * (total_line_length / screen_size.ws_col + 1) *
177  (1 + (po->standard != 0)) >= screen_size.ws_row -
178  (po->header != 0) *
179  (total_line_length / screen_size.ws_col + 1) * 2
180  - (po->header != 0) * 2 /* row count and newline */
181  )))
182  {
183  fflush(NULL);
184  fout = popen(pagerenv, "w");
185  if (fout)
186  {
187  usePipe = true;
188 #ifndef WIN32
189 #ifdef ENABLE_THREAD_SAFETY
190  if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
191  sigpipe_masked = true;
192 #else
193  oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
194 #endif /* ENABLE_THREAD_SAFETY */
195 #endif /* WIN32 */
196  }
197  else
198  fout = stdout;
199  }
200  }
201 
202  if (!po->expanded && (po->align || po->html3))
203  {
204  fields = (char **) calloc((size_t) nTups + 1,
205  nFields * sizeof(char *));
206  if (!fields)
207  {
208  fprintf(stderr, libpq_gettext("out of memory\n"));
209  goto exit;
210  }
211  }
212  else if (po->header && !po->html3)
213  {
214  if (po->expanded)
215  {
216  if (po->align)
217  fprintf(fout, libpq_gettext("%-*s%s Value\n"),
218  fieldMaxLen - fs_len, libpq_gettext("Field"), po->fieldSep);
219  else
220  fprintf(fout, libpq_gettext("%s%sValue\n"), libpq_gettext("Field"), po->fieldSep);
221  }
222  else
223  {
224  int len = 0;
225 
226  for (j = 0; j < nFields; j++)
227  {
228  const char *s = fieldNames[j];
229 
230  fputs(s, fout);
231  len += strlen(s) + fs_len;
232  if ((j + 1) < nFields)
233  fputs(po->fieldSep, fout);
234  }
235  fputc('\n', fout);
236  for (len -= fs_len; len--; fputc('-', fout));
237  fputc('\n', fout);
238  }
239  }
240  if (po->expanded && po->html3)
241  {
242  if (po->caption)
243  fprintf(fout, "<center><h2>%s</h2></center>\n", po->caption);
244  else
245  fprintf(fout,
246  "<center><h2>"
247  "Query retrieved %d rows * %d fields"
248  "</h2></center>\n",
249  nTups, nFields);
250  }
251  for (i = 0; i < nTups; i++)
252  {
253  if (po->expanded)
254  {
255  if (po->html3)
256  fprintf(fout,
257  "<table %s><caption align=\"top\">%d</caption>\n",
258  po->tableOpt ? po->tableOpt : "", i);
259  else
260  fprintf(fout, libpq_gettext("-- RECORD %d --\n"), i);
261  }
262  for (j = 0; j < nFields; j++)
263  {
264  if (!do_field(po, res, i, j, fs_len, fields, nFields,
265  fieldNames, fieldNotNum,
266  fieldMax, fieldMaxLen, fout))
267  goto exit;
268  }
269  if (po->html3 && po->expanded)
270  fputs("</table>\n", fout);
271  }
272  if (!po->expanded && (po->align || po->html3))
273  {
274  if (po->html3)
275  {
276  if (po->header)
277  {
278  if (po->caption)
279  fprintf(fout,
280  "<table %s><caption align=\"top\">%s</caption>\n",
281  po->tableOpt ? po->tableOpt : "",
282  po->caption);
283  else
284  fprintf(fout,
285  "<table %s><caption align=\"top\">"
286  "Retrieved %d rows * %d fields"
287  "</caption>\n",
288  po->tableOpt ? po->tableOpt : "", nTups, nFields);
289  }
290  else
291  fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : "");
292  }
293  if (po->header)
294  border = do_header(fout, po, nFields, fieldMax, fieldNames,
295  fieldNotNum, fs_len, res);
296  for (i = 0; i < nTups; i++)
297  output_row(fout, po, nFields, fields,
298  fieldNotNum, fieldMax, border, i);
299  }
300  if (po->header && !po->html3)
301  fprintf(fout, "(%d row%s)\n\n", PQntuples(res),
302  (PQntuples(res) == 1) ? "" : "s");
303  if (po->html3 && !po->expanded)
304  fputs("</table>\n", fout);
305 
306 exit:
307  free(fieldMax);
308  free(fieldNotNum);
309  free(border);
310  if (fields)
311  {
312  /* if calloc succeeded, this shouldn't overflow size_t */
313  size_t numfields = ((size_t) nTups + 1) * (size_t) nFields;
314 
315  while (numfields-- > 0)
316  free(fields[numfields]);
317  free(fields);
318  }
319  free(fieldNames);
320  if (usePipe)
321  {
322 #ifdef WIN32
323  _pclose(fout);
324 #else
325  pclose(fout);
326 
327 #ifdef ENABLE_THREAD_SAFETY
328  /* we can't easily verify if EPIPE occurred, so say it did */
329  if (sigpipe_masked)
330  pq_reset_sigpipe(&osigset, sigpipe_pending, true);
331 #else
332  pqsignal(SIGPIPE, oldsigpipehandler);
333 #endif /* ENABLE_THREAD_SAFETY */
334 #endif /* WIN32 */
335  }
336  }
337 }
static char * do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum, const int fs_len, const PGresult *res)
Definition: fe-print.c:456
static bool do_field(const PQprintOpt *po, const PGresult *res, const int i, const int j, const int fs_len, char **fields, const int nFields, const char **fieldNames, unsigned char *fieldNotNum, int *fieldMax, const int fieldMaxLen, FILE *fout)
Definition: fe-print.c:341
static void output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields, unsigned char *fieldNotNum, int *fieldMax, char *border, const int row_index)
Definition: fe-print.c:542
#define calloc(a, b)
Definition: header.h:55
exit(1)
void(* pqsigfunc)(SIGNAL_ARGS)
Definition: port.h:488
pqsigfunc pqsignal(int signo, pqsigfunc func)
pqbool pager
Definition: libpq-fe.h:210
char * caption
Definition: libpq-fe.h:213
pqbool header
Definition: libpq-fe.h:205
char ** fieldName
Definition: libpq-fe.h:214
char * tableOpt
Definition: libpq-fe.h:212
#define SIGPIPE
Definition: win32_port.h:181
#define SIG_IGN
Definition: win32_port.h:173

References _PQprintOpt::align, calloc, _PQprintOpt::caption, do_field(), do_header(), exit(), _PQprintOpt::expanded, fflush(), _PQprintOpt::fieldName, _PQprintOpt::fieldSep, fprintf, free, _PQprintOpt::header, _PQprintOpt::html3, i, j, len, libpq_gettext, output_row(), _PQprintOpt::pager, PQfname(), PQnfields(), PQntuples(), pqsignal(), res, SIG_IGN, SIGPIPE, _PQprintOpt::standard, generate_unaccent_rules::stdout, and _PQprintOpt::tableOpt.

Referenced by printResultSet().

◆ PQprintTuples()

void PQprintTuples ( const PGresult res,
FILE *  fout,
int  PrintAttNames,
int  TerseOutput,
int  colWidth 
)

Definition at line 682 of file fe-print.c.

688 {
689  int nFields;
690  int nTups;
691  int i,
692  j;
693  char formatString[80];
694  char *tborder = NULL;
695 
696  nFields = PQnfields(res);
697  nTups = PQntuples(res);
698 
699  if (colWidth > 0)
700  sprintf(formatString, "%%s %%-%ds", colWidth);
701  else
702  sprintf(formatString, "%%s %%s");
703 
704  if (nFields > 0)
705  { /* only print rows with at least 1 field. */
706 
707  if (!TerseOutput)
708  {
709  int width;
710 
711  width = nFields * 14;
712  tborder = (char *) malloc(width + 1);
713  if (!tborder)
714  {
715  fprintf(stderr, libpq_gettext("out of memory\n"));
716  return;
717  }
718  for (i = 0; i < width; i++)
719  tborder[i] = '-';
720  tborder[width] = '\0';
721  fprintf(fout, "%s\n", tborder);
722  }
723 
724  for (i = 0; i < nFields; i++)
725  {
726  if (PrintAttNames)
727  {
728  fprintf(fout, formatString,
729  TerseOutput ? "" : "|",
730  PQfname(res, i));
731  }
732  }
733 
734  if (PrintAttNames)
735  {
736  if (TerseOutput)
737  fprintf(fout, "\n");
738  else
739  fprintf(fout, "|\n%s\n", tborder);
740  }
741 
742  for (i = 0; i < nTups; i++)
743  {
744  for (j = 0; j < nFields; j++)
745  {
746  const char *pval = PQgetvalue(res, i, j);
747 
748  fprintf(fout, formatString,
749  TerseOutput ? "" : "|",
750  pval ? pval : "");
751  }
752  if (TerseOutput)
753  fprintf(fout, "\n");
754  else
755  fprintf(fout, "|\n%s\n", tborder);
756  }
757  }
758 
759  free(tborder);
760 }
#define sprintf
Definition: port.h:240

References fprintf, free, i, j, libpq_gettext, malloc, PQfname(), PQgetvalue(), PQnfields(), PQntuples(), res, and sprintf.