1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-23 14:01:44 +03:00

psql cleanup

This commit is contained in:
Bruce Momjian
1999-11-04 23:14:30 +00:00
parent 2323b63631
commit 0e6652e673
29 changed files with 5255 additions and 8040 deletions

View File

@ -35,8 +35,7 @@
/* functions for use in this file only */
static backslashResult
exec_command(const char * cmd,
static backslashResult exec_command(const char *cmd,
char *const * options,
const char *options_string,
PQExpBuffer query_buf,
@ -84,32 +83,40 @@ HandleSlashCmds(PsqlSettings *pset,
const char *cmd;
size_t blank_loc;
int i;
const char * continue_parse = NULL; /* tell the mainloop where the backslash command ended */
const char *continue_parse = NULL; /* tell the mainloop where the
* backslash command ended */
my_line = xstrdup(line);
/* Find the first whitespace (or backslash)
line[blank_loc] will now be the whitespace character
or the \0 at the end */
/*
* Find the first whitespace (or backslash) line[blank_loc] will now
* be the whitespace character or the \0 at the end
*/
blank_loc = strcspn(my_line, " \t");
/* do we have an option string? */
if (my_line[blank_loc] != '\0') {
if (my_line[blank_loc] != '\0')
{
options_string = &my_line[blank_loc + 1];
my_line[blank_loc] = '\0';
}
if (options_string) {
if (options_string)
{
char quote;
unsigned int pos;
options_string = &options_string[strspn(options_string, " \t")]; /* skip leading whitespace */
options_string = &options_string[strspn(options_string, " \t")]; /* skip leading
* whitespace */
i = 0;
token = strtokx(options_string, " \t", "\"'`", '\\', &quote, &pos);
for (i = 0; token && i<16; i++) {
switch(quote) {
for (i = 0; token && i < 16; i++)
{
switch (quote)
{
case '"':
options[i] = unescape(token, pset);
break;
@ -126,17 +133,21 @@ HandleSlashCmds(PsqlSettings *pset,
size_t result;
fd = popen(file, "r");
if (!fd) {
if (!fd)
{
perror(file);
error = true;
}
if (!error) {
if (!error)
{
initPQExpBuffer(&output);
do {
do
{
result = fread(buf, 1, 512, fd);
if (ferror(fd)) {
if (ferror(fd))
{
perror(file);
error = true;
break;
@ -145,13 +156,15 @@ HandleSlashCmds(PsqlSettings *pset,
} while (!feof(fd));
appendPQExpBufferChar(&output, '\0');
if (pclose(fd) == -1) {
if (pclose(fd) == -1)
{
perror(file);
error = true;
}
}
if (!error) {
if (!error)
{
if (output.data[strlen(output.data) - 1] == '\n')
output.data[strlen(output.data) - 1] = '\0';
}
@ -159,7 +172,8 @@ HandleSlashCmds(PsqlSettings *pset,
free(file);
if (!error)
options[i] = output.data;
else {
else
{
options[i] = xstrdup("");
termPQExpBuffer(&output);
}
@ -187,11 +201,15 @@ HandleSlashCmds(PsqlSettings *pset,
status = exec_command(cmd, options, options_string, query_buf, pset);
if (status == CMD_UNKNOWN) {
/* If the command was not recognized, try inserting a space after
the first letter and call again. The one letter commands
allow arguments to start immediately after the command,
but that is no longer encouraged. */
if (status == CMD_UNKNOWN)
{
/*
* If the command was not recognized, try inserting a space after
* the first letter and call again. The one letter commands allow
* arguments to start immediately after the command, but that is
* no longer encouraged.
*/
const char *new_options[17];
char new_cmd[2];
int i;
@ -206,7 +224,8 @@ HandleSlashCmds(PsqlSettings *pset,
status = exec_command(new_cmd, (char *const *) new_options, my_line + 2, query_buf, pset);
}
if (status == CMD_UNKNOWN) {
if (status == CMD_UNKNOWN)
{
fprintf(stderr, "Unrecognized command: \\%s. Try \\? for help.\n", cmd);
status = CMD_ERROR;
}
@ -215,7 +234,8 @@ HandleSlashCmds(PsqlSettings *pset,
continue_parse += 2;
if (end_of_cmd) {
if (end_of_cmd)
{
if (continue_parse)
*end_of_cmd = line + (continue_parse - my_line);
else
@ -241,15 +261,19 @@ exec_command(const char * cmd,
PQExpBuffer query_buf,
PsqlSettings *pset)
{
bool success = true; /* indicate here if the command ran ok or failed */
bool success = true; /* indicate here if the command ran ok or
* failed */
bool quiet = GetVariableBool(pset->vars, "quiet");
backslashResult status = CMD_SKIP_LINE;
/* \a -- toggle field alignment
This is deprecated and makes no sense, but we keep it around. */
if (strcmp(cmd, "a") == 0) {
/*
* \a -- toggle field alignment This is deprecated and makes no sense,
* but we keep it around.
*/
if (strcmp(cmd, "a") == 0)
{
if (pset->popt.topt.format != PRINT_ALIGNED)
success = do_pset("format", "aligned", &pset->popt, quiet);
else
@ -257,30 +281,36 @@ exec_command(const char * cmd,
}
/* \C -- override table title
(formerly change HTML caption) This is deprecated. */
/*
* \C -- override table title (formerly change HTML caption) This is
* deprecated.
*/
else if (strcmp(cmd, "C") == 0)
success = do_pset("title", options[0], &pset->popt, quiet);
/* \c or \connect -- connect to new database or as different user
/*
* \c or \connect -- connect to new database or as different user
*
* \c foo bar : connect to db "foo" as user "bar"
* \c foo [-] : connect to db "foo" as current user
* \c - bar : connect to current db as user "bar"
* \c : connect to default db as default user
* \c foo bar : connect to db "foo" as user "bar" \c foo [-] :
* connect to db "foo" as current user \c - bar : connect to
* current db as user "bar" \c : connect to default db as
* default user
*/
else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
{
if (options[1])
/* gave username */
success = do_connect(options[0], options[1], pset);
else {
else
{
if (options[0])
/* gave database name */
success = do_connect(options[0], "", pset); /* empty string is same username as before,
NULL would mean libpq default */
success = do_connect(options[0], "", pset); /* empty string is same
* username as before,
* NULL would mean libpq
* default */
else
/* connect to default db as default user */
success = do_connect(NULL, NULL, pset);
@ -297,13 +327,16 @@ exec_command(const char * cmd,
print_copyright();
/* \d* commands */
else if (cmd[0] == 'd') {
switch(cmd[1]) {
else if (cmd[0] == 'd')
{
switch (cmd[1])
{
case '\0':
if (options[0])
success = describeTableDetails(options[0], pset);
else
success = listTables("tvs", NULL, pset); /* standard listing of interesting things */
success = listTables("tvs", NULL, pset); /* standard listing of
* interesting things */
break;
case 'a':
success = describeAggregates(options[0], pset);
@ -326,7 +359,11 @@ exec_command(const char * cmd,
case 'T':
success = describeTypes(options[0], pset);
break;
case 't': case 'v': case 'i': case 's': case 'S':
case 't':
case 'v':
case 'i':
case 's':
case 'S':
if (cmd[1] == 'S' && cmd[2] == '\0')
success = listTables("Stvs", NULL, pset);
else
@ -338,28 +375,35 @@ exec_command(const char * cmd,
}
/* \e or \edit -- edit the current query buffer (or a file and make it the
query buffer */
/*
* \e or \edit -- edit the current query buffer (or a file and make it
* the query buffer
*/
else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
status = do_edit(options[0], query_buf) ? CMD_NEWEDIT : CMD_ERROR;
/* \echo */
else if (strcmp(cmd, "echo") == 0) {
else if (strcmp(cmd, "echo") == 0)
{
int i;
for (i = 0; i < 16 && options[i]; i++)
fputs(options[i], stdout);
fputs("\n", stdout);
}
/* \f -- change field separator
(This is deprecated in favour of \pset.) */
/*
* \f -- change field separator (This is deprecated in favour of
* \pset.)
*/
else if (strcmp(cmd, "f") == 0)
success = do_pset("fieldsep", options[0], &pset->popt, quiet);
/* \g means send query */
else if (strcmp(cmd, "g") == 0) {
else if (strcmp(cmd, "g") == 0)
{
if (!options[0])
pset->gfname = NULL;
else
@ -380,7 +424,8 @@ exec_command(const char * cmd,
/* \i is include file */
else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
{
if (!options[0]) {
if (!options[0])
{
fputs("Usage: \\i <filename>\n", stderr);
success = false;
}
@ -394,9 +439,12 @@ exec_command(const char * cmd,
/* large object things */
else if (strncmp(cmd, "lo_", 3)==0) {
if (strcmp(cmd+3, "export") == 0) {
if (!options[1]) {
else if (strncmp(cmd, "lo_", 3) == 0)
{
if (strcmp(cmd + 3, "export") == 0)
{
if (!options[1])
{
fputs("Usage: \\lo_export <loid> <filename>\n", stderr);
success = false;
}
@ -404,8 +452,10 @@ exec_command(const char * cmd,
success = do_lo_export(pset, options[0], options[1]);
}
else if (strcmp(cmd+3, "import") == 0) {
if (!options[0]) {
else if (strcmp(cmd + 3, "import") == 0)
{
if (!options[0])
{
fputs("Usage: \\lo_import <filename> [<description>]\n", stderr);
success = false;
}
@ -416,8 +466,10 @@ exec_command(const char * cmd,
else if (strcmp(cmd + 3, "list") == 0)
success = do_lo_list(pset);
else if (strcmp(cmd+3, "unlink") == 0) {
if (!options[0]) {
else if (strcmp(cmd + 3, "unlink") == 0)
{
if (!options[0])
{
fputs("Usage: \\lo_unlink <loid>\n", stderr);
success = false;
}
@ -444,8 +496,10 @@ exec_command(const char * cmd,
}
/* \pset -- set printing parameters */
else if (strcmp(cmd, "pset")==0) {
if (!options[0]) {
else if (strcmp(cmd, "pset") == 0)
{
if (!options[0])
{
fputs("Usage: \\pset <parameter> [<value>]\n", stderr);
success = false;
}
@ -458,8 +512,10 @@ exec_command(const char * cmd,
status = CMD_TERMINATE;
/* \qecho */
else if (strcmp(cmd, "qecho") == 0) {
else if (strcmp(cmd, "qecho") == 0)
{
int i;
for (i = 0; i < 16 && options[i]; i++)
fputs(options[i], pset->queryFout);
fputs("\n", pset->queryFout);
@ -469,7 +525,8 @@ exec_command(const char * cmd,
else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
{
resetPQExpBuffer(query_buf);
if (!quiet) puts("Query buffer reset (cleared).");
if (!quiet)
puts("Query buffer reset (cleared).");
}
@ -477,6 +534,7 @@ exec_command(const char * cmd,
else if (strcmp(cmd, "s") == 0)
{
const char *fname;
if (!options[0])
fname = "/dev/tty";
else
@ -492,17 +550,24 @@ exec_command(const char * cmd,
/* \set -- generalized set option command */
else if (strcmp(cmd, "set") == 0)
{
if (!options[0]) {
if (!options[0])
{
/* list all variables */
/* (This is in utter violation of the GetVariable abstraction, but
I have not dreamt up a better way.) */
/*
* (This is in utter violation of the GetVariable abstraction,
* but I have not dreamt up a better way.)
*/
struct _variable *ptr;
for (ptr = pset->vars; ptr->next; ptr = ptr->next)
fprintf(stdout, "%s = '%s'\n", ptr->next->name, ptr->next->value);
success = true;
}
else {
if (!SetVariable(pset->vars, options[0], options[1])) {
else
{
if (!SetVariable(pset->vars, options[0], options[1]))
{
fprintf(stderr, "Set variable failed.\n");
success = false;
}
@ -525,12 +590,15 @@ exec_command(const char * cmd,
FILE *fd = NULL;
bool pipe = false;
if (!options[0]) {
if (!options[0])
{
fprintf(stderr, "Usage \\%s <filename>\n", cmd);
success = false;
}
else {
if (options[0][0] == '|') {
else
{
if (options[0][0] == '|')
{
pipe = true;
#ifndef __CYGWIN32__
fd = popen(&options[0][1], "w");
@ -538,7 +606,8 @@ exec_command(const char * cmd,
fd = popen(&options[0][1], "wb");
#endif
}
else {
else
{
#ifndef __CYGWIN32__
fd = fopen(options[0], "w");
#else
@ -546,13 +615,15 @@ exec_command(const char * cmd,
#endif
}
if (!fd) {
if (!fd)
{
perror(options[0]);
success = false;
}
}
if (fd) {
if (fd)
{
int result;
if (query_buf && query_buf->len > 0)
@ -563,7 +634,8 @@ exec_command(const char * cmd,
else
result = fclose(fd);
if (result == EOF) {
if (result == EOF)
{
perror("close");
success = false;
}
@ -588,21 +660,26 @@ exec_command(const char * cmd,
#ifdef NOT_USED
/* These commands don't do anything. I just use them to test the parser. */
/*
* These commands don't do anything. I just use them to test the
* parser.
*/
else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
{
int i;
fprintf(stderr, "+ optline = |%s|\n", options_string);
for (i = 0; options[i]; i++)
fprintf(stderr, "+ opt%d = |%s|\n", i, options[i]);
}
#endif
else {
else
status = CMD_UNKNOWN;
}
if (!success) status = CMD_ERROR;
if (!success)
status = CMD_ERROR;
return status;
}
@ -620,9 +697,10 @@ static char *
unescape(const char *source, PsqlSettings *pset)
{
unsigned char *p;
bool esc = false; /* Last character we saw was the
escape character */
char *destination, *tmp;
bool esc = false; /* Last character we saw was the escape
* character */
char *destination,
*tmp;
size_t length;
#ifdef USE_ASSERT_CHECKING
@ -632,13 +710,16 @@ unescape(const char * source, PsqlSettings * pset)
length = strlen(source) + 1;
tmp = destination = (char *) malloc(length);
if (!tmp) {
if (!tmp)
{
perror("malloc");
exit(EXIT_FAILURE);
}
for (p = (char *) source; *p; p += PQmblen(p)) {
if (esc) {
for (p = (char *) source; *p; p += PQmblen(p))
{
if (esc)
{
char c;
switch (*p)
@ -655,11 +736,20 @@ unescape(const char * source, PsqlSettings * pset)
case 'f':
c = '\f';
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
long int l;
char *end;
l = strtol(p, &end, 0);
c = l;
p = end - 1;
@ -672,17 +762,18 @@ unescape(const char * source, PsqlSettings * pset)
esc = false;
}
else if (*p == '\\') {
else if (*p == '\\')
esc = true;
}
else if (*p == '$')
{
if (*(p+1) == '{') {
if (*(p + 1) == '{')
{
unsigned int len;
char *copy;
const char *value;
void *new;
len = strcspn(p + 2, "}");
copy = xstrdup(p + 2);
copy[len] = '\0';
@ -690,7 +781,8 @@ unescape(const char * source, PsqlSettings * pset)
length += strlen(value) - (len + 3);
new = realloc(destination, length);
if (!new) {
if (!new)
{
perror("realloc");
exit(EXIT_FAILURE);
}
@ -702,12 +794,12 @@ unescape(const char * source, PsqlSettings * pset)
p += len + 2;
free(copy);
}
else {
else
*tmp++ = '$';
}
}
else {
else
{
*tmp++ = *p;
esc = false;
}
@ -749,9 +841,8 @@ do_connect(const char *new_dbname, const char *new_user, PsqlSettings * pset)
dbparam = new_dbname;
/* If user is "" or "-" then use the old one */
if ( new_user && PQuser(oldconn) && ( strcmp(new_user, "")==0 || strcmp(new_user, "-")==0 || strcmp(new_user, PQuser(oldconn))==0 )) {
if (new_user && PQuser(oldconn) && (strcmp(new_user, "") == 0 || strcmp(new_user, "-") == 0 || strcmp(new_user, PQuser(oldconn)) == 0))
userparam = PQuser(oldconn);
}
/* If username is "?" then prompt */
else if (new_user && strcmp(new_user, "?") == 0)
userparam = prompted_user = simple_prompt("Username: ", 100, true); /* save for free() */
@ -760,33 +851,39 @@ do_connect(const char *new_dbname, const char *new_user, PsqlSettings * pset)
/* need to prompt for password? */
if (pset->getPassword)
pwparam = prompted_password = simple_prompt("Password: ", 100, false); /* need to save for free() */
pwparam = prompted_password = simple_prompt("Password: ", 100, false); /* need to save for
* free() */
/* Use old password if no new one given (if you didn't have an old one, fine) */
/*
* Use old password if no new one given (if you didn't have an old
* one, fine)
*/
if (!pwparam)
pwparam = PQpass(oldconn);
#ifdef MULTIBYTE
/*
* PGCLIENTENCODING may be set by the previous connection. if a
* user does not explicitly set PGCLIENTENCODING, we should
* discard PGCLIENTENCODING so that libpq could get the backend
* encoding as the default PGCLIENTENCODING value. -- 1998/12/12
* Tatsuo Ishii
* PGCLIENTENCODING may be set by the previous connection. if a user
* does not explicitly set PGCLIENTENCODING, we should discard
* PGCLIENTENCODING so that libpq could get the backend encoding as
* the default PGCLIENTENCODING value. -- 1998/12/12 Tatsuo Ishii
*/
if (!pset->has_client_encoding)
putenv("PGCLIENTENCODING=");
#endif
do {
do
{
need_pass = false;
pset->db = PQsetdbLogin(PQhost(oldconn), PQport(oldconn),
NULL, NULL, dbparam, userparam, pwparam);
if (PQstatus(pset->db) == CONNECTION_BAD &&
strcmp(PQerrorMessage(pset->db), "fe_sendauth: no password supplied\n")==0) {
strcmp(PQerrorMessage(pset->db), "fe_sendauth: no password supplied\n") == 0)
{
need_pass = true;
free(prompted_password);
prompted_password = NULL;
@ -797,32 +894,38 @@ do_connect(const char *new_dbname, const char *new_user, PsqlSettings * pset)
free(prompted_password);
free(prompted_user);
/* If connection failed, try at least keep the old one.
That's probably more convenient than just kicking you out of the
program. */
/*
* If connection failed, try at least keep the old one. That's
* probably more convenient than just kicking you out of the program.
*/
if (!pset->db || PQstatus(pset->db) == CONNECTION_BAD)
{
fprintf(stderr, "Could not establish database connection.\n%s", PQerrorMessage(pset->db));
PQfinish(pset->db);
if (!oldconn || !pset->cur_cmd_interactive) { /* we don't want unpredictable things to happen
in scripting mode */
if (!oldconn || !pset->cur_cmd_interactive)
{ /* we don't want unpredictable things to
* happen in scripting mode */
fputs("Terminating.\n", stderr);
if (oldconn)
PQfinish(oldconn);
pset->db = NULL;
}
else {
else
{
fputs("Keeping old connection.\n", stderr);
pset->db = oldconn;
}
}
else {
if (!GetVariable(pset->vars, "quiet")) {
else
{
if (!GetVariable(pset->vars, "quiet"))
{
if (userparam != new_user) /* no new user */
printf("You are now connected to database %s.\n", dbparam);
else if (dbparam != new_dbname) /* no new db */
printf("You are now connected as new user %s.\n", new_user);
else /* both new */
else
/* both new */
printf("You are now connected to database %s as user %s.\n",
PQdb(pset->db), PQuser(pset->db));
}
@ -855,7 +958,8 @@ editFile(const char *fname)
#ifdef USE_ASSERT_CHECKING
assert(fname);
#else
if (!fname) return false;
if (!fname)
return false;
#endif
/* Find an editor to use */
@ -888,21 +992,26 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
FILE *stream;
const char *fname;
bool error = false;
#ifndef WIN32
struct stat before, after;
struct stat before,
after;
#endif
#ifdef USE_ASSERT_CHECKING
assert(query_buf);
#else
if (!query_buf) return false;
if (!query_buf)
return false;
#endif
if (filename_arg)
fname = filename_arg;
else {
else
{
/* make a temp file to edit */
#ifndef WIN32
mode_t oldumask;
@ -921,18 +1030,23 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
umask(oldumask);
#endif
if (!stream) {
if (!stream)
{
perror(fname);
error = true;
}
else {
else
{
unsigned int ql = query_buf->len;
if (ql == 0 || query_buf->data[ql - 1] != '\n') {
if (ql == 0 || query_buf->data[ql - 1] != '\n')
{
appendPQExpBufferChar(query_buf, '\n');
ql++;
}
if (fwrite(query_buf->data, 1, ql, stream) != ql) {
if (fwrite(query_buf->data, 1, ql, stream) != ql)
{
perror(fname);
fclose(stream);
remove(fname);
@ -944,7 +1058,8 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
}
#ifndef WIN32
if (!error && stat(fname, &before) != 0) {
if (!error && stat(fname, &before) != 0)
{
perror(fname);
error = true;
}
@ -955,29 +1070,36 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
error = !editFile(fname);
#ifndef WIN32
if (!error && stat(fname, &after) !=0) {
if (!error && stat(fname, &after) != 0)
{
perror(fname);
error = true;
}
if (!error && before.st_mtime != after.st_mtime) {
if (!error && before.st_mtime != after.st_mtime)
{
#else
if (!error) {
if (!error)
{
#endif
stream = fopen(fname, "r");
if (!stream) {
if (!stream)
{
perror(fname);
error = true;
}
else {
else
{
/* read file back in */
char line[1024];
size_t result;
resetPQExpBuffer(query_buf);
do {
do
{
result = fread(line, 1, 1024, stream);
if (ferror(stream)) {
if (ferror(stream))
{
perror(fname);
error = true;
break;
@ -1020,7 +1142,8 @@ process_file(const char *filename, PsqlSettings *pset)
fd = fopen(filename, "r");
#endif
if (!fd) {
if (!fd)
{
perror(filename);
return false;
}
@ -1039,7 +1162,8 @@ process_file(const char *filename, PsqlSettings *pset)
static const char *
_align2string(enum printFormat in)
{
switch (in) {
switch (in)
{
case PRINT_NOTHING:
return "nothing";
break;
@ -1064,17 +1188,20 @@ bool
do_pset(const char *param, const char *value, printQueryOpt * popt, bool quiet)
{
size_t vallen = 0;
#ifdef USE_ASSERT_CHECKING
assert(param);
#else
if (!param) return false;
if (!param)
return false;
#endif
if (value)
vallen = strlen(value);
/* set format */
if (strcmp(param, "format")==0) {
if (strcmp(param, "format") == 0)
{
if (!value)
;
else if (strncasecmp("unaligned", value, vallen) == 0)
@ -1085,7 +1212,8 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
popt->topt.format = PRINT_HTML;
else if (strncasecmp("latex", value, vallen) == 0)
popt->topt.format = PRINT_LATEX;
else {
else
{
fprintf(stderr, "Allowed formats are unaligned, aligned, html, latex.\n");
return false;
}
@ -1095,7 +1223,8 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
}
/* set border style/width */
else if (strcmp(param, "border")==0) {
else if (strcmp(param, "border") == 0)
{
if (value)
popt->topt.border = atoi(value);
@ -1104,15 +1233,18 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
}
/* set expanded/vertical mode */
else if (strcmp(param, "x")==0 || strcmp(param, "expanded")==0 || strcmp(param, "vertical")==0) {
else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
{
popt->topt.expanded = !popt->topt.expanded;
if (!quiet)
printf("Expanded display is %s.\n", popt->topt.expanded ? "on" : "off");
}
/* null display */
else if (strcmp(param, "null")==0) {
if (value) {
else if (strcmp(param, "null") == 0)
{
if (value)
{
free(popt->nullPrint);
popt->nullPrint = xstrdup(value);
}
@ -1121,8 +1253,10 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
}
/* field separator for unaligned text */
else if (strcmp(param, "fieldsep")==0) {
if (value) {
else if (strcmp(param, "fieldsep") == 0)
{
if (value)
{
free(popt->topt.fieldSep);
popt->topt.fieldSep = xstrdup(value);
}
@ -1131,9 +1265,11 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
}
/* toggle between full and barebones format */
else if (strcmp(param, "t")==0 || strcmp(param, "tuples_only")==0) {
else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
{
popt->topt.tuples_only = !popt->topt.tuples_only;
if (!quiet) {
if (!quiet)
{
if (popt->topt.tuples_only)
puts("Showing only tuples.");
else
@ -1142,14 +1278,16 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
}
/* set title override */
else if (strcmp(param, "title")==0) {
else if (strcmp(param, "title") == 0)
{
free(popt->title);
if (!value)
popt->title = NULL;
else
popt->title = xstrdup(value);
if (!quiet) {
if (!quiet)
{
if (popt->title)
printf("Title is \"%s\".\n", popt->title);
else
@ -1158,14 +1296,16 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
}
/* set HTML table tag options */
else if (strcmp(param, "T")==0 || strcmp(param, "tableattr")==0) {
else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
{
free(popt->topt.tableAttr);
if (!value)
popt->topt.tableAttr = NULL;
else
popt->topt.tableAttr = xstrdup(value);
if (!quiet) {
if (!quiet)
{
if (popt->topt.tableAttr)
printf("Table attribute is \"%s\".\n", popt->topt.tableAttr);
else
@ -1174,9 +1314,11 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
}
/* toggle use of pager */
else if (strcmp(param, "pager")==0) {
else if (strcmp(param, "pager") == 0)
{
popt->topt.pager = !popt->topt.pager;
if (!quiet) {
if (!quiet)
{
if (popt->topt.pager)
puts("Using pager is on.");
else
@ -1185,7 +1327,8 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
}
else {
else
{
fprintf(stderr, "Unknown option: %s\n", param);
return false;
}
@ -1202,7 +1345,8 @@ do_shell(const char *command)
{
int result;
if (!command) {
if (!command)
{
char *sys;
char *shellName;
@ -1220,7 +1364,8 @@ do_shell(const char *command)
else
result = system(command);
if (result==127 || result==-1) {
if (result == 127 || result == -1)
{
perror("system");
return false;
}

View File

@ -11,36 +11,33 @@
typedef enum _backslashResult {
typedef enum _backslashResult
{
CMD_UNKNOWN = 0, /* not done parsing yet (internal only) */
CMD_SEND, /* query complete; send off */
CMD_SKIP_LINE, /* keep building query */
CMD_TERMINATE, /* quit program */
CMD_NEWEDIT, /* query buffer was changed (e.g., via \e) */
CMD_ERROR /* the execution of the backslash command resulted
in an error */
CMD_ERROR /* the execution of the backslash command
* resulted in an error */
} backslashResult;
backslashResult
HandleSlashCmds(PsqlSettings *pset,
backslashResult HandleSlashCmds(PsqlSettings *pset,
const char *line,
PQExpBuffer query_buf,
const char **end_of_cmd);
bool
do_connect(const char *new_dbname,
bool do_connect(const char *new_dbname,
const char *new_user,
PsqlSettings *pset);
bool
process_file(const char *filename,
bool process_file(const char *filename,
PsqlSettings *pset);
bool
do_pset(const char * param,
bool do_pset(const char *param,
const char *value,
printQueryOpt * popt,
bool quiet);

View File

@ -39,15 +39,19 @@
* "Safe" wrapper around strdup()
* (Using this also avoids writing #ifdef HAVE_STRDUP in every file :)
*/
char * xstrdup(const char * string)
char *
xstrdup(const char *string)
{
char *tmp;
if (!string) {
if (!string)
{
fprintf(stderr, "xstrdup: Cannot duplicate null pointer.\n");
exit(EXIT_FAILURE);
}
tmp = strdup(string);
if (!tmp) {
if (!tmp)
{
perror("strdup");
exit(EXIT_FAILURE);
}
@ -72,7 +76,8 @@ setQFout(const char *fname, PsqlSettings *pset)
#ifdef USE_ASSERT_CHECKING
assert(pset);
#else
if (!pset) return false;
if (!pset)
return false;
#endif
/* Close old file/pipe */
@ -150,13 +155,16 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
char *destination;
#ifdef HAVE_TERMIOS_H
struct termios t_orig, t;
struct termios t_orig,
t;
#endif
destination = (char *) malloc(maxlen + 2);
if (!destination)
return NULL;
if (prompt) fputs(prompt, stdout);
if (prompt)
fputs(prompt, stdout);
#ifdef HAVE_TERMIOS_H
if (!echo)
@ -171,17 +179,21 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
fgets(destination, maxlen, stdin);
#ifdef HAVE_TERMIOS_H
if (!echo) {
if (!echo)
{
tcsetattr(0, TCSADRAIN, &t_orig);
puts("");
}
#endif
length = strlen(destination);
if (length > 0 && destination[length - 1] != '\n') {
if (length > 0 && destination[length - 1] != '\n')
{
/* eat rest of the line */
char buf[512];
do {
do
{
fgets(buf, 512, stdin);
} while (buf[strlen(buf) - 1] != '\n');
}
@ -213,10 +225,12 @@ interpolate_var(const char * name, PsqlSettings * pset)
assert(name);
assert(pset);
#else
if (!name || !pset) return NULL;
if (!name || !pset)
return NULL;
#endif
if (strspn(name, VALID_VARIABLE_CHARS) == strlen(name)) {
if (strspn(name, VALID_VARIABLE_CHARS) == strlen(name))
{
var = GetVariable(pset->vars, name);
if (var)
return var;
@ -225,41 +239,50 @@ interpolate_var(const char * name, PsqlSettings * pset)
}
/* otherwise return magic variable */
/* (by convention these should be capitalized (but not all caps), to not be
shadowed by regular vars or to shadow env vars) */
/*
* (by convention these should be capitalized (but not all caps), to
* not be shadowed by regular vars or to shadow env vars)
*/
if (strcmp(name, "Version") == 0)
return PG_VERSION_STR;
if (strcmp(name, "Database")==0) {
if (strcmp(name, "Database") == 0)
{
if (PQdb(pset->db))
return PQdb(pset->db);
else
return "";
}
if (strcmp(name, "User")==0) {
if (strcmp(name, "User") == 0)
{
if (PQuser(pset->db))
return PQuser(pset->db);
else
return "";
}
if (strcmp(name, "Host")==0) {
if (strcmp(name, "Host") == 0)
{
if (PQhost(pset->db))
return PQhost(pset->db);
else
return "";
}
if (strcmp(name, "Port")==0) {
if (strcmp(name, "Port") == 0)
{
if (PQport(pset->db))
return PQport(pset->db);
else
return "";
}
/* env vars (if env vars are all caps there should be no prob, otherwise
you're on your own */
/*
* env vars (if env vars are all caps there should be no prob,
* otherwise you're on your own
*/
if ((var = getenv(name)))
return var;
@ -302,7 +325,8 @@ handle_sigint(SIGNAL_ARGS)
/* Try to send cancel request */
if (PQrequestCancel(cancelConn))
safe_write_stderr("\nCANCEL request sent\n");
else {
else
{
safe_write_stderr("\nCould not send cancel request: ");
safe_write_stderr(PQerrorMessage(cancelConn));
}
@ -322,13 +346,15 @@ PSQLexec(PsqlSettings *pset, const char *query)
PGresult *res;
const char *var;
if (!pset->db) {
if (!pset->db)
{
fputs("You are not currently connected to a database.\n", stderr);
return NULL;
}
var = GetVariable(pset->vars, "echo_secret");
if (var) {
if (var)
{
printf("********* QUERY *********\n%s\n*************************\n\n", query);
fflush(stdout);
}
@ -347,7 +373,8 @@ PSQLexec(PsqlSettings *pset, const char *query)
{
fputs("The connection to the server was lost. Attempting reset: ", stderr);
PQreset(pset->db);
if (PQstatus(pset->db) == CONNECTION_BAD) {
if (PQstatus(pset->db) == CONNECTION_BAD)
{
fputs("Failed.\n", stderr);
PQfinish(pset->db);
PQclear(res);
@ -364,7 +391,8 @@ PSQLexec(PsqlSettings *pset, const char *query)
PQresultStatus(res) == PGRES_COPY_OUT)
)
return res;
else {
else
{
fprintf(stderr, "%s", PQerrorMessage(pset->db));
PQclear(res);
return NULL;
@ -392,13 +420,16 @@ SendQuery(PsqlSettings *pset, const char *query)
PGresult *results;
PGnotify *notify;
if (!pset->db) {
if (!pset->db)
{
fputs("You are not currently connected to a database.\n", stderr);
return false;
}
if (GetVariableBool(pset->vars, "singlestep")) {
if (GetVariableBool(pset->vars, "singlestep"))
{
char buf[3];
fprintf(stdout, "***(Single step mode: Verify query)*********************************************\n"
"QUERY: %s\n"
"***(press return to proceed or enter x and return to cancel)********************\n",
@ -432,7 +463,8 @@ SendQuery(PsqlSettings *pset, const char *query)
PsqlSettings settings_copy = *pset;
settings_copy.queryFout = stdout;
if (!setQFout(pset->gfname, &settings_copy)) {
if (!setQFout(pset->gfname, &settings_copy))
{
success = false;
break;
}
@ -491,7 +523,8 @@ SendQuery(PsqlSettings *pset, const char *query)
{
fputs("The connection to the server was lost. Attempting reset: ", stderr);
PQreset(pset->db);
if (PQstatus(pset->db) == CONNECTION_BAD) {
if (PQstatus(pset->db) == CONNECTION_BAD)
{
fputs("Failed.\n", stderr);
PQfinish(pset->db);
PQclear(results);

View File

@ -33,7 +33,8 @@
* returns a malloc'ed structure with the options, or NULL on parsing error
*/
struct copy_options {
struct copy_options
{
char *table;
char *file;
bool from;
@ -66,7 +67,8 @@ parse_slash_copy(const char *args)
line = xstrdup(args);
if (!(result = calloc(1, sizeof (struct copy_options)))) {
if (!(result = calloc(1, sizeof(struct copy_options))))
{
perror("calloc");
exit(EXIT_FAILURE);
}
@ -74,8 +76,10 @@ parse_slash_copy(const char *args)
token = strtokx(line, " \t", "\"", '\\', &quote, NULL);
if (!token)
error = true;
else {
if (!quote && strcasecmp(token, "binary")==0) {
else
{
if (!quote && strcasecmp(token, "binary") == 0)
{
result->binary = true;
token = strtokx(NULL, " \t", "\"", '\\', &quote, NULL);
if (!token)
@ -89,19 +93,23 @@ parse_slash_copy(const char *args)
assert(error || result->table);
#endif
if (!error) {
if (!error)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
if (!token)
error = true;
else {
if (strcasecmp(token, "with")==0) {
else
{
if (strcasecmp(token, "with") == 0)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
if (!token || strcasecmp(token, "oids") != 0)
error = true;
else
result->oids = true;
if (!error) {
if (!error)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
if (!token)
error = true;
@ -117,7 +125,8 @@ parse_slash_copy(const char *args)
}
}
if (!error) {
if (!error)
{
token = strtokx(NULL, " \t", "'", '\\', NULL, NULL);
if (!token)
error = true;
@ -129,16 +138,20 @@ parse_slash_copy(const char *args)
assert(error || result->file);
#endif
if (!error) {
if (!error)
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
if (token) {
if (token)
{
if (strcasecmp(token, "using") != 0)
error = true;
else {
else
{
token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
if (!token || strcasecmp(token, "delimiters") != 0)
error = true;
else {
else
{
token = strtokx(NULL, " \t", "'", '\\', NULL, NULL);
if (token)
result->delim = xstrdup(token);
@ -151,7 +164,8 @@ parse_slash_copy(const char *args)
free(line);
if (error) {
if (error)
{
fputs("Parse error at ", stderr);
if (!token)
fputs("end of line.", stderr);
@ -204,10 +218,14 @@ do_copy(const char * args, PsqlSettings *pset)
strcat(query, "TO stdout");
if (options->delim) {
/* backend copy only uses the first character here,
but that might be the escape backslash
(makes me wonder though why it's called delimiterS) */
if (options->delim)
{
/*
* backend copy only uses the first character here, but that might
* be the escape backslash (makes me wonder though why it's called
* delimiterS)
*/
strncat(query, " USING DELIMITERS '", 2);
strcat(query, options->delim);
strcat(query, "'");
@ -227,7 +245,8 @@ do_copy(const char * args, PsqlSettings *pset)
copystream = fopen(options->file, "wb");
#endif
if (!copystream) {
if (!copystream)
{
fprintf(stderr,
"Unable to open file %s which to copy: %s\n",
options->from ? "from" : "to", strerror(errno));
@ -258,7 +277,8 @@ do_copy(const char * args, PsqlSettings *pset)
PQclear(result);
if (!GetVariable(pset->vars, "quiet")) {
if (!GetVariable(pset->vars, "quiet"))
{
if (success)
puts("Successfully copied.");
else

View File

@ -36,15 +36,19 @@
bool
describeAggregates(const char *name, PsqlSettings *pset)
{
char descbuf[384 + 2*REGEXP_CUTOFF]; /* observe/adjust this if you change the query */
char descbuf[384 + 2 * REGEXP_CUTOFF]; /* observe/adjust this
* if you change the
* query */
PGresult *res;
bool description = GetVariableBool(pset->vars, "description");
printQueryOpt myopt = pset->popt;
descbuf[0] = '\0';
/* There are two kinds of aggregates: ones that work on particular types
ones that work on all */
/*
* There are two kinds of aggregates: ones that work on particular
* types ones that work on all
*/
strcat(descbuf,
"SELECT a.aggname AS \"Name\", t.typname AS \"Type\"");
if (description)
@ -53,7 +57,8 @@ describeAggregates(const char * name, PsqlSettings * pset)
strcat(descbuf,
"\nFROM pg_aggregate a, pg_type t\n"
"WHERE a.aggbasetype = t.oid\n");
if (name) {
if (name)
{
strcat(descbuf, " AND a.aggname ~* '^");
strncat(descbuf, name, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -103,9 +108,8 @@ describeFunctions(const char * name, PsqlSettings * pset)
printQueryOpt myopt = pset->popt;
/*
* we skip in/out funcs by excluding functions that take
* some arguments, but have no types defined for those
* arguments
* we skip in/out funcs by excluding functions that take some
* arguments, but have no types defined for those arguments
*/
descbuf[0] = '\0';
@ -158,7 +162,8 @@ describeTypes(const char * name, PsqlSettings * pset)
strcat(descbuf, "\nFROM pg_type\n"
"WHERE typrelid = 0 AND typname !~ '^_.*'\n");
if (name) {
if (name)
{
strcat(descbuf, " AND typname ~* '^");
strncat(descbuf, name, REGEXP_CUTOFF);
strcat(descbuf, "' ");
@ -189,7 +194,8 @@ describeTypes(const char * name, PsqlSettings * pset)
bool
describeOperators(const char *name, PsqlSettings *pset)
{
char descbuf[1536 + 3 * 32]; /* 32 is max length for operator name */
char descbuf[1536 + 3 * 32]; /* 32 is max length for operator
* name */
PGresult *res;
bool description = GetVariableBool(pset->vars, "description");
printQueryOpt myopt = pset->popt;
@ -329,7 +335,8 @@ permissionsList(const char * name, PsqlSettings *pset)
"FROM pg_class\n"
"WHERE ( relkind = 'r' OR relkind = 'S') AND\n"
" relname !~ '^pg_'\n");
if (name) {
if (name)
{
strcat(descbuf, " AND rename ~ '^");
strncat(descbuf, name, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -340,10 +347,10 @@ permissionsList(const char * name, PsqlSettings *pset)
if (!res)
return false;
if (PQntuples(res) == 0) {
if (PQntuples(res) == 0)
fputs("Couldn't find any tables.\n", pset->queryFout);
}
else {
else
{
myopt.topt.tuples_only = false;
myopt.nullPrint = NULL;
sprintf(descbuf, "Access permissions for database \"%s\"", PQdb(pset->db));
@ -380,7 +387,8 @@ objectDescription(const char * object, PsqlSettings *pset)
strcat(descbuf, "SELECT DISTINCT a.aggname as \"Name\", 'aggregate'::text as \"What\", d.description as \"Description\"\n"
"FROM pg_aggregate a, pg_description d\n"
"WHERE a.oid = d.objoid\n");
if (object) {
if (object)
{
strcat(descbuf, " AND a.aggname ~* '^");
strncat(descbuf, object, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -391,7 +399,8 @@ objectDescription(const char * object, PsqlSettings *pset)
strcat(descbuf, "SELECT DISTINCT p.proname as \"Name\", 'function'::text as \"What\", d.description as \"Description\"\n"
"FROM pg_proc p, pg_description d\n"
"WHERE p.oid = d.objoid AND (p.pronargs = 0 or oid8types(p.proargtypes) != '')\n");
if (object) {
if (object)
{
strcat(descbuf, " AND p.proname ~* '^");
strncat(descbuf, object, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -403,7 +412,8 @@ objectDescription(const char * object, PsqlSettings *pset)
"FROM pg_operator o, pg_description d\n"
// must get comment via associated function
"WHERE RegprocToOid(o.oprcode) = d.objoid\n");
if (object) {
if (object)
{
strcat(descbuf, " AND o.oprname = '");
strncat(descbuf, object, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -414,7 +424,8 @@ objectDescription(const char * object, PsqlSettings *pset)
strcat(descbuf, "SELECT DISTINCT t.typname as \"Name\", 'type'::text as \"What\", d.description as \"Description\"\n"
"FROM pg_type t, pg_description d\n"
"WHERE t.oid = d.objoid\n");
if (object) {
if (object)
{
strcat(descbuf, " AND t.typname ~* '^");
strncat(descbuf, object, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -425,7 +436,8 @@ objectDescription(const char * object, PsqlSettings *pset)
strcat(descbuf, "SELECT DISTINCT c.relname as \"Name\", 'relation'::text||'('||c.relkind||')' as \"What\", d.description as \"Description\"\n"
"FROM pg_class c, pg_description d\n"
"WHERE c.oid = d.objoid\n");
if (object) {
if (object)
{
strcat(descbuf, " AND c.relname ~* '^");
strncat(descbuf, object, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -436,7 +448,8 @@ objectDescription(const char * object, PsqlSettings *pset)
strcat(descbuf, "SELECT DISTINCT r.rulename as \"Name\", 'rule'::text as \"What\", d.description as \"Description\"\n"
"FROM pg_rewrite r, pg_description d\n"
"WHERE r.oid = d.objoid AND r.rulename !~ '^_RET'\n");
if (object) {
if (object)
{
strcat(descbuf, " AND r.rulename ~* '^");
strncat(descbuf, object, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -447,7 +460,8 @@ objectDescription(const char * object, PsqlSettings *pset)
strcat(descbuf, "SELECT DISTINCT t.tgname as \"Name\", 'trigger'::text as \"What\", d.description as \"Description\"\n"
"FROM pg_trigger t, pg_description d\n"
"WHERE t.oid = d.objoid\n");
if (object) {
if (object)
{
strcat(descbuf, " AND t.tgname ~* '^");
strncat(descbuf, object, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -480,11 +494,14 @@ objectDescription(const char * object, PsqlSettings *pset)
* and pass it to the underlying printTable() function.
*
*/
static void * xmalloc(size_t size)
static void *
xmalloc(size_t size)
{
void *tmp;
tmp = malloc(size);
if (!tmp) {
if (!tmp)
{
perror("malloc");
exit(EXIT_FAILURE);
}
@ -496,7 +513,9 @@ bool
describeTableDetails(const char *name, PsqlSettings *pset)
{
char descbuf[512 + NAMEDATALEN];
PGresult *res = NULL, *res2 = NULL, *res3 = NULL;
PGresult *res = NULL,
*res2 = NULL,
*res3 = NULL;
printTableOpt myopt = pset->popt.topt;
bool description = GetVariableBool(pset->vars, "description");
int i;
@ -513,7 +532,8 @@ describeTableDetails(const char * name, PsqlSettings * pset)
headers[0] = "Attribute";
headers[1] = "Type";
headers[2] = "Info";
if (description) {
if (description)
{
headers[3] = "Description";
headers[4] = NULL;
}
@ -535,7 +555,8 @@ describeTableDetails(const char * name, PsqlSettings * pset)
return false;
/* Did we get anything? */
if (PQntuples(res)==0) {
if (PQntuples(res) == 0)
{
if (!GetVariableBool(pset->vars, "quiet"))
fprintf(stdout, "Did not find any class named \"%s\".\n", name);
PQclear(res);
@ -557,17 +578,20 @@ describeTableDetails(const char * name, PsqlSettings * pset)
/* Generate table cells to be printed */
cells = calloc(PQntuples(res) * cols + 1, sizeof(*cells));
if (!cells) {
if (!cells)
{
perror("calloc");
exit(EXIT_FAILURE);
}
for (i = 0; i < PQntuples(res); i++) {
for (i = 0; i < PQntuples(res); i++)
{
int4 attypmod = atoi(PQgetvalue(res, i, 3));
char *attype = PQgetvalue(res, i, 1);
/* Name */
cells[i*cols + 0] = PQgetvalue(res, i, 0); /* don't free this afterwards */
cells[i * cols + 0] = PQgetvalue(res, i, 0); /* don't free this
* afterwards */
/* Type */
cells[i * cols + 1] = xmalloc(NAMEDATALEN + 16);
@ -584,11 +608,13 @@ describeTableDetails(const char * name, PsqlSettings * pset)
strcpy(cells[i * cols + 1], attype);
/* Info */
cells[i*cols + 2] = xmalloc(128 + 128); /* I'm cutting off the default string at 128 */
cells[i * cols + 2] = xmalloc(128 + 128); /* I'm cutting off the
* default string at 128 */
cells[i * cols + 2][0] = '\0';
if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
strcat(cells[i * cols + 2], "not null");
if (strcmp(PQgetvalue(res, i, 5), "t") == 0) {
if (strcmp(PQgetvalue(res, i, 5), "t") == 0)
{
/* handle "default" here */
strcpy(descbuf, "SELECT substring(d.adsrc for 128) FROM pg_attrdef d, pg_class c\n"
"WHERE c.relname = '");
@ -597,8 +623,10 @@ describeTableDetails(const char * name, PsqlSettings * pset)
strcat(descbuf, PQgetvalue(res, i, 6));
res3 = PSQLexec(pset, descbuf);
if (!res) return false;
if (cells[i*cols+2][0]) strcat(cells[i*cols+2], " ");
if (!res)
return false;
if (cells[i * cols + 2][0])
strcat(cells[i * cols + 2], " ");
strcat(cells[i * cols + 2], "default ");
strcat(cells[i * cols + 2], PQgetvalue(res3, 0, 0));
}
@ -616,13 +644,15 @@ describeTableDetails(const char * name, PsqlSettings * pset)
sprintf(title, "Table \"%s\"", name);
/* Make footers */
if (view_def) {
if (view_def)
{
footers = xmalloc(2 * sizeof(*footers));
footers[0] = xmalloc(20 + strlen(view_def));
sprintf(footers[0], "View definition: %s", view_def);
footers[1] = NULL;
}
else {
else
{
/* display indices */
strcpy(descbuf, "SELECT c2.relname\n"
"FROM pg_class c, pg_class c2, pg_index i\n"
@ -634,10 +664,12 @@ describeTableDetails(const char * name, PsqlSettings * pset)
if (!res3)
return false;
if (PQntuples(res3) > 0) {
if (PQntuples(res3) > 0)
{
footers = xmalloc((PQntuples(res3) + 1) * sizeof(*footers));
for (i=0; i<PQntuples(res3); i++) {
for (i = 0; i < PQntuples(res3); i++)
{
footers[i] = xmalloc(10 + NAMEDATALEN);
if (PQntuples(res3) == 1)
sprintf(footers[i], "Index: %s", PQgetvalue(res3, i, 0));
@ -658,7 +690,8 @@ describeTableDetails(const char * name, PsqlSettings * pset)
/* clean up */
free(title);
for (i = 0; i<PQntuples(res); i++) {
for (i = 0; i < PQntuples(res); i++)
{
free(cells[i * cols + 1]);
free(cells[i * cols + 2]);
}
@ -708,7 +741,8 @@ listTables(const char * infotype, const char * name, PsqlSettings * pset)
descbuf[0] = '\0';
/* tables */
if (showTables) {
if (showTables)
{
strcat(descbuf, "SELECT u.usename as \"Owner\", c.relname as \"Name\", 'table'::text as \"Type\"");
if (description)
strcat(descbuf, ", obj_description(c.oid) as \"Description\"");
@ -716,7 +750,8 @@ listTables(const char * infotype, const char * name, PsqlSettings * pset)
"WHERE c.relowner = u.usesysid AND c.relkind = 'r'\n"
" AND not exists (select 1 from pg_views where viewname = c.relname)\n");
strcat(descbuf, showSystem ? " AND c.relname ~ '^pg_'\n" : " AND c.relname !~ '^pg_'\n");
if (name) {
if (name)
{
strcat(descbuf, " AND c.relname ~ '^");
strncat(descbuf, name, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -724,7 +759,8 @@ listTables(const char * infotype, const char * name, PsqlSettings * pset)
}
/* views */
if (showViews) {
if (showViews)
{
if (descbuf[0])
strcat(descbuf, "\nUNION\n\n");
@ -735,7 +771,8 @@ listTables(const char * infotype, const char * name, PsqlSettings * pset)
"WHERE c.relowner = u.usesysid AND c.relkind = 'r'\n"
" AND exists (select 1 from pg_views where viewname = c.relname)\n");
strcat(descbuf, showSystem ? " AND c.relname ~ '^pg_'\n" : " AND c.relname !~ '^pg_'\n");
if (name) {
if (name)
{
strcat(descbuf, " AND c.relname ~ '^");
strncat(descbuf, name, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -743,7 +780,8 @@ listTables(const char * infotype, const char * name, PsqlSettings * pset)
}
/* indices, sequences */
if (showIndices || showSeq) {
if (showIndices || showSeq)
{
if (descbuf[0])
strcat(descbuf, "\nUNION\n\n");
@ -766,7 +804,8 @@ listTables(const char * infotype, const char * name, PsqlSettings * pset)
strcat(descbuf, " AND (c.relkind != 'i' OR c.relname !~ '^xinx')\n");
strcat(descbuf, showSystem ? " AND c.relname ~ '^pg_'\n" : " AND c.relname !~ '^pg_'\n");
if (name) {
if (name)
{
strcat(descbuf, " AND c.relname ~ '^");
strncat(descbuf, name, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -774,7 +813,8 @@ listTables(const char * infotype, const char * name, PsqlSettings * pset)
}
/* real system catalogue tables */
if (showSystem && showTables) {
if (showSystem && showTables)
{
if (descbuf[0])
strcat(descbuf, "\nUNION\n\n");
@ -783,7 +823,8 @@ listTables(const char * infotype, const char * name, PsqlSettings * pset)
strcat(descbuf, ", obj_description(c.oid) as \"Description\"");
strcat(descbuf, "\nFROM pg_class c, pg_user u\n"
"WHERE c.relowner = u.usesysid AND c.relkind = 's'\n");
if (name) {
if (name)
{
strcat(descbuf, " AND c.relname ~ '^");
strncat(descbuf, name, REGEXP_CUTOFF);
strcat(descbuf, "'\n");
@ -800,7 +841,8 @@ listTables(const char * infotype, const char * name, PsqlSettings * pset)
if (PQntuples(res) == 0)
fprintf(pset->queryFout, "No matching classes found.\n");
else {
else
{
myopt.topt.tuples_only = false;
myopt.nullPrint = NULL;
myopt.title = "List of classes";

View File

@ -34,21 +34,27 @@
*/
#define ON(var) (var ? "on" : "off")
void usage(void)
void
usage(void)
{
const char *env;
const char *user;
#ifndef WIN32
struct passwd *pw = NULL;
#endif
/* Find default user, in case we need it. */
user = getenv("USER");
if (!user) {
if (!user)
{
#ifndef WIN32
pw = getpwuid(getuid());
if (pw) user = pw->pw_name;
else {
if (pw)
user = pw->pw_name;
else
{
perror("getpwuid()");
exit(EXIT_FAILURE);
}
@ -64,7 +70,8 @@ void usage(void)
/* Display default database */
env = getenv("PGDATABASE");
if (!env) env=user;
if (!env)
env = user;
fprintf(stderr, " -d dbname Specify database name to connect to (default: %s)\n", env);
fprintf(stderr, " -e Echo all input in non-interactive mode\n");
@ -101,7 +108,8 @@ void usage(void)
/* Display default user */
env = getenv("PGUSER");
if (!env) env=user;
if (!env)
env = user;
fprintf(stderr, " -U [username] Specifiy username, \"?\"=prompt (default user: %s)\n", env);
fprintf(stderr, " -x Turn on expanded table output (-P expanded)\n");
@ -112,7 +120,8 @@ void usage(void)
fprintf(stderr, "Consult the documentation for the complete details.\n");
#ifndef WIN32
if (pw) free(pw);
if (pw)
free(pw);
#endif
}
@ -125,10 +134,12 @@ void usage(void)
*/
#ifndef TIOCGWINSZ
struct winsize {
struct winsize
{
int ws_row;
int ws_col;
};
#endif
void
@ -197,7 +208,8 @@ slashUsage(PsqlSettings *pset)
fprintf(fout, " \\z -- list table access permissions\n");
fprintf(fout, " \\! [<cmd>] -- shell escape or command\n");
if (usePipe) {
if (usePipe)
{
pclose(fout);
pqsignal(SIGPIPE, SIG_DFL);
}

View File

@ -13,4 +13,3 @@ void print_copyright(void);
#endif

View File

@ -10,9 +10,11 @@
/* (of course there is no runtime command for doing that :) */
#ifdef USE_READLINE
static bool useReadline;
#endif
#ifdef USE_HISTORY
static bool useHistory;
#endif
@ -28,12 +30,14 @@ gets_interactive(const char *prompt)
char *s;
#ifdef USE_READLINE
if (useReadline) {
if (useReadline)
{
s = readline(prompt);
fputc('\r', stdout);
fflush(stdout);
}
else {
else
{
#endif
fputs(prompt, stdout);
fflush(stdout);
@ -65,9 +69,11 @@ gets_fromFile(FILE *source)
initPQExpBuffer(&buffer);
while (fgets(line, 1024, source) != NULL) {
while (fgets(line, 1024, source) != NULL)
{
appendPQExpBufferStr(&buffer, line);
if (buffer.data[buffer.len-1] == '\n') {
if (buffer.data[buffer.len - 1] == '\n')
{
buffer.data[buffer.len - 1] = '\0';
return buffer.data;
}
@ -93,22 +99,27 @@ void
initializeInput(int flags)
{
#ifdef USE_READLINE
if (flags == 1) {
if (flags == 1)
{
useReadline = true;
rl_readline_name = "psql";
}
#endif
#ifdef USE_HISTORY
if (flags == 1) {
if (flags == 1)
{
const char *home;
useHistory = true;
using_history();
home = getenv("HOME");
if (home) {
if (home)
{
char *psql_history = (char *) malloc(strlen(home) + 20);
if (psql_history) {
if (psql_history)
{
sprintf(psql_history, "%s/.psql_history", home);
read_history(psql_history);
free(psql_history);
@ -124,8 +135,10 @@ bool
saveHistory(const char *fname)
{
#ifdef USE_HISTORY
if (useHistory) {
if (write_history(fname) != 0) {
if (useHistory)
{
if (write_history(fname) != 0)
{
perror(fname);
return false;
}
@ -144,14 +157,17 @@ void
finishInput(void)
{
#ifdef USE_HISTORY
if (useHistory) {
if (useHistory)
{
char *home;
char *psql_history;
home = getenv("HOME");
if (home) {
if (home)
{
psql_history = (char *) malloc(strlen(home) + 20);
if (psql_history) {
if (psql_history)
{
sprintf(psql_history, "%s/.psql_history", home);
write_history(psql_history);
free(psql_history);

View File

@ -24,7 +24,8 @@
static char notice[80];
static void
_my_notice_handler(void * arg, const char * message) {
_my_notice_handler(void *arg, const char *message)
{
(void) arg;
strncpy(notice, message, 79);
notice[79] = '\0';
@ -51,12 +52,14 @@ handle_transaction(PsqlSettings * pset)
if (!res)
return false;
if (notice[0]) {
if (notice[0])
{
if ((!commit && strcmp(notice, "NOTICE: UserAbortTransactionBlock and not in in-progress state\n") != 0) ||
(commit && strcmp(notice, "NOTICE: EndTransactionBlock and not inprogress/abort state\n") != 0))
fputs(notice, stderr);
}
else if (!GetVariableBool(pset->vars, "quiet")) {
else if (!GetVariableBool(pset->vars, "quiet"))
{
if (commit)
puts("Warning: Your transaction in progress has been committed.");
else
@ -85,12 +88,14 @@ do_lo_export(PsqlSettings * pset, const char * loid_arg, const char * filename_a
if (var && strcmp(var, "nothing") == 0)
own_transaction = false;
if (!pset->db) {
if (!pset->db)
{
fputs("You are not connected to a database.\n", stderr);
return false;
}
if (own_transaction) {
if (own_transaction)
{
if (!handle_transaction(pset))
return false;
@ -101,17 +106,22 @@ do_lo_export(PsqlSettings * pset, const char * loid_arg, const char * filename_a
}
status = lo_export(pset->db, atol(loid_arg), (char *) filename_arg);
if (status != 1) { /* of course this status is documented nowhere :( */
if (status != 1)
{ /* of course this status is documented
* nowhere :( */
fputs(PQerrorMessage(pset->db), stderr);
if (own_transaction) {
if (own_transaction)
{
res = PQexec(pset->db, "ROLLBACK");
PQclear(res);
}
return false;
}
if (own_transaction) {
if (!(res = PSQLexec(pset, "COMMIT"))) {
if (own_transaction)
{
if (!(res = PSQLexec(pset, "COMMIT")))
{
res = PQexec(pset->db, "ROLLBACK");
PQclear(res);
return false;
@ -145,12 +155,14 @@ do_lo_import(PsqlSettings * pset, const char * filename_arg, const char * commen
if (var && strcmp(var, "nothing") == 0)
own_transaction = false;
if (!pset->db) {
if (!pset->db)
{
fputs("You are not connected to a database.\n", stderr);
return false;
}
if (own_transaction) {
if (own_transaction)
{
if (!handle_transaction(pset))
return false;
@ -161,9 +173,11 @@ do_lo_import(PsqlSettings * pset, const char * filename_arg, const char * commen
}
loid = lo_import(pset->db, (char *) filename_arg);
if (loid == InvalidOid) {
if (loid == InvalidOid)
{
fputs(PQerrorMessage(pset->db), stderr);
if (own_transaction) {
if (own_transaction)
{
res = PQexec(pset->db, "ROLLBACK");
PQclear(res);
}
@ -171,7 +185,8 @@ do_lo_import(PsqlSettings * pset, const char * filename_arg, const char * commen
}
/* insert description if given */
if (comment_arg) {
if (comment_arg)
{
sprintf(buf, "INSERT INTO pg_description VALUES (%d, '", loid);
for (i = 0; i < strlen(comment_arg); i++)
if (comment_arg[i] == '\'')
@ -180,8 +195,10 @@ do_lo_import(PsqlSettings * pset, const char * filename_arg, const char * commen
strncat(buf, &comment_arg[i], 1);
strcat(buf, "')");
if (!(res = PSQLexec(pset, buf))) {
if (own_transaction) {
if (!(res = PSQLexec(pset, buf)))
{
if (own_transaction)
{
res = PQexec(pset->db, "ROLLBACK");
PQclear(res);
}
@ -189,8 +206,10 @@ do_lo_import(PsqlSettings * pset, const char * filename_arg, const char * commen
}
}
if (own_transaction) {
if (!(res = PSQLexec(pset, "COMMIT"))) {
if (own_transaction)
{
if (!(res = PSQLexec(pset, "COMMIT")))
{
res = PQexec(pset->db, "ROLLBACK");
PQclear(res);
return false;
@ -212,7 +231,8 @@ do_lo_import(PsqlSettings * pset, const char * filename_arg, const char * commen
*
* removes a large object out of the database
*/
bool do_lo_unlink(PsqlSettings * pset, const char * loid_arg)
bool
do_lo_unlink(PsqlSettings *pset, const char *loid_arg)
{
PGresult *res;
int status;
@ -224,12 +244,14 @@ bool do_lo_unlink(PsqlSettings * pset, const char * loid_arg)
if (var && strcmp(var, "nothing") == 0)
own_transaction = false;
if (!pset->db) {
if (!pset->db)
{
fputs("You are not connected to a database.\n", stderr);
return false;
}
if (own_transaction) {
if (own_transaction)
{
if (!handle_transaction(pset))
return false;
@ -240,9 +262,11 @@ bool do_lo_unlink(PsqlSettings * pset, const char * loid_arg)
}
status = lo_unlink(pset->db, loid);
if (status == -1) {
if (status == -1)
{
fputs(PQerrorMessage(pset->db), stderr);
if (own_transaction) {
if (own_transaction)
{
res = PQexec(pset->db, "ROLLBACK");
PQclear(res);
}
@ -251,8 +275,10 @@ bool do_lo_unlink(PsqlSettings * pset, const char * loid_arg)
/* remove the comment as well */
sprintf(buf, "DELETE FROM pg_description WHERE objoid = %d", loid);
if (!(res = PSQLexec(pset, buf))) {
if (own_transaction) {
if (!(res = PSQLexec(pset, buf)))
{
if (own_transaction)
{
res = PQexec(pset->db, "ROLLBACK");
PQclear(res);
}
@ -260,8 +286,10 @@ bool do_lo_unlink(PsqlSettings * pset, const char * loid_arg)
}
if (own_transaction) {
if (!(res = PSQLexec(pset, "COMMIT"))) {
if (own_transaction)
{
if (!(res = PSQLexec(pset, "COMMIT")))
{
res = PQexec(pset->db, "ROLLBACK");
PQclear(res);
return false;
@ -282,7 +310,8 @@ bool do_lo_unlink(PsqlSettings * pset, const char * loid_arg)
*
* Show all large objects in database, with comments if desired
*/
bool do_lo_list(PsqlSettings * pset)
bool
do_lo_list(PsqlSettings *pset)
{
PGresult *res;
char descbuf[512];

View File

@ -40,7 +40,9 @@ MainLoop(PsqlSettings *pset, FILE *source)
int paren_level;
unsigned int query_start;
int i, prevlen, thislen;
int i,
prevlen,
thislen;
/* Save the prior command source */
FILE *prev_cmd_source;
@ -60,7 +62,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
query_buf = createPQExpBuffer();
if (!query_buf) {
if (!query_buf)
{
perror("createPQExpBuffer");
exit(EXIT_FAILURE);
}
@ -76,6 +79,7 @@ MainLoop(PsqlSettings *pset, FILE *source)
{
if (slashCmdStatus == CMD_NEWEDIT)
{
/*
* just returned from editing the line? then just copy to the
* input buffer
@ -89,9 +93,10 @@ MainLoop(PsqlSettings *pset, FILE *source)
}
else
{
/*
* otherwise, set interactive prompt if necessary
* and get another line
* otherwise, set interactive prompt if necessary and get
* another line
*/
if (pset->cur_cmd_interactive)
{
@ -121,9 +126,10 @@ MainLoop(PsqlSettings *pset, FILE *source)
/*
* query_buf holds query already accumulated. line is the malloc'd
* new line of input (note it must be freed before looping around!)
* query_start is the next command start location within the line.
* query_buf holds query already accumulated. line is the
* malloc'd new line of input (note it must be freed before
* looping around!) query_start is the next command start location
* within the line.
*/
/* No more input. Time to quit, or \i done */
@ -141,8 +147,10 @@ MainLoop(PsqlSettings *pset, FILE *source)
/* strip trailing backslashes, they don't have a clear meaning */
while (1) {
while (1)
{
char *cp = strrchr(line, '\\');
if (cp && (*(cp + 1) == '\0'))
*cp = '\0';
else
@ -159,12 +167,16 @@ MainLoop(PsqlSettings *pset, FILE *source)
len = strlen(line);
thislen = PQmblen(line);
for (i = 0; line[i]; i += (thislen = PQmblen(&line[i])) ) {
if (interpol_char && interpol_char[0] != '\0' && interpol_char[0] == line[i]) {
size_t in_length, out_length;
for (i = 0; line[i]; i += (thislen = PQmblen(&line[i])))
{
if (interpol_char && interpol_char[0] != '\0' && interpol_char[0] == line[i])
{
size_t in_length,
out_length;
const char *value;
char *new;
bool closer; /* did we have a closing delimiter or just an end of line? */
bool closer; /* did we have a closing delimiter
* or just an end of line? */
in_length = strcspn(&line[i + thislen], interpol_char);
closer = line[i + thislen + in_length] == line[i];
@ -173,7 +185,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
out_length = strlen(value);
new = malloc(len + out_length - (in_length + (closer ? 2 : 1)) + 1);
if (!new) {
if (!new)
{
perror("malloc");
exit(EXIT_FAILURE);
}
@ -191,7 +204,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
}
/* nothing left on line? then ignore */
if (line[0] == '\0') {
if (line[0] == '\0')
{
free(line);
continue;
}
@ -204,8 +218,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
/*
* Parse line, looking for command separators.
*
* The current character is at line[i], the prior character at
* line[i - prevlen], the next character at line[i + thislen].
* The current character is at line[i], the prior character at line[i
* - prevlen], the next character at line[i + thislen].
*/
prevlen = 0;
thislen = (len > 0) ? PQmblen(line) : 0;
@ -213,7 +227,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
#define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i))
success = true;
for (i = 0; i < len; ADVANCE_1) {
for (i = 0; i < len; ADVANCE_1)
{
if (!success && die_on_error)
break;
@ -226,7 +241,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
/* in quote? */
if (in_quote) {
if (in_quote)
{
/* end of quote */
if (line[i] == in_quote && !was_bslash)
in_quote = '\0';
@ -237,15 +253,18 @@ MainLoop(PsqlSettings *pset, FILE *source)
in_quote = line[i];
/* in extended comment? */
else if (xcomment != NULL) {
if (line[i] == '*' && line[i + thislen] == '/') {
else if (xcomment != NULL)
{
if (line[i] == '*' && line[i + thislen] == '/')
{
xcomment = NULL;
ADVANCE_1;
}
}
/* start of extended comment? */
else if (line[i] == '/' && line[i + thislen] == '*') {
else if (line[i] == '/' && line[i + thislen] == '*')
{
xcomment = &line[i];
ADVANCE_1;
}
@ -266,11 +285,17 @@ MainLoop(PsqlSettings *pset, FILE *source)
paren_level--;
/* semicolon? then send query */
else if (line[i] == ';' && !was_bslash && paren_level==0) {
else if (line[i] == ';' && !was_bslash && paren_level == 0)
{
line[i] = '\0';
/* is there anything else on the line? */
if (line[query_start + strspn(line + query_start, " \t")]!='\0') {
/* insert a cosmetic newline, if this is not the first line in the buffer */
if (line[query_start + strspn(line + query_start, " \t")] != '\0')
{
/*
* insert a cosmetic newline, if this is not the first
* line in the buffer
*/
if (query_buf->len > 0)
appendPQExpBufferChar(query_buf, '\n');
/* append the line to the query buffer */
@ -285,14 +310,20 @@ MainLoop(PsqlSettings *pset, FILE *source)
}
/* backslash command */
else if (was_bslash) {
else if (was_bslash)
{
const char *end_of_cmd = NULL;
line[i - prevlen] = '\0'; /* overwrites backslash */
/* is there anything else on the line? */
if (line[query_start + strspn(line + query_start, " \t")]!='\0') {
/* insert a cosmetic newline, if this is not the first line in the buffer */
if (line[query_start + strspn(line + query_start, " \t")] != '\0')
{
/*
* insert a cosmetic newline, if this is not the first
* line in the buffer
*/
if (query_buf->len > 0)
appendPQExpBufferChar(query_buf, '\n');
/* append the line to the query buffer */
@ -305,14 +336,16 @@ MainLoop(PsqlSettings *pset, FILE *source)
success = slashCmdStatus != CMD_ERROR;
if (slashCmdStatus == CMD_SEND) {
if (slashCmdStatus == CMD_SEND)
{
success = SendQuery(pset, query_buf->data);
resetPQExpBuffer(query_buf);
query_start = i + thislen;
}
/* is there anything left after the backslash command? */
if (end_of_cmd) {
if (end_of_cmd)
{
i += end_of_cmd - &line[i];
query_start = i;
}
@ -322,20 +355,23 @@ MainLoop(PsqlSettings *pset, FILE *source)
}
if (!success && die_on_error && !pset->cur_cmd_interactive) {
if (!success && die_on_error && !pset->cur_cmd_interactive)
{
successResult = EXIT_USER;
break;
}
if (slashCmdStatus == CMD_TERMINATE) {
if (slashCmdStatus == CMD_TERMINATE)
{
successResult = EXIT_SUCCESS;
break;
}
/* Put the rest of the line in the query buffer. */
if (line[query_start + strspn(line + query_start, " \t")]!='\0') {
if (line[query_start + strspn(line + query_start, " \t")] != '\0')
{
if (query_buf->len > 0)
appendPQExpBufferChar(query_buf, '\n');
appendPQExpBufferStr(query_buf, line + query_start);
@ -345,14 +381,16 @@ MainLoop(PsqlSettings *pset, FILE *source)
/* In single line mode, send off the query if any */
if (query_buf->data[0] != '\0' && GetVariableBool(pset->vars, "singleline")) {
if (query_buf->data[0] != '\0' && GetVariableBool(pset->vars, "singleline"))
{
success = SendQuery(pset, query_buf->data);
resetPQExpBuffer(query_buf);
}
/* Have we lost the db connection? */
if (pset->db == NULL && !pset->cur_cmd_interactive) {
if (pset->db == NULL && !pset->cur_cmd_interactive)
{
successResult = EXIT_BADCONN;
break;
}
@ -365,4 +403,3 @@ MainLoop(PsqlSettings *pset, FILE *source)
return successResult;
} /* MainLoop() */

View File

@ -7,4 +7,4 @@
int
MainLoop(PsqlSettings *pset, FILE *source);
#endif MAINLOOP_H
#endif /* MAINLOOP_H */

View File

@ -44,9 +44,11 @@ print_unaligned_text(const char * title, char ** headers, char ** cells, char **
fprintf(fout, "%s\n", title);
/* print headers and count columns */
for (ptr = headers; *ptr; ptr++) {
for (ptr = headers; *ptr; ptr++)
{
col_count++;
if (!opt_barebones) {
if (!opt_barebones)
{
if (col_count > 1)
fputs(opt_fieldsep, fout);
fputs(*ptr, fout);
@ -57,7 +59,8 @@ print_unaligned_text(const char * title, char ** headers, char ** cells, char **
/* print cells */
i = 0;
for (ptr = cells; *ptr; ptr++) {
for (ptr = cells; *ptr; ptr++)
{
fputs(*ptr, fout);
if ((i + 1) % col_count)
fputs(opt_fieldsep, fout);
@ -94,13 +97,14 @@ print_unaligned_vertical(const char * title, char ** headers, char ** cells, cha
fprintf(fout, "%s\n", title);
/* count columns */
for (ptr = headers; *ptr; ptr++) {
for (ptr = headers; *ptr; ptr++)
col_count++;
}
/* print records */
for (i=0, ptr = cells; *ptr; i++, ptr++) {
if (i % col_count == 0) {
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
if (i % col_count == 0)
{
if (!opt_barebones)
fprintf(fout, "-- RECORD %d\n", record++);
else
@ -111,7 +115,8 @@ print_unaligned_vertical(const char * title, char ** headers, char ** cells, cha
/* print footers */
if (!opt_barebones && footers) {
if (!opt_barebones && footers)
{
fputs("--- END ---\n", fout);
for (ptr = footers; *ptr; ptr++)
fprintf(fout, "%s\n", *ptr);
@ -129,17 +134,21 @@ print_unaligned_vertical(const char * title, char ** headers, char ** cells, cha
static void
_print_horizontal_line(const unsigned int col_count, const unsigned int *widths, unsigned short border, FILE *fout)
{
unsigned int i, j;
unsigned int i,
j;
if (border == 1)
fputc('-', fout);
else if (border == 2)
fputs("+-", fout);
for (i=0; i<col_count; i++) {
for (i = 0; i < col_count; i++)
{
for (j = 0; j < widths[i]; j++)
fputc('-', fout);
if (i<col_count-1) {
if (i < col_count - 1)
{
if (border == 0)
fputc(' ', fout);
else
@ -163,8 +172,10 @@ print_aligned_text(const char * title, char ** headers, char ** cells, char ** f
FILE *fout)
{
unsigned int col_count = 0;
unsigned int i, tmp;
unsigned int * widths, total_w;
unsigned int i,
tmp;
unsigned int *widths,
total_w;
char **ptr;
/* count columns */
@ -172,7 +183,8 @@ print_aligned_text(const char * title, char ** headers, char ** cells, char ** f
col_count++;
widths = calloc(col_count, sizeof(*widths));
if (!widths) {
if (!widths)
{
perror("calloc");
exit(EXIT_FAILURE);
}
@ -197,7 +209,8 @@ print_aligned_text(const char * title, char ** headers, char ** cells, char ** f
total_w += widths[i];
/* print title */
if (title && !opt_barebones) {
if (title && !opt_barebones)
{
if (strlen(title) >= total_w)
fprintf(fout, "%s\n", title);
else
@ -205,7 +218,8 @@ print_aligned_text(const char * title, char ** headers, char ** cells, char ** f
}
/* print headers */
if (!opt_barebones) {
if (!opt_barebones)
{
if (opt_border == 2)
_print_horizontal_line(col_count, widths, opt_border, fout);
@ -214,11 +228,13 @@ print_aligned_text(const char * title, char ** headers, char ** cells, char ** f
else if (opt_border == 1)
fputc(' ', fout);
for (i=0; i<col_count; i++) {
for (i = 0; i < col_count; i++)
{
/* centered */
fprintf(fout, "%-*s%s%-*s", (int) floor((widths[i] - strlen(headers[i])) / 2.0), "", headers[i], (int) ceil((widths[i] - strlen(headers[i])) / 2.0), "");
if (i<col_count-1) {
if (i < col_count - 1)
{
if (opt_border == 0)
fputc(' ', fout);
else
@ -236,9 +252,11 @@ print_aligned_text(const char * title, char ** headers, char ** cells, char ** f
}
/* print cells */
for (i=0, ptr = cells; *ptr; i++, ptr++) {
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
/* beginning of line */
if (i % col_count == 0) {
if (i % col_count == 0)
{
if (opt_border == 2)
fputs("| ", fout);
else if (opt_border == 1)
@ -248,7 +266,8 @@ print_aligned_text(const char * title, char ** headers, char ** cells, char ** f
/* content */
if (opt_align[(i) % col_count] == 'r')
fprintf(fout, "%*s", widths[i % col_count], cells[i]);
else {
else
{
if ((i + 1) % col_count == 0 && opt_border != 2)
fputs(cells[i], fout);
else
@ -256,14 +275,16 @@ print_aligned_text(const char * title, char ** headers, char ** cells, char ** f
}
/* divider */
if ((i+1) % col_count) {
if ((i + 1) % col_count)
{
if (opt_border == 0)
fputc(' ', fout);
else
fputs(" | ", fout);
}
/* end of line */
else {
else
{
if (opt_border == 2)
fputs(" |", fout);
fputc('\n', fout);
@ -294,11 +315,15 @@ print_aligned_vertical(const char * title, char ** headers, char ** cells, char
unsigned int col_count = 0;
unsigned int record = 1;
char **ptr;
unsigned int i, tmp, hwidth=0, dwidth=0;
unsigned int i,
tmp,
hwidth = 0,
dwidth = 0;
char *divider;
/* count columns and find longest header */
for (ptr = headers; *ptr; ptr++) {
for (ptr = headers; *ptr; ptr++)
{
col_count++;
if ((tmp = strlen(*ptr)) > hwidth)
hwidth = tmp; /* don't wanna call strlen twice */
@ -315,32 +340,39 @@ print_aligned_vertical(const char * title, char ** headers, char ** cells, char
/* make horizontal border */
divider = malloc(hwidth + dwidth + 10);
if (!divider) {
if (!divider)
{
perror("malloc");
exit(EXIT_FAILURE);
}
divider[0] = '\0';
if (opt_border == 2)
strcat(divider, "+-");
for (i=0; i<hwidth; i++) strcat(divider, opt_border > 0 ? "-" : " ");
for (i = 0; i < hwidth; i++)
strcat(divider, opt_border > 0 ? "-" : " ");
if (opt_border > 0)
strcat(divider, "-+-");
else
strcat(divider, " ");
for (i=0; i<dwidth; i++) strcat(divider, opt_border > 0 ? "-" : " ");
for (i = 0; i < dwidth; i++)
strcat(divider, opt_border > 0 ? "-" : " ");
if (opt_border == 2)
strcat(divider, "-+");
/* print records */
for (i=0, ptr = cells; *ptr; i++, ptr++) {
if (i % col_count == 0) {
if (!opt_barebones) {
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
if (i % col_count == 0)
{
if (!opt_barebones)
{
char *div_copy = strdup(divider);
char *record_str = malloc(32);
size_t record_str_len;
if (!div_copy || !record_str) {
if (!div_copy || !record_str)
{
perror("malloc");
exit(EXIT_FAILURE);
}
@ -350,10 +382,13 @@ print_aligned_vertical(const char * title, char ** headers, char ** cells, char
else
sprintf(record_str, "[ RECORD %d ]", record++);
record_str_len = strlen(record_str);
if (record_str_len + opt_border > strlen(div_copy)) {
if (record_str_len + opt_border > strlen(div_copy))
{
void *new;
new = realloc(div_copy, record_str_len + opt_border);
if (!new) {
if (!new)
{
perror("realloc");
exit(EXIT_FAILURE);
}
@ -387,7 +422,8 @@ print_aligned_vertical(const char * title, char ** headers, char ** cells, char
/* print footers */
if (!opt_barebones && footers && *footers) {
if (!opt_barebones && footers && *footers)
{
if (opt_border < 2)
fputc('\n', fout);
for (ptr = footers; *ptr; ptr++)
@ -411,8 +447,10 @@ static void
html_escaped_print(const char *in, FILE *fout)
{
const char *p;
for (p = in; *p; p++)
switch (*p) {
switch (*p)
{
case '&':
fputs("&amp;", fout);
break;
@ -448,7 +486,8 @@ print_html_text(const char * title, char ** headers, char ** cells, char ** foot
fputs(">\n", fout);
/* print title */
if (!opt_barebones && title) {
if (!opt_barebones && title)
{
fputs(" <caption>", fout);
html_escaped_print(title, fout);
fputs("</caption>\n", fout);
@ -457,9 +496,11 @@ print_html_text(const char * title, char ** headers, char ** cells, char ** foot
/* print headers and count columns */
if (!opt_barebones)
fputs(" <tr>\n", fout);
for (i=0, ptr = headers; *ptr; i++, ptr++) {
for (i = 0, ptr = headers; *ptr; i++, ptr++)
{
col_count++;
if (!opt_barebones) {
if (!opt_barebones)
{
fputs(" <th align=center>", fout);
html_escaped_print(*ptr, fout);
fputs("</th>\n", fout);
@ -469,12 +510,14 @@ print_html_text(const char * title, char ** headers, char ** cells, char ** foot
fputs(" </tr>\n", fout);
/* print cells */
for (i=0, ptr = cells; *ptr; i++, ptr++) {
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
if (i % col_count == 0)
fputs(" <tr valign=top>\n", fout);
fprintf(fout, " <td align=%s>", opt_align[(i) % col_count] == 'r' ? "right" : "left");
if ( (*ptr)[strspn(*ptr, " \t")] == '\0' ) /* is string only whitespace? */
if ((*ptr)[strspn(*ptr, " \t")] == '\0') /* is string only
* whitespace? */
fputs("&nbsp;", fout);
else
html_escaped_print(*ptr, fout);
@ -489,7 +532,8 @@ print_html_text(const char * title, char ** headers, char ** cells, char ** foot
/* print footers */
if (footers && !opt_barebones)
for (ptr = footers; *ptr; ptr++) {
for (ptr = footers; *ptr; ptr++)
{
html_escaped_print(*ptr, fout);
fputs("<br>\n", fout);
}
@ -516,7 +560,8 @@ print_html_vertical(const char * title, char ** headers, char ** cells, char **
fputs(">\n", fout);
/* print title */
if (!opt_barebones && title) {
if (!opt_barebones && title)
{
fputs(" <caption>", fout);
html_escaped_print(title, fout);
fputs("</caption>\n", fout);
@ -527,8 +572,10 @@ print_html_vertical(const char * title, char ** headers, char ** cells, char **
col_count++;
/* print records */
for (i=0, ptr = cells; *ptr; i++, ptr++) {
if (i % col_count == 0) {
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
if (i % col_count == 0)
{
if (!opt_barebones)
fprintf(fout, "\n <tr><td colspan=2 align=center>Record %d</td></tr>\n", record++);
else
@ -540,7 +587,8 @@ print_html_vertical(const char * title, char ** headers, char ** cells, char **
fputs("</th>\n", fout);
fprintf(fout, " <td align=%s>", opt_align[i % col_count] == 'r' ? "right" : "left");
if ( (*ptr)[strspn(*ptr, " \t")] == '\0' ) /* is string only whitespace? */
if ((*ptr)[strspn(*ptr, " \t")] == '\0') /* is string only
* whitespace? */
fputs("&nbsp;", fout);
else
html_escaped_print(*ptr, fout);
@ -551,7 +599,8 @@ print_html_vertical(const char * title, char ** headers, char ** cells, char **
/* print footers */
if (footers && !opt_barebones)
for (ptr = footers; *ptr; ptr++) {
for (ptr = footers; *ptr; ptr++)
{
html_escaped_print(*ptr, fout);
fputs("<br>\n", fout);
}
@ -570,8 +619,10 @@ static void
latex_escaped_print(const char *in, FILE *fout)
{
const char *p;
for (p = in; *p; p++)
switch (*p) {
switch (*p)
{
case '&':
fputs("\\&", fout);
break;
@ -612,7 +663,8 @@ print_latex_text(const char * title, char ** headers, char ** cells, char ** foo
/* print title */
if (!opt_barebones && title) {
if (!opt_barebones && title)
{
fputs("\begin{center}\n", fout);
latex_escaped_print(title, fout);
fputs("\n\end{center}\n\n", fout);
@ -622,14 +674,19 @@ print_latex_text(const char * title, char ** headers, char ** cells, char ** foo
fputs("\\begin{tabular}{", fout);
if (opt_border == 0)
fputs(opt_align, fout);
else if (opt_border==1) {
for (cp = opt_align; *cp; cp++) {
if (cp != opt_align) fputc('|', fout);
else if (opt_border == 1)
{
for (cp = opt_align; *cp; cp++)
{
if (cp != opt_align)
fputc('|', fout);
fputc(*cp, fout);
}
}
else if (opt_border==2) {
for (cp = opt_align; *cp; cp++) {
else if (opt_border == 2)
{
for (cp = opt_align; *cp; cp++)
{
fputc('|', fout);
fputc(*cp, fout);
}
@ -641,22 +698,26 @@ print_latex_text(const char * title, char ** headers, char ** cells, char ** foo
fputs("\\hline\n", fout);
/* print headers and count columns */
for (i=0, ptr = headers; *ptr; i++, ptr++) {
for (i = 0, ptr = headers; *ptr; i++, ptr++)
{
col_count++;
if (!opt_barebones) {
if (!opt_barebones)
{
if (i != 0)
fputs(" & ", fout);
latex_escaped_print(*ptr, fout);
}
}
if (!opt_barebones) {
if (!opt_barebones)
{
fputs(" \\\\\n", fout);
fputs("\\hline\n", fout);
}
/* print cells */
for (i=0, ptr = cells; *ptr; i++, ptr++) {
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
latex_escaped_print(*ptr, fout);
if ((i + 1) % col_count == 0)
@ -674,7 +735,8 @@ print_latex_text(const char * title, char ** headers, char ** cells, char ** foo
/* print footers */
if (footers && !opt_barebones)
for (ptr = footers; *ptr; ptr++) {
for (ptr = footers; *ptr; ptr++)
{
latex_escaped_print(*ptr, fout);
fputs(" \\\\\n", fout);
}
@ -697,7 +759,8 @@ print_latex_vertical(const char * title, char ** headers, char ** cells, char **
(void) opt_align; /* currently unused parameter */
/* print title */
if (!opt_barebones && title) {
if (!opt_barebones && title)
{
fputs("\begin{center}\n", fout);
latex_escaped_print(title, fout);
fputs("\n\end{center}\n\n", fout);
@ -720,10 +783,13 @@ print_latex_vertical(const char * title, char ** headers, char ** cells, char **
/* print records */
for (i=0, ptr = cells; *ptr; i++, ptr++) {
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
/* new record */
if (i % col_count == 0) {
if (!opt_barebones) {
if (i % col_count == 0)
{
if (!opt_barebones)
{
if (opt_border == 2)
fputs("\\hline\n", fout);
fprintf(fout, "\\multicolumn{2}{c}{Record %d} \\\\\n", record++);
@ -747,7 +813,8 @@ print_latex_vertical(const char * title, char ** headers, char ** cells, char **
/* print footers */
if (footers && !opt_barebones)
for (ptr = footers; *ptr; ptr++) {
for (ptr = footers; *ptr; ptr++)
{
latex_escaped_print(*ptr, fout);
fputs(" \\\\\n", fout);
}
@ -796,8 +863,11 @@ printTable(const char * title, char ** headers, char ** cells, char ** footers,
)
{
const char *pagerprog;
#ifdef TIOCGWINSZ
unsigned int col_count=0, row_count=0, lines;
unsigned int col_count = 0,
row_count = 0,
lines;
char **ptr;
int result;
struct winsize screen_size;
@ -819,17 +889,20 @@ printTable(const char * title, char ** headers, char ** cells, char ** footers,
lines += 5;
result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size);
if (result==-1 || lines > screen_size.ws_row) {
if (result == -1 || lines > screen_size.ws_row)
{
#endif
pagerprog = getenv("PAGER");
if (!pagerprog) pagerprog = DEFAULT_PAGER;
if (!pagerprog)
pagerprog = DEFAULT_PAGER;
pager = popen(pagerprog, "w");
#ifdef TIOCGWINSZ
}
#endif
}
if (pager) {
if (pager)
{
output = pager;
pqsignal(SIGPIPE, SIG_IGN);
}
@ -839,7 +912,8 @@ printTable(const char * title, char ** headers, char ** cells, char ** footers,
/* print the stuff */
switch (opt->format) {
switch (opt->format)
{
case PRINT_UNALIGNED:
if (opt->expanded)
print_unaligned_vertical(title, headers, cells, footers, opt->fieldSep, opt->tuples_only, output);
@ -868,7 +942,8 @@ printTable(const char * title, char ** headers, char ** cells, char ** footers,
fprintf(stderr, "+ Oops, you shouldn't see this!\n");
}
if (pager) {
if (pager)
{
pclose(pager);
pqsignal(SIGPIPE, SIG_DFL);
}
@ -891,7 +966,8 @@ printQuery(PGresult * result, const printQueryOpt * opt, FILE * fout)
nfields = PQnfields(result);
headers = calloc(nfields + 1, sizeof(*headers));
if (!headers) {
if (!headers)
{
perror("calloc");
exit(EXIT_FAILURE);
}
@ -902,12 +978,14 @@ printQuery(PGresult * result, const printQueryOpt * opt, FILE * fout)
/* set cells */
cells = calloc(nfields * PQntuples(result) + 1, sizeof(*cells));
if (!cells) {
if (!cells)
{
perror("calloc");
exit(EXIT_FAILURE);
}
for (i=0; i< nfields * PQntuples(result); i++) {
for (i = 0; i < nfields * PQntuples(result); i++)
{
if (PQgetisnull(result, i / nfields, i % nfields))
cells[i] = opt->nullPrint ? opt->nullPrint : "";
else
@ -918,9 +996,11 @@ printQuery(PGresult * result, const printQueryOpt * opt, FILE * fout)
if (opt->footers)
footers = opt->footers;
else if (!opt->topt.expanded) {
else if (!opt->topt.expanded)
{
footers = calloc(2, sizeof(*footers));
if (!footers) {
if (!footers)
{
perror("calloc");
exit(EXIT_FAILURE);
}
@ -937,13 +1017,16 @@ printQuery(PGresult * result, const printQueryOpt * opt, FILE * fout)
/* set alignment */
align = calloc(nfields + 1, sizeof(*align));
if (!align) {
if (!align)
{
perror("calloc");
exit(EXIT_FAILURE);
}
for (i=0; i<nfields; i++) {
for (i = 0; i < nfields; i++)
{
Oid ftype = PQftype(result, i);
if (ftype == 20 || /* int8 */
ftype == 21 || /* int2 */
ftype == 23 || /* int4 */
@ -965,7 +1048,8 @@ printQuery(PGresult * result, const printQueryOpt * opt, FILE * fout)
free(headers);
free(cells);
if (footers) {
if (footers)
{
free(footers[0]);
free(footers);
}

View File

@ -7,7 +7,8 @@
#include <stdio.h>
#include <libpq-fe.h>
enum printFormat {
enum printFormat
{
PRINT_NOTHING = 0, /* to make sure someone initializes this */
PRINT_UNALIGNED,
PRINT_ALIGNED,
@ -17,12 +18,16 @@ enum printFormat {
};
typedef struct _printTableOpt {
typedef struct _printTableOpt
{
enum printFormat format; /* one of the above */
bool expanded; /* expanded/vertical output (if supported by output format) */
bool pager; /* use pager for output (if to stdout and stdout is a tty) */
bool expanded; /* expanded/vertical output (if supported
* by output format) */
bool pager; /* use pager for output (if to stdout and
* stdout is a tty) */
bool tuples_only; /* don't output headers, row counts, etc. */
unsigned short int border; /* Print a border around the table. 0=none, 1=dividing lines, 2=full */
unsigned short int border; /* Print a border around the table.
* 0=none, 1=dividing lines, 2=full */
char *fieldSep; /* field separator for unaligned text mode */
char *tableAttr; /* attributes for HTML <table ...> */
} printTableOpt;
@ -39,19 +44,20 @@ typedef struct _printTableOpt {
* - align is an 'l' or an 'r' for every column, if the output format needs it.
* (You must specify this long enough. Otherwise anything could happen.)
*/
void
printTable(const char * title, char ** headers, char ** cells, char ** footers,
void printTable(const char *title, char **headers, char **cells, char **footers,
const char *align,
const printTableOpt * opt, FILE *fout);
typedef struct _printQueryOpt {
typedef struct _printQueryOpt
{
printTableOpt topt; /* the options above */
char *nullPrint; /* how to print null entities */
bool quote; /* quote all values as much as possible */
char *title; /* override title */
char ** footers; /* override footer (default is "(xx rows)") */
char **footers; /* override footer (default is "(xx
* rows)") */
} printQueryOpt;
/*

View File

@ -99,9 +99,12 @@ get_prompt(PsqlSettings *pset, promptStatus_t status)
if (pset->db)
strncpy(buf, PQdb(pset->db), MAX_PROMPT_SIZE);
break;
case '~': {
case '~':
{
const char *var;
if (pset->db) {
if (pset->db)
{
if (strcmp(PQdb(pset->db), PQuser(pset->db)) == 0 ||
((var = getenv("PGDATABASE")) && strcmp(var, PQdb(pset->db)) == 0))
strcpy(buf, "~");
@ -113,8 +116,10 @@ get_prompt(PsqlSettings *pset, promptStatus_t status)
/* DB server hostname (long/short) */
case 'M':
case 'm':
if (pset->db) {
if (PQhost(pset->db)) {
if (pset->db)
{
if (PQhost(pset->db))
{
strncpy(buf, PQhost(pset->db), MAX_PROMPT_SIZE);
if (*p == 'm')
buf[strcspn(buf, ".")] = '\0';
@ -125,7 +130,8 @@ get_prompt(PsqlSettings *pset, promptStatus_t status)
break;
/* DB server port number */
case '>':
if (pset->db) {
if (pset->db)
{
if (PQhost(pset->db))
strncpy(buf, PQport(pset->db), MAX_PROMPT_SIZE);
else
@ -138,11 +144,20 @@ get_prompt(PsqlSettings *pset, promptStatus_t status)
strncpy(buf, PQuser(pset->db), MAX_PROMPT_SIZE);
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
long int l;
char *end;
l = strtol(p, &end, 0);
sprintf(buf, "%c", (unsigned char) l);
p = end - 1;
@ -150,7 +165,8 @@ get_prompt(PsqlSettings *pset, promptStatus_t status)
}
case 'R':
switch(status) {
switch (status)
{
case PROMPT_READY:
if (!pset->db)
buf[0] = '!';
@ -196,11 +212,13 @@ get_prompt(PsqlSettings *pset, promptStatus_t status)
FILE *fd = NULL;
char *file = strdup(p + 1);
int cmdend;
cmdend = strcspn(file, "`");
file[cmdend] = '\0';
if (file)
fd = popen(file, "r");
if (fd) {
if (fd)
{
fgets(buf, MAX_PROMPT_SIZE - 1, fd);
pclose(fd);
}
@ -217,6 +235,7 @@ get_prompt(PsqlSettings *pset, promptStatus_t status)
char *name;
const char *val;
int nameend;
name = strdup(p + 1);
nameend = strcspn(name, "$");
name[nameend] = '\0';
@ -245,12 +264,10 @@ get_prompt(PsqlSettings *pset, promptStatus_t status)
esc = false;
}
if (!esc) {
if (!esc)
strncat(destination, buf, MAX_PROMPT_SIZE - strlen(destination));
}
}
destination[MAX_PROMPT_SIZE] = '\0';
return destination;
}

View File

@ -3,7 +3,8 @@
#include "settings.h"
typedef enum _promptStatus {
typedef enum _promptStatus
{
PROMPT_READY,
PROMPT_CONTINUE,
PROMPT_COMMENT,

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: psqlHelp.h,v 1.80 1999/10/29 23:52:22 momjian Exp $
* $Id: psqlHelp.h,v 1.81 1999/11/04 23:14:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -384,5 +384,6 @@ TIMEZONE|XACTISOLEVEL|CLIENT_ENCODING|SERVER_ENCODING"},
\tVACUUM [VERBOSE] [ANALYZE] [table]\n\
\tor\n\
\tVACUUM [VERBOSE] ANALYZE [table [(column_name1, ...column_nameN)]];"},
{NULL, NULL, NULL} /* important to keep a NULL terminator here!*/
{NULL, NULL, NULL} /* important to keep a NULL terminator
* here! */
};

View File

@ -29,15 +29,18 @@ typedef struct _psqlSettings
char *gfname; /* one-shot file output argument for \g */
bool notty; /* stdin or stdout is not a tty (as determined on startup) */
bool notty; /* stdin or stdout is not a tty (as
* determined on startup) */
bool useReadline; /* use libreadline routines */
bool useHistory;
bool getPassword; /* prompt the user for a username and
password */
FILE * cur_cmd_source; /* describe the status of the current main loop */
* password */
FILE *cur_cmd_source; /* describe the status of the current main
* loop */
bool cur_cmd_interactive;
bool has_client_encoding; /* was PGCLIENTENCODING set on startup? */
bool has_client_encoding; /* was PGCLIENTENCODING set on
* startup? */
} PsqlSettings;

View File

@ -46,7 +46,9 @@ showVersion(PsqlSettings *pset, bool verbose);
/* Structures to pass information between the option parsing routine
* and the main function
*/
enum _actions { ACT_NOTHING = 0,
enum _actions
{
ACT_NOTHING = 0,
ACT_SINGLE_SLASH,
ACT_LIST_DB,
ACT_SHOW_VER,
@ -54,7 +56,8 @@ enum _actions { ACT_NOTHING = 0,
ACT_FILE
};
struct adhoc_opts {
struct adhoc_opts
{
char *dbname;
char *host;
char *port;
@ -118,7 +121,8 @@ main(int argc, char **argv)
if (options.action == ACT_LIST_DB || options.action == ACT_SHOW_VER)
options.dbname = "template1";
if (options.username) {
if (options.username)
{
if (strcmp(options.username, "?") == 0)
username = simple_prompt("Username: ", 100, true);
else
@ -129,12 +133,14 @@ main(int argc, char **argv)
password = simple_prompt("Password: ", 100, false);
/* loop until we have a password if requested by backend */
do {
do
{
need_pass = false;
settings.db = PQsetdbLogin(options.host, options.port, NULL, NULL, options.dbname, username, password);
if (PQstatus(settings.db) == CONNECTION_BAD &&
strcmp(PQerrorMessage(settings.db), "fe_sendauth: no password supplied\n")==0) {
strcmp(PQerrorMessage(settings.db), "fe_sendauth: no password supplied\n") == 0)
{
need_pass = true;
free(password);
password = NULL;
@ -145,19 +151,23 @@ main(int argc, char **argv)
free(username);
free(password);
if (PQstatus(settings.db) == CONNECTION_BAD) {
if (PQstatus(settings.db) == CONNECTION_BAD)
{
fprintf(stderr, "Connection to database '%s' failed.\n%s\n", PQdb(settings.db), PQerrorMessage(settings.db));
PQfinish(settings.db);
exit(EXIT_BADCONN);
}
if (options.action == ACT_LIST_DB) {
if (options.action == ACT_LIST_DB)
{
int success = listAllDbs(&settings);
PQfinish(settings.db);
exit(!success);
}
if (options.action == ACT_SHOW_VER) {
if (options.action == ACT_SHOW_VER)
{
showVersion(&settings, true);
PQfinish(settings.db);
exit(EXIT_SUCCESS);
@ -215,6 +225,7 @@ main(int argc, char **argv)
#ifdef WIN32
/* getopt is not in the standard includes on Win32 */
int getopt(int, char *const[], const char *);
#endif
static void
@ -255,6 +266,7 @@ parse_options(int argc, char *argv[], PsqlSettings * pset, struct adhoc_opts * o
};
int optindex;
#endif
extern char *optarg;
@ -266,7 +278,11 @@ parse_options(int argc, char *argv[], PsqlSettings * pset, struct adhoc_opts * o
#ifdef HAVE_GETOPT_LONG
while ((c = getopt_long(argc, argv, "Ac:d:eEf:F:lh:Hno:p:P:qsStT:uU:v:VWx?", long_options, &optindex)) != -1)
#else
/* Be sure to leave the '-' in here, so we can catch accidental long options. */
/*
* Be sure to leave the '-' in here, so we can catch accidental long
* options.
*/
while ((c = getopt(argc, argv, "Ac:d:eEf:F:lh:Hno:p:P:qsStT:uU:v:VWx?-")) != -1)
#endif
{
@ -326,12 +342,14 @@ parse_options(int argc, char *argv[], PsqlSettings * pset, struct adhoc_opts * o
equal_loc = strchr(value, '=');
if (!equal_loc)
result = do_pset(value, NULL, &pset->popt, true);
else {
else
{
*equal_loc = '\0';
result = do_pset(value, equal_loc + 1, &pset->popt, true);
}
if (!result) {
if (!result)
{
fprintf(stderr, "Couldn't set printing paramter %s.\n", value);
exit(EXIT_FAILURE);
}
@ -371,15 +389,19 @@ parse_options(int argc, char *argv[], PsqlSettings * pset, struct adhoc_opts * o
value = xstrdup(optarg);
equal_loc = strchr(value, '=');
if (!equal_loc) {
if (!DeleteVariable(pset->vars, value)) {
if (!equal_loc)
{
if (!DeleteVariable(pset->vars, value))
{
fprintf(stderr, "Couldn't delete variable %s.\n", value);
exit(EXIT_FAILURE);
}
}
else {
else
{
*equal_loc = '\0';
if (!SetVariable(pset->vars, value, equal_loc+1)) {
if (!SetVariable(pset->vars, value, equal_loc + 1))
{
fprintf(stderr, "Couldn't set variable %s to %s.\n", value, equal_loc);
exit(EXIT_FAILURE);
}
@ -412,8 +434,12 @@ parse_options(int argc, char *argv[], PsqlSettings * pset, struct adhoc_opts * o
}
}
/* if we still have arguments, use it as the database name and username */
while (argc - optind >= 1) {
/*
* if we still have arguments, use it as the database name and
* username
*/
while (argc - optind >= 1)
{
if (!options->dbname)
options->dbname = argv[optind];
else if (!options->username)
@ -449,9 +475,11 @@ process_psqlrc(PsqlSettings * pset)
/* Look for one in the home dir */
home = getenv("HOME");
if (home) {
if (home)
{
psqlrc = (char *) malloc(strlen(home) + 20);
if (!psqlrc) {
if (!psqlrc)
{
perror("malloc");
exit(EXIT_FAILURE);
}
@ -459,7 +487,8 @@ process_psqlrc(PsqlSettings * pset)
sprintf(psqlrc, "%s/.psqlrc-" PG_RELEASE "." PG_VERSION "." PG_SUBVERSION, home);
if (access(psqlrc, R_OK) == 0)
process_file(psqlrc, pset);
else {
else
{
sprintf(psqlrc, "%s/.psqlrc", home);
if (access(psqlrc, R_OK) == 0)
process_file(psqlrc, pset);
@ -484,21 +513,27 @@ showVersion(PsqlSettings *pset, bool verbose)
{
PGresult *res;
char *versionstr = NULL;
long int release = 0, version = 0, subversion = 0;
long int release = 0,
version = 0,
subversion = 0;
/* get backend version */
res = PSQLexec(pset, "SELECT version()");
if (PQresultStatus(res) == PGRES_TUPLES_OK)
versionstr = PQgetvalue(res, 0, 0);
if (!verbose) {
if (versionstr) puts(versionstr);
if (!verbose)
{
if (versionstr)
puts(versionstr);
PQclear(res);
return;
}
if (strncmp(versionstr, "PostgreSQL ", 11) == 0) {
if (strncmp(versionstr, "PostgreSQL ", 11) == 0)
{
char *tmp;
release = strtol(&versionstr[11], &tmp, 10);
version = strtol(tmp + 1, &tmp, 10);
subversion = strtol(tmp + 1, &tmp, 10);

View File

@ -2,11 +2,13 @@
#include <c.h>
#include "stringutils.h"
//#include <ctype.h>
//
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
//#include <stdio.h>
//
#include <stdio.h>
#include <postgres.h>
#ifndef HAVE_STRDUP
@ -34,21 +36,26 @@ unescape_quotes(char *source, char quote, char escape);
*
* Note that the string s is _not_ overwritten in this implementation.
*/
char * strtokx(const char *s,
char *
strtokx(const char *s,
const char *delim,
const char *quote,
char escape,
char *was_quoted,
unsigned int *token_pos)
{
static char * storage = NULL; /* store the local copy of the users string here */
static char * string = NULL; /* pointer into storage where to continue on next call */
static char *storage = NULL;/* store the local copy of the users
* string here */
static char *string = NULL; /* pointer into storage where to continue
* on next call */
/* variously abused variables: */
unsigned int offset;
char *start;
char *cp = NULL;
if (s) {
if (s)
{
free(storage);
storage = strdup(s);
string = storage;
@ -61,7 +68,8 @@ char * strtokx(const char *s,
offset = strspn(string, delim);
/* end of string reached */
if (string[offset] == '\0') {
if (string[offset] == '\0')
{
/* technically we don't need to free here, but we're nice */
free(storage);
storage = NULL;
@ -73,9 +81,11 @@ char * strtokx(const char *s,
if (quote)
cp = strchr(quote, string[offset]);
if (cp) {
if (cp)
{
/* okay, we have a quoting character, now scan for the closer */
char *p;
start = &string[offset + 1];
if (token_pos)
@ -91,7 +101,8 @@ char * strtokx(const char *s,
);
/* not yet end of string? */
if (*p != '\0') {
if (*p != '\0')
{
*p = '\0';
string = p + 1;
if (was_quoted)
@ -99,7 +110,8 @@ char * strtokx(const char *s,
unescape_quotes(start, *cp, escape);
return start;
}
else {
else
{
if (was_quoted)
*was_quoted = *cp;
string = p;
@ -119,13 +131,15 @@ char * strtokx(const char *s,
if (was_quoted)
*was_quoted = 0;
if (start[offset] != '\0') {
if (start[offset] != '\0')
{
start[offset] = '\0';
string = &start[offset] + 1;
return start;
}
else {
else
{
string = &start[offset];
return start;
}
@ -143,14 +157,16 @@ static void
unescape_quotes(char *source, char quote, char escape)
{
char *p;
char *destination, *tmp;
char *destination,
*tmp;
#ifdef USE_ASSERT_CHECKING
assert(source);
#endif
destination = (char *) calloc(1, strlen(source) + 1);
if (!destination) {
if (!destination)
{
perror("calloc");
exit(EXIT_FAILURE);
}
@ -161,7 +177,8 @@ unescape_quotes(char *source, char quote, char escape)
{
char c;
if (*p == escape && *(p+1) && quote == *(p+1)) {
if (*p == escape && *(p + 1) && quote == *(p + 1))
{
c = *(p + 1);
p++;
}

View File

@ -3,8 +3,7 @@
/* The cooler version of strtok() which knows about quotes and doesn't
* overwrite your input */
extern char *
strtokx(const char *s,
extern char *strtokx(const char *s,
const char *delim,
const char *quote,
char escape,

View File

@ -6,16 +6,19 @@
#include <assert.h>
VariableSpace CreateVariableSpace(void)
VariableSpace
CreateVariableSpace(void)
{
struct _variable *ptr;
ptr = calloc(1, sizeof *ptr);
if (!ptr) return NULL;
if (!ptr)
return NULL;
ptr->name = strdup("@");
ptr->value = strdup("");
if (!ptr->name || !ptr->value) {
if (!ptr->name || !ptr->value)
{
free(ptr->name);
free(ptr->value);
free(ptr);
@ -27,16 +30,19 @@ VariableSpace CreateVariableSpace(void)
const char * GetVariable(VariableSpace space, const char * name)
const char *
GetVariable(VariableSpace space, const char *name)
{
struct _variable *current;
if (!space)
return NULL;
if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name)) return NULL;
if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
return NULL;
for (current = space; current; current = current->next) {
for (current = space; current; current = current->next)
{
#ifdef USE_ASSERT_CHECKING
assert(current->name);
assert(current->value);
@ -50,16 +56,19 @@ const char * GetVariable(VariableSpace space, const char * name)
bool GetVariableBool(VariableSpace space, const char * name)
bool
GetVariableBool(VariableSpace space, const char *name)
{
return GetVariable(space, name) != NULL ? true : false;
}
bool SetVariable(VariableSpace space, const char * name, const char * value)
bool
SetVariable(VariableSpace space, const char *name, const char *value)
{
struct _variable *current, *previous;
struct _variable *current,
*previous;
if (!space)
return false;
@ -67,14 +76,17 @@ bool SetVariable(VariableSpace space, const char * name, const char * value)
if (!value)
return DeleteVariable(space, name);
if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name)) return false;
if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
return false;
for (current = space; current; previous = current, current = current->next) {
for (current = space; current; previous = current, current = current->next)
{
#ifdef USE_ASSERT_CHECKING
assert(current->name);
assert(current->value);
#endif
if (strcmp(current->name, name)==0) {
if (strcmp(current->name, name) == 0)
{
free(current->value);
current->value = strdup(value);
return current->value ? true : false;
@ -93,21 +105,26 @@ bool SetVariable(VariableSpace space, const char * name, const char * value)
bool DeleteVariable(VariableSpace space, const char * name)
bool
DeleteVariable(VariableSpace space, const char *name)
{
struct _variable *current, *previous;
struct _variable *current,
*previous;
if (!space)
return false;
if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name)) return false;
if (strspn(name, VALID_VARIABLE_CHARS) != strlen(name))
return false;
for (current = space, previous = NULL; current; previous = current, current = current->next) {
for (current = space, previous = NULL; current; previous = current, current = current->next)
{
#ifdef USE_ASSERT_CHECKING
assert(current->name);
assert(current->value);
#endif
if (strcmp(current->name, name)==0) {
if (strcmp(current->name, name) == 0)
{
free(current->name);
free(current->value);
if (previous)
@ -122,7 +139,8 @@ bool DeleteVariable(VariableSpace space, const char * name)
void DestroyVariableSpace(VariableSpace space)
void
DestroyVariableSpace(VariableSpace space)
{
if (!space)
return;

View File

@ -13,7 +13,8 @@
#define VALID_VARIABLE_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_"
struct _variable {
struct _variable
{
char *name;
char *value;
struct _variable *next;