PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
fe-print.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * fe-print.c
4  * functions for pretty-printing query results
5  *
6  * Portions Copyright (c) 1996-2017, 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 void 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
68 PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
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;
84  int fieldMaxLen = 0;
85  int numFieldName;
86  int fs_len = strlen(po->fieldSep);
87  int total_line_length = 0;
88  int usePipe = 0;
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  if (!(fieldNames = (const char **) calloc(nFields, sizeof(char *))))
112  {
113  fprintf(stderr, libpq_gettext("out of memory\n"));
114  abort();
115  }
116  if (!(fieldNotNum = (unsigned char *) calloc(nFields, 1)))
117  {
118  fprintf(stderr, libpq_gettext("out of memory\n"));
119  abort();
120  }
121  if (!(fieldMax = (int *) calloc(nFields, sizeof(int))))
122  {
123  fprintf(stderr, libpq_gettext("out of memory\n"));
124  abort();
125  }
126  for (numFieldName = 0;
127  po->fieldName && po->fieldName[numFieldName];
128  numFieldName++)
129  ;
130  for (j = 0; j < nFields; j++)
131  {
132  int len;
133  const char *s = (j < numFieldName && po->fieldName[j][0]) ?
134  po->fieldName[j] : PQfname(res, j);
135 
136  fieldNames[j] = s;
137  len = s ? strlen(s) : 0;
138  fieldMax[j] = len;
139  len += fs_len;
140  if (len > fieldMaxLen)
141  fieldMaxLen = len;
142  total_line_length += len;
143  }
144 
145  total_line_length += nFields * strlen(po->fieldSep) + 1;
146 
147  if (fout == NULL)
148  fout = stdout;
149  if (po->pager && fout == stdout && isatty(fileno(stdin)) &&
150  isatty(fileno(stdout)))
151  {
152  /*
153  * If we think there'll be more than one screen of output, try to
154  * pipe to the pager program.
155  */
156 #ifdef TIOCGWINSZ
157  if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
158  screen_size.ws_col == 0 ||
159  screen_size.ws_row == 0)
160  {
161  screen_size.ws_row = 24;
162  screen_size.ws_col = 80;
163  }
164 #else
165  screen_size.ws_row = 24;
166  screen_size.ws_col = 80;
167 #endif
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  fout = popen(pagerenv, "w");
184  if (fout)
185  {
186  usePipe = 1;
187 #ifndef WIN32
188 #ifdef ENABLE_THREAD_SAFETY
189  if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
190  sigpipe_masked = true;
191 #else
192  oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
193 #endif /* ENABLE_THREAD_SAFETY */
194 #endif /* WIN32 */
195  }
196  else
197  fout = stdout;
198  }
199  }
200 
201  if (!po->expanded && (po->align || po->html3))
202  {
203  if (!(fields = (char **) calloc(nFields * (nTups + 1), sizeof(char *))))
204  {
205  fprintf(stderr, libpq_gettext("out of memory\n"));
206  abort();
207  }
208  }
209  else if (po->header && !po->html3)
210  {
211  if (po->expanded)
212  {
213  if (po->align)
214  fprintf(fout, libpq_gettext("%-*s%s Value\n"),
215  fieldMaxLen - fs_len, libpq_gettext("Field"), po->fieldSep);
216  else
217  fprintf(fout, libpq_gettext("%s%sValue\n"), libpq_gettext("Field"), po->fieldSep);
218  }
219  else
220  {
221  int len = 0;
222 
223  for (j = 0; j < nFields; j++)
224  {
225  const char *s = fieldNames[j];
226 
227  fputs(s, fout);
228  len += strlen(s) + fs_len;
229  if ((j + 1) < nFields)
230  fputs(po->fieldSep, fout);
231  }
232  fputc('\n', fout);
233  for (len -= fs_len; len--; fputc('-', fout));
234  fputc('\n', fout);
235  }
236  }
237  if (po->expanded && po->html3)
238  {
239  if (po->caption)
240  fprintf(fout, "<center><h2>%s</h2></center>\n", po->caption);
241  else
242  fprintf(fout,
243  "<center><h2>"
244  "Query retrieved %d rows * %d fields"
245  "</h2></center>\n",
246  nTups, nFields);
247  }
248  for (i = 0; i < nTups; i++)
249  {
250  if (po->expanded)
251  {
252  if (po->html3)
253  fprintf(fout,
254  "<table %s><caption align=\"top\">%d</caption>\n",
255  po->tableOpt ? po->tableOpt : "", i);
256  else
257  fprintf(fout, libpq_gettext("-- RECORD %d --\n"), i);
258  }
259  for (j = 0; j < nFields; j++)
260  do_field(po, res, i, j, fs_len, fields, nFields,
261  fieldNames, fieldNotNum,
262  fieldMax, fieldMaxLen, fout);
263  if (po->html3 && po->expanded)
264  fputs("</table>\n", fout);
265  }
266  if (!po->expanded && (po->align || po->html3))
267  {
268  if (po->html3)
269  {
270  if (po->header)
271  {
272  if (po->caption)
273  fprintf(fout,
274  "<table %s><caption align=\"top\">%s</caption>\n",
275  po->tableOpt ? po->tableOpt : "",
276  po->caption);
277  else
278  fprintf(fout,
279  "<table %s><caption align=\"top\">"
280  "Retrieved %d rows * %d fields"
281  "</caption>\n",
282  po->tableOpt ? po->tableOpt : "", nTups, nFields);
283  }
284  else
285  fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : "");
286  }
287  if (po->header)
288  border = do_header(fout, po, nFields, fieldMax, fieldNames,
289  fieldNotNum, fs_len, res);
290  for (i = 0; i < nTups; i++)
291  output_row(fout, po, nFields, fields,
292  fieldNotNum, fieldMax, border, i);
293  free(fields);
294  if (border)
295  free(border);
296  }
297  if (po->header && !po->html3)
298  fprintf(fout, "(%d row%s)\n\n", PQntuples(res),
299  (PQntuples(res) == 1) ? "" : "s");
300  free(fieldMax);
301  free(fieldNotNum);
302  free((void *) fieldNames);
303  if (usePipe)
304  {
305 #ifdef WIN32
306  _pclose(fout);
307 #else
308  pclose(fout);
309 
310 #ifdef ENABLE_THREAD_SAFETY
311  /* we can't easily verify if EPIPE occurred, so say it did */
312  if (sigpipe_masked)
313  pq_reset_sigpipe(&osigset, sigpipe_pending, true);
314 #else
315  pqsignal(SIGPIPE, oldsigpipehandler);
316 #endif /* ENABLE_THREAD_SAFETY */
317 #endif /* WIN32 */
318  }
319  if (po->html3 && !po->expanded)
320  fputs("</table>\n", fout);
321  }
322 }
323 
324 
325 static void
326 do_field(const PQprintOpt *po, const PGresult *res,
327  const int i, const int j, const int fs_len,
328  char **fields,
329  const int nFields, char const **fieldNames,
330  unsigned char *fieldNotNum, int *fieldMax,
331  const int fieldMaxLen, FILE *fout)
332 {
333  const char *pval,
334  *p;
335  int plen;
336  bool skipit;
337 
338  plen = PQgetlength(res, i, j);
339  pval = PQgetvalue(res, i, j);
340 
341  if (plen < 1 || !pval || !*pval)
342  {
343  if (po->align || po->expanded)
344  skipit = true;
345  else
346  {
347  skipit = false;
348  goto efield;
349  }
350  }
351  else
352  skipit = false;
353 
354  if (!skipit)
355  {
356  if (po->align && !fieldNotNum[j])
357  {
358  /* Detect whether field contains non-numeric data */
359  char ch = '0';
360 
361  for (p = pval; *p; p += PQmblen(p, res->client_encoding))
362  {
363  ch = *p;
364  if (!((ch >= '0' && ch <= '9') ||
365  ch == '.' ||
366  ch == 'E' ||
367  ch == 'e' ||
368  ch == ' ' ||
369  ch == '-'))
370  {
371  fieldNotNum[j] = 1;
372  break;
373  }
374  }
375 
376  /*
377  * Above loop will believe E in first column is numeric; also, we
378  * insist on a digit in the last column for a numeric. This test
379  * is still not bulletproof but it handles most cases.
380  */
381  if (*pval == 'E' || *pval == 'e' ||
382  !(ch >= '0' && ch <= '9'))
383  fieldNotNum[j] = 1;
384  }
385 
386  if (!po->expanded && (po->align || po->html3))
387  {
388  if (plen > fieldMax[j])
389  fieldMax[j] = plen;
390  if (!(fields[i * nFields + j] = (char *) malloc(plen + 1)))
391  {
392  fprintf(stderr, libpq_gettext("out of memory\n"));
393  abort();
394  }
395  strcpy(fields[i * nFields + j], pval);
396  }
397  else
398  {
399  if (po->expanded)
400  {
401  if (po->html3)
402  fprintf(fout,
403  "<tr><td align=\"left\"><b>%s</b></td>"
404  "<td align=\"%s\">%s</td></tr>\n",
405  fieldNames[j],
406  fieldNotNum[j] ? "left" : "right",
407  pval);
408  else
409  {
410  if (po->align)
411  fprintf(fout,
412  "%-*s%s %s\n",
413  fieldMaxLen - fs_len, fieldNames[j],
414  po->fieldSep,
415  pval);
416  else
417  fprintf(fout,
418  "%s%s%s\n",
419  fieldNames[j], po->fieldSep, pval);
420  }
421  }
422  else
423  {
424  if (!po->html3)
425  {
426  fputs(pval, fout);
427  efield:
428  if ((j + 1) < nFields)
429  fputs(po->fieldSep, fout);
430  else
431  fputc('\n', fout);
432  }
433  }
434  }
435  }
436 }
437 
438 
439 static char *
440 do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax,
441  const char **fieldNames, unsigned char *fieldNotNum,
442  const int fs_len, const PGresult *res)
443 {
444  int j; /* for loop index */
445  char *border = NULL;
446 
447  if (po->html3)
448  fputs("<tr>", fout);
449  else
450  {
451  int tot = 0;
452  int n = 0;
453  char *p = NULL;
454 
455  for (; n < nFields; n++)
456  tot += fieldMax[n] + fs_len + (po->standard ? 2 : 0);
457  if (po->standard)
458  tot += fs_len * 2 + 2;
459  border = malloc(tot + 1);
460  if (!border)
461  {
462  fprintf(stderr, libpq_gettext("out of memory\n"));
463  abort();
464  }
465  p = border;
466  if (po->standard)
467  {
468  char *fs = po->fieldSep;
469 
470  while (*fs++)
471  *p++ = '+';
472  }
473  for (j = 0; j < nFields; j++)
474  {
475  int len;
476 
477  for (len = fieldMax[j] + (po->standard ? 2 : 0); len--; *p++ = '-');
478  if (po->standard || (j + 1) < nFields)
479  {
480  char *fs = po->fieldSep;
481 
482  while (*fs++)
483  *p++ = '+';
484  }
485  }
486  *p = '\0';
487  if (po->standard)
488  fprintf(fout, "%s\n", border);
489  }
490  if (po->standard)
491  fputs(po->fieldSep, fout);
492  for (j = 0; j < nFields; j++)
493  {
494  const char *s = PQfname(res, j);
495 
496  if (po->html3)
497  {
498  fprintf(fout, "<th align=\"%s\">%s</th>",
499  fieldNotNum[j] ? "left" : "right", fieldNames[j]);
500  }
501  else
502  {
503  int n = strlen(s);
504 
505  if (n > fieldMax[j])
506  fieldMax[j] = n;
507  if (po->standard)
508  fprintf(fout,
509  fieldNotNum[j] ? " %-*s " : " %*s ",
510  fieldMax[j], s);
511  else
512  fprintf(fout, fieldNotNum[j] ? "%-*s" : "%*s", fieldMax[j], s);
513  if (po->standard || (j + 1) < nFields)
514  fputs(po->fieldSep, fout);
515  }
516  }
517  if (po->html3)
518  fputs("</tr>\n", fout);
519  else
520  fprintf(fout, "\n%s\n", border);
521  return border;
522 }
523 
524 
525 static void
526 output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
527  unsigned char *fieldNotNum, int *fieldMax, char *border,
528  const int row_index)
529 {
530  int field_index; /* for loop index */
531 
532  if (po->html3)
533  fputs("<tr>", fout);
534  else if (po->standard)
535  fputs(po->fieldSep, fout);
536  for (field_index = 0; field_index < nFields; field_index++)
537  {
538  char *p = fields[row_index * nFields + field_index];
539 
540  if (po->html3)
541  fprintf(fout, "<td align=\"%s\">%s</td>",
542  fieldNotNum[field_index] ? "left" : "right", p ? p : "");
543  else
544  {
545  fprintf(fout,
546  fieldNotNum[field_index] ?
547  (po->standard ? " %-*s " : "%-*s") :
548  (po->standard ? " %*s " : "%*s"),
549  fieldMax[field_index],
550  p ? p : "");
551  if (po->standard || field_index + 1 < nFields)
552  fputs(po->fieldSep, fout);
553  }
554  if (p)
555  free(p);
556  }
557  if (po->html3)
558  fputs("</tr>", fout);
559  else if (po->standard)
560  fprintf(fout, "\n%s", border);
561  fputc('\n', fout);
562 }
563 
564 
565 
566 /*
567  * really old printing routines
568  */
569 
570 void
572  FILE *fp, /* where to send the output */
573  int fillAlign, /* pad the fields with spaces */
574  const char *fieldSep, /* field separator */
575  int printHeader, /* display headers? */
576  int quiet
577 )
578 {
579 #define DEFAULT_FIELD_SEP " "
580 
581  int i,
582  j;
583  int nFields;
584  int nTuples;
585  int *fLength = NULL;
586 
587  if (fieldSep == NULL)
588  fieldSep = DEFAULT_FIELD_SEP;
589 
590  /* Get some useful info about the results */
591  nFields = PQnfields(res);
592  nTuples = PQntuples(res);
593 
594  if (fp == NULL)
595  fp = stdout;
596 
597  /* Figure the field lengths to align to */
598  /* will be somewhat time consuming for very large results */
599  if (fillAlign)
600  {
601  fLength = (int *) malloc(nFields * sizeof(int));
602  if (!fLength)
603  {
604  fprintf(stderr, libpq_gettext("out of memory\n"));
605  abort();
606  }
607 
608  for (j = 0; j < nFields; j++)
609  {
610  fLength[j] = strlen(PQfname(res, j));
611  for (i = 0; i < nTuples; i++)
612  {
613  int flen = PQgetlength(res, i, j);
614 
615  if (flen > fLength[j])
616  fLength[j] = flen;
617  }
618  }
619  }
620 
621  if (printHeader)
622  {
623  /* first, print out the attribute names */
624  for (i = 0; i < nFields; i++)
625  {
626  fputs(PQfname(res, i), fp);
627  if (fillAlign)
628  fill(strlen(PQfname(res, i)), fLength[i], ' ', fp);
629  fputs(fieldSep, fp);
630  }
631  fprintf(fp, "\n");
632 
633  /* Underline the attribute names */
634  for (i = 0; i < nFields; i++)
635  {
636  if (fillAlign)
637  fill(0, fLength[i], '-', fp);
638  fputs(fieldSep, fp);
639  }
640  fprintf(fp, "\n");
641  }
642 
643  /* next, print out the instances */
644  for (i = 0; i < nTuples; i++)
645  {
646  for (j = 0; j < nFields; j++)
647  {
648  fprintf(fp, "%s", PQgetvalue(res, i, j));
649  if (fillAlign)
650  fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp);
651  fputs(fieldSep, fp);
652  }
653  fprintf(fp, "\n");
654  }
655 
656  if (!quiet)
657  fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res),
658  (PQntuples(res) == 1) ? "" : "s");
659 
660  fflush(fp);
661 
662  if (fLength)
663  free(fLength);
664 }
665 
666 
667 
668 void
670  FILE *fout, /* output stream */
671  int PrintAttNames, /* print attribute names or not */
672  int TerseOutput, /* delimiter bars or not? */
673  int colWidth /* width of column, if 0, use variable width */
674 )
675 {
676  int nFields;
677  int nTups;
678  int i,
679  j;
680  char formatString[80];
681  char *tborder = NULL;
682 
683  nFields = PQnfields(res);
684  nTups = PQntuples(res);
685 
686  if (colWidth > 0)
687  sprintf(formatString, "%%s %%-%ds", colWidth);
688  else
689  sprintf(formatString, "%%s %%s");
690 
691  if (nFields > 0)
692  { /* only print rows with at least 1 field. */
693 
694  if (!TerseOutput)
695  {
696  int width;
697 
698  width = nFields * 14;
699  tborder = (char *) malloc(width + 1);
700  if (!tborder)
701  {
702  fprintf(stderr, libpq_gettext("out of memory\n"));
703  abort();
704  }
705  for (i = 0; i < width; i++)
706  tborder[i] = '-';
707  tborder[width] = '\0';
708  fprintf(fout, "%s\n", tborder);
709  }
710 
711  for (i = 0; i < nFields; i++)
712  {
713  if (PrintAttNames)
714  {
715  fprintf(fout, formatString,
716  TerseOutput ? "" : "|",
717  PQfname(res, i));
718  }
719  }
720 
721  if (PrintAttNames)
722  {
723  if (TerseOutput)
724  fprintf(fout, "\n");
725  else
726  fprintf(fout, "|\n%s\n", tborder);
727  }
728 
729  for (i = 0; i < nTups; i++)
730  {
731  for (j = 0; j < nFields; j++)
732  {
733  const char *pval = PQgetvalue(res, i, j);
734 
735  fprintf(fout, formatString,
736  TerseOutput ? "" : "|",
737  pval ? pval : "");
738  }
739  if (TerseOutput)
740  fprintf(fout, "\n");
741  else
742  fprintf(fout, "|\n%s\n", tborder);
743  }
744  }
745 
746  if (tborder)
747  free(tborder);
748 }
749 
750 
751 /* simply send out max-length number of filler characters to fp */
752 
753 static void
754 fill(int length, int max, char filler, FILE *fp)
755 {
756  int count;
757 
758  count = max - length;
759  while (count-- >= 0)
760  putc(filler, fp);
761 }
static void fill(int length, int max, char filler, FILE *fp)
Definition: fe-print.c:754
#define calloc(a, b)
Definition: header.h:55
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3078
int length(const List *list)
Definition: list.c:1271
void PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
Definition: fe-print.c:68
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2681
void PQprintTuples(const PGresult *res, FILE *fout, int PrintAttNames, int TerseOutput, int colWidth)
Definition: fe-print.c:669
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2759
void PQdisplayTuples(const PGresult *res, FILE *fp, int fillAlign, const char *fieldSep, int printHeader, int quiet)
Definition: fe-print.c:571
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
pqbool standard
Definition: libpq-fe.h:181
char * fieldSep
Definition: libpq-fe.h:185
#define malloc(a)
Definition: header.h:50
#define SIG_IGN
Definition: win32.h:185
void(* pqsigfunc)(int signo)
Definition: port.h:473
pqbool align
Definition: libpq-fe.h:180
char * caption
Definition: libpq-fe.h:187
pqbool pager
Definition: libpq-fe.h:184
#define SIGPIPE
Definition: win32.h:193
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
#define free(a)
Definition: header.h:65
#define DEFAULT_FIELD_SEP
#define NULL
Definition: c.h:229
char ** fieldName
Definition: libpq-fe.h:188
pqbool expanded
Definition: libpq-fe.h:183
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:526
pqbool html3
Definition: libpq-fe.h:182
char * tableOpt
Definition: libpq-fe.h:186
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:440
pqbool header
Definition: libpq-fe.h:179
int i
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1182
#define libpq_gettext(x)
Definition: libpq-int.h:682
static void 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:326
int client_encoding
Definition: libpq-int.h:189