25 #include <sys/ioctl.h>
32 #include <sys/termios.h>
41 const int i,
const int j,
const int fs_len,
43 const int nFields,
const char **fieldNames,
44 unsigned char *fieldNotNum,
int *fieldMax,
45 const int fieldMaxLen, FILE *fout);
47 int *fieldMax,
const char **fieldNames,
unsigned char *fieldNotNum,
50 unsigned char *fieldNotNum,
int *fieldMax,
char *border,
52 static void fill(
int length,
int max,
char filler, FILE *fp);
80 unsigned char *fieldNotNum = NULL;
83 const char **fieldNames = NULL;
87 int total_line_length = 0;
91 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
93 bool sigpipe_masked =
false;
96 #if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
101 struct winsize screen_size;
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)
119 for (numFieldName = 0;
123 for (
j = 0;
j < nFields;
j++)
126 const char *s = (
j < numFieldName && po->
fieldName[
j][0]) ?
130 len = s ? strlen(s) : 0;
133 if (
len > fieldMaxLen)
135 total_line_length +=
len;
138 total_line_length += nFields * strlen(po->
fieldSep) + 1;
142 if (po->
pager && fout ==
stdout && isatty(fileno(stdin)) &&
150 if (ioctl(fileno(
stdout), TIOCGWINSZ, &screen_size) == -1 ||
151 screen_size.ws_col == 0 ||
152 screen_size.ws_row == 0)
154 screen_size.ws_row = 24;
155 screen_size.ws_col = 80;
158 screen_size.ws_row = 24;
159 screen_size.ws_col = 80;
168 pagerenv = getenv(
"PAGER");
170 if (pagerenv != NULL &&
171 strspn(pagerenv,
" \t\r\n") != strlen(pagerenv) &&
174 nTups * (nFields + 1) >= screen_size.ws_row) ||
176 nTups * (total_line_length / screen_size.ws_col + 1) *
177 (1 + (po->
standard != 0)) >= screen_size.ws_row -
179 (total_line_length / screen_size.ws_col + 1) * 2
183 fout = popen(pagerenv,
"w");
188 #ifdef ENABLE_THREAD_SAFETY
189 if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
190 sigpipe_masked =
true;
203 fields = (
char **)
calloc((
size_t) nTups + 1,
204 nFields *
sizeof(
char *));
225 for (
j = 0;
j < nFields;
j++)
227 const char *s = fieldNames[
j];
230 len += strlen(s) + fs_len;
231 if ((
j + 1) < nFields)
235 for (
len -= fs_len;
len--; fputc(
'-', fout));
246 "Query retrieved %d rows * %d fields"
250 for (
i = 0;
i < nTups;
i++)
256 "<table %s><caption align=\"top\">%d</caption>\n",
261 for (
j = 0;
j < nFields;
j++)
264 fieldNames, fieldNotNum,
265 fieldMax, fieldMaxLen, fout))
269 fputs(
"</table>\n", fout);
279 "<table %s><caption align=\"top\">%s</caption>\n",
284 "<table %s><caption align=\"top\">"
285 "Retrieved %d rows * %d fields"
293 border =
do_header(fout, po, nFields, fieldMax, fieldNames,
294 fieldNotNum, fs_len,
res);
295 for (
i = 0;
i < nTups;
i++)
297 fieldNotNum, fieldMax, border,
i);
303 fputs(
"</table>\n", fout);
315 size_t numfields = ((size_t) nTups + 1) * (size_t) nFields;
317 while (numfields-- > 0)
319 if (fields[numfields])
320 free(fields[numfields]);
325 free((
void *) fieldNames);
333 #ifdef ENABLE_THREAD_SAFETY
336 pq_reset_sigpipe(&osigset, sigpipe_pending,
true);
348 const int i,
const int j,
const int fs_len,
350 const int nFields,
char const **fieldNames,
351 unsigned char *fieldNotNum,
int *fieldMax,
352 const int fieldMaxLen, FILE *fout)
362 if (plen < 1 || !pval || !*pval)
377 if (po->
align && !fieldNotNum[
j])
385 if (!((ch >=
'0' && ch <=
'9') ||
402 if (*pval ==
'E' || *pval ==
'e' ||
403 !(ch >=
'0' && ch <=
'9'))
409 if (plen > fieldMax[
j])
411 if (!(fields[
i * nFields +
j] = (
char *)
malloc(plen + 1)))
416 strcpy(fields[
i * nFields +
j], pval);
424 "<tr><td align=\"left\"><b>%s</b></td>"
425 "<td align=\"%s\">%s</td></tr>\n",
427 fieldNotNum[
j] ?
"left" :
"right",
434 fieldMaxLen - fs_len, fieldNames[
j],
449 if ((
j + 1) < nFields)
463 const char **fieldNames,
unsigned char *fieldNotNum,
477 for (; n < nFields; n++)
478 tot += fieldMax[n] + fs_len + (po->
standard ? 2 : 0);
480 tot += fs_len * 2 + 2;
495 for (
j = 0;
j < nFields;
j++)
514 for (
j = 0;
j < nFields;
j++)
520 fprintf(fout,
"<th align=\"%s\">%s</th>",
521 fieldNotNum[
j] ?
"left" :
"right", fieldNames[
j]);
531 fieldNotNum[
j] ?
" %-*s " :
" %*s ",
534 fprintf(fout, fieldNotNum[
j] ?
"%-*s" :
"%*s", fieldMax[
j], s);
540 fputs(
"</tr>\n", fout);
542 fprintf(fout,
"\n%s\n", border);
549 unsigned char *fieldNotNum,
int *fieldMax,
char *border,
558 for (field_index = 0; field_index < nFields; field_index++)
560 char *p = fields[row_index * nFields + field_index];
563 fprintf(fout,
"<td align=\"%s\">%s</td>",
564 fieldNotNum[field_index] ?
"left" :
"right", p ? p :
"");
568 fieldNotNum[field_index] ?
569 (po->
standard ?
" %-*s " :
"%-*s") :
571 fieldMax[field_index],
573 if (po->
standard || field_index + 1 < nFields)
578 fputs(
"</tr>", fout);
594 const char *fieldSep,
599 #define DEFAULT_FIELD_SEP " "
607 if (fieldSep == NULL)
621 fLength = (
int *)
malloc(nFields *
sizeof(
int));
628 for (
j = 0;
j < nFields;
j++)
631 for (
i = 0;
i < nTuples;
i++)
635 if (flen > fLength[
j])
644 for (
i = 0;
i < nFields;
i++)
654 for (
i = 0;
i < nFields;
i++)
657 fill(0, fLength[
i],
'-', fp);
664 for (
i = 0;
i < nTuples;
i++)
666 for (
j = 0;
j < nFields;
j++)
700 char formatString[80];
701 char *tborder = NULL;
707 sprintf(formatString,
"%%s %%-%ds", colWidth);
709 sprintf(formatString,
"%%s %%s");
718 width = nFields * 14;
719 tborder = (
char *)
malloc(width + 1);
725 for (
i = 0;
i < width;
i++)
727 tborder[width] =
'\0';
728 fprintf(fout,
"%s\n", tborder);
731 for (
i = 0;
i < nFields;
i++)
736 TerseOutput ?
"" :
"|",
746 fprintf(fout,
"|\n%s\n", tborder);
749 for (
i = 0;
i < nTups;
i++)
751 for (
j = 0;
j < nFields;
j++)
756 TerseOutput ?
"" :
"|",
762 fprintf(fout,
"|\n%s\n", tborder);
774 fill(
int length,
int max,
char filler, FILE *fp)
778 count = max - length;
static void PGresult * res
int PQgetlength(const PGresult *res, int tup_num, int field_num)
int PQntuples(const PGresult *res)
char * PQfname(const PGresult *res, int field_num)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
int PQnfields(const PGresult *res)
int PQmblenBounded(const char *s, int encoding)
void PQdisplayTuples(const PGresult *res, FILE *fp, int fillAlign, const char *fieldSep, int printHeader, int quiet)
static void fill(int length, int max, char filler, FILE *fp)
#define DEFAULT_FIELD_SEP
void PQprintTuples(const PGresult *res, FILE *fout, int PrintAttNames, int TerseOutput, int colWidth)
void PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
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 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 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 const char fflush(stdout)
void(* pqsigfunc)(int signo)
pqsigfunc pqsignal(int signum, pqsigfunc handler)