diff options
author | Bruce Momjian <bruce@momjian.us> | 1999-11-04 23:14:30 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 1999-11-04 23:14:30 +0000 |
commit | 0e6652e67357354e01f2466184343d0bc0ee2cab (patch) | |
tree | 0c06450508417e033f8a2b90241a7126cd54c4fe /src/bin/psql/command.c | |
parent | 2323b63631080b7d4c287872a83b0ea30bd7874a (diff) |
psql cleanup
Diffstat (limited to 'src/bin/psql/command.c')
-rw-r--r-- | src/bin/psql/command.c | 1953 |
1 files changed, 1049 insertions, 904 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 6bcf96c9cda..29df2792625 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -7,9 +7,9 @@ #include <stdlib.h> #include <ctype.h> #ifndef WIN32 -#include <sys/types.h> /* for umask() */ -#include <sys/stat.h> /* for umask(), stat() */ -#include <unistd.h> /* for geteuid(), getpid(), stat() */ +#include <sys/types.h> /* for umask() */ +#include <sys/stat.h> /* for umask(), stat() */ +#include <unistd.h> /* for geteuid(), getpid(), stat() */ #endif #include <assert.h> @@ -35,21 +35,20 @@ /* functions for use in this file only */ -static backslashResult -exec_command(const char * cmd, - char * const * options, - const char * options_string, - PQExpBuffer query_buf, - PsqlSettings * pset); +static backslashResult exec_command(const char *cmd, + char *const * options, + const char *options_string, + PQExpBuffer query_buf, + PsqlSettings *pset); static bool -do_edit(const char *filename_arg, PQExpBuffer query_buf); + do_edit(const char *filename_arg, PQExpBuffer query_buf); static char * -unescape(const char * source, PsqlSettings * pset); + unescape(const char *source, PsqlSettings *pset); static bool -do_shell(const char *command); + do_shell(const char *command); @@ -72,538 +71,616 @@ do_shell(const char *command); backslashResult HandleSlashCmds(PsqlSettings *pset, - const char *line, - PQExpBuffer query_buf, - const char ** end_of_cmd) + const char *line, + PQExpBuffer query_buf, + const char **end_of_cmd) { - backslashResult status = CMD_SKIP_LINE; - char * my_line; - char * options[17] ={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - char * token; - const char * options_string = NULL; - const char * cmd; - size_t blank_loc; - int i; - 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 */ - blank_loc = strcspn(my_line, " \t"); - - /* do we have an option string? */ - if (my_line[blank_loc] != '\0') { - options_string = &my_line[blank_loc+1]; - - my_line[blank_loc] = '\0'; - } - - if (options_string) { - char quote; - unsigned int pos; - options_string = &options_string[strspn(options_string, " \t")]; /* skip leading whitespace */ - - i = 0; - token = strtokx(options_string, " \t", "\"'`", '\\', "e, &pos); - - for (i = 0; token && i<16; i++) { - switch(quote) { - case '"': - options[i] = unescape(token, pset); - break; - case '\'': - options[i] = xstrdup(token); - break; - case '`': - { - bool error = false; - FILE * fd = NULL; - char * file = unescape(token, pset); - PQExpBufferData output; - char buf[512]; - size_t result; - - fd = popen(file, "r"); - if (!fd) { - perror(file); - error = true; - } + backslashResult status = CMD_SKIP_LINE; + char *my_line; + char *options[17] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + char *token; + const char *options_string = NULL; + const char *cmd; + size_t blank_loc; + int i; + 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 + */ + blank_loc = strcspn(my_line, " \t"); + + /* do we have an option string? */ + if (my_line[blank_loc] != '\0') + { + options_string = &my_line[blank_loc + 1]; - if (!error) { - initPQExpBuffer(&output); + my_line[blank_loc] = '\0'; + } - do { - result = fread(buf, 1, 512, fd); - if (ferror(fd)) { - perror(file); - error = true; - break; + if (options_string) + { + char quote; + unsigned int pos; + + options_string = &options_string[strspn(options_string, " \t")]; /* skip leading + * whitespace */ + + i = 0; + token = strtokx(options_string, " \t", "\"'`", '\\', "e, &pos); + + for (i = 0; token && i < 16; i++) + { + switch (quote) + { + case '"': + options[i] = unescape(token, pset); + break; + case '\'': + options[i] = xstrdup(token); + break; + case '`': + { + bool error = false; + FILE *fd = NULL; + char *file = unescape(token, pset); + PQExpBufferData output; + char buf[512]; + size_t result; + + fd = popen(file, "r"); + if (!fd) + { + perror(file); + error = true; + } + + if (!error) + { + initPQExpBuffer(&output); + + do + { + result = fread(buf, 1, 512, fd); + if (ferror(fd)) + { + perror(file); + error = true; + break; + } + appendBinaryPQExpBuffer(&output, buf, result); + } while (!feof(fd)); + appendPQExpBufferChar(&output, '\0'); + + if (pclose(fd) == -1) + { + perror(file); + error = true; + } + } + + if (!error) + { + if (output.data[strlen(output.data) - 1] == '\n') + output.data[strlen(output.data) - 1] = '\0'; + } + + free(file); + if (!error) + options[i] = output.data; + else + { + options[i] = xstrdup(""); + termPQExpBuffer(&output); + } + break; + } + case 0: + default: + if (token[0] == '\\') + continue_parse = options_string + pos; + else if (token[0] == '$') + options[i] = xstrdup(interpolate_var(token + 1, pset)); + else + options[i] = xstrdup(token); + break; } - appendBinaryPQExpBuffer(&output, buf, result); - } while (!feof(fd)); - appendPQExpBufferChar(&output, '\0'); - - if (pclose(fd) == -1) { - perror(file); - error = true; - } - } - if (!error) { - if (output.data[strlen(output.data)-1] == '\n') - output.data[strlen(output.data)-1] = '\0'; - } + if (continue_parse) + break; - free(file); - if (!error) - options[i] = output.data; - else { - options[i] = xstrdup(""); - termPQExpBuffer(&output); + token = strtokx(NULL, " \t", "\"'`", '\\', "e, &pos); } - break; - } - case 0: - default: - if (token[0] == '\\') - continue_parse = options_string + pos; - else if (token[0] == '$') - options[i] = xstrdup(interpolate_var(token+1, pset)); - else - options[i] = xstrdup(token); - break; - } - - if (continue_parse) - break; - - token = strtokx(NULL, " \t", "\"'`", '\\', "e, &pos); } - } - cmd = my_line; + cmd = my_line; - status = exec_command(cmd, options, options_string, query_buf, 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. */ - const char * new_options[17]; - char new_cmd[2]; - int i; + if (status == CMD_UNKNOWN) + { - for (i=1; i<17; i++) - new_options[i] = options[i-1]; - new_options[0] = cmd+1; + /* + * 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; - new_cmd[0] = cmd[0]; - new_cmd[1] = '\0'; + for (i = 1; i < 17; i++) + new_options[i] = options[i - 1]; + new_options[0] = cmd + 1; + + new_cmd[0] = cmd[0]; + new_cmd[1] = '\0'; + + status = exec_command(new_cmd, (char *const *) new_options, my_line + 2, query_buf, pset); + } - status = exec_command(new_cmd, (char * const *)new_options, my_line+2, query_buf, pset); - } + if (status == CMD_UNKNOWN) + { + fprintf(stderr, "Unrecognized command: \\%s. Try \\? for help.\n", cmd); + status = CMD_ERROR; + } - if (status == CMD_UNKNOWN) { - fprintf(stderr, "Unrecognized command: \\%s. Try \\? for help.\n", cmd); - status = CMD_ERROR; - } - - if (continue_parse && *(continue_parse+1) == '\\') - continue_parse+=2; + if (continue_parse && *(continue_parse + 1) == '\\') + continue_parse += 2; - if (end_of_cmd) { - if (continue_parse) - *end_of_cmd = line + (continue_parse - my_line); - else - *end_of_cmd = NULL; - } + if (end_of_cmd) + { + if (continue_parse) + *end_of_cmd = line + (continue_parse - my_line); + else + *end_of_cmd = NULL; + } - /* clean up */ - for (i = 0; i<16 && options[i]; i++) - free(options[i]); + /* clean up */ + for (i = 0; i < 16 && options[i]; i++) + free(options[i]); - free(my_line); + free(my_line); - return status; + return status; } static backslashResult -exec_command(const char * cmd, - char * const * options, - const char * options_string, - PQExpBuffer query_buf, - PsqlSettings * pset) +exec_command(const char *cmd, + char *const * options, + const char *options_string, + PQExpBuffer query_buf, + PsqlSettings *pset) { - bool success = true; /* indicate here if the command ran ok or failed */ - bool quiet = GetVariableBool(pset->vars, "quiet"); + bool success = true; /* indicate here if the command ran ok or + * failed */ + bool quiet = GetVariableBool(pset->vars, "quiet"); - backslashResult status = CMD_SKIP_LINE; + 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) { - if (pset->popt.topt.format != PRINT_ALIGNED) - success = do_pset("format", "aligned", &pset->popt, quiet); - else - success = do_pset("format", "unaligned", &pset->popt, quiet); - } - - - /* \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 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 { - if (options[0]) - /* gave database name */ - 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); + /* + * \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 + success = do_pset("format", "unaligned", &pset->popt, quiet); } - } - - - /* \copy */ - else if (strcmp(cmd, "copy") == 0) - success = do_copy(options_string, pset); - - /* \copyright */ - else if (strcmp(cmd, "copyright") == 0) - print_copyright(); - - /* \d* commands */ - 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 */ - break; - case 'a': - success = describeAggregates(options[0], pset); - break; - case 'd': - success = objectDescription(options[0], pset); - break; - case 'f': - success = describeFunctions(options[0], pset); - break; - case 'l': - success = do_lo_list(pset); - break; - case 'o': - success = describeOperators(options[0], pset); - break; - case 'p': - success = permissionsList(options[0], pset); - break; - case 'T': - success = describeTypes(options[0], pset); - break; - case 't': case 'v': case 'i': case 's': case 'S': - if (cmd[1] == 'S' && cmd[2] == '\0') - success = listTables("Stvs", NULL, pset); - else - success = listTables(&cmd[1], options[0], pset); - break; - default: - status = CMD_UNKNOWN; + + + /* + * \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 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 + { + if (options[0]) + /* gave database name */ + 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); + } } - } - /* \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; + /* \copy */ + else if (strcmp(cmd, "copy") == 0) + success = do_copy(options_string, pset); + /* \copyright */ + else if (strcmp(cmd, "copyright") == 0) + print_copyright(); - /* \echo */ - else if (strcmp(cmd, "echo") == 0) { - int i; - for (i=0; i<16 && options[i]; i++) - fputs(options[i], stdout); - fputs("\n", stdout); - } + /* \d* commands */ + 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 */ + break; + case 'a': + success = describeAggregates(options[0], pset); + break; + case 'd': + success = objectDescription(options[0], pset); + break; + case 'f': + success = describeFunctions(options[0], pset); + break; + case 'l': + success = do_lo_list(pset); + break; + case 'o': + success = describeOperators(options[0], pset); + break; + case 'p': + success = permissionsList(options[0], pset); + break; + case 'T': + success = describeTypes(options[0], pset); + break; + case 't': + case 'v': + case 'i': + case 's': + case 'S': + if (cmd[1] == 'S' && cmd[2] == '\0') + success = listTables("Stvs", NULL, pset); + else + success = listTables(&cmd[1], options[0], pset); + break; + default: + status = CMD_UNKNOWN; + } + } - /* \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); + /* + * \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; - /* \g means send query */ - else if (strcmp(cmd, "g") == 0) { - if (!options[0]) - pset->gfname = NULL; - else - pset->gfname = xstrdup(options[0]); - status = CMD_SEND; - } - /* help */ - else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0) - helpSQL(options_string); + /* \echo */ + else if (strcmp(cmd, "echo") == 0) + { + int i; + for (i = 0; i < 16 && options[i]; i++) + fputs(options[i], stdout); + fputs("\n", stdout); + } - /* HTML mode */ - else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0) - success = do_pset("format", "html", &pset->popt, quiet); + /* + * \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); - /* \i is include file */ - else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0) - { - if (!options[0]) { - fputs("Usage: \\i <filename>\n", stderr); - success = false; + /* \g means send query */ + else if (strcmp(cmd, "g") == 0) + { + if (!options[0]) + pset->gfname = NULL; + else + pset->gfname = xstrdup(options[0]); + status = CMD_SEND; } - else - success = process_file(options[0], pset); - } - - /* \l is list databases */ - else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0) - success = listAllDbs(pset); - - - /* large object things */ - 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; - } - else - success = do_lo_export(pset, options[0], options[1]); + + /* help */ + else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0) + helpSQL(options_string); + + + /* HTML mode */ + else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0) + success = do_pset("format", "html", &pset->popt, quiet); + + + /* \i is include file */ + else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0) + { + if (!options[0]) + { + fputs("Usage: \\i <filename>\n", stderr); + success = false; + } + else + success = process_file(options[0], pset); } - else if (strcmp(cmd+3, "import") == 0) { - if (!options[0]) { - fputs("Usage: \\lo_import <filename> [<description>]\n", stderr); - success = false; - } - else - success = do_lo_import(pset, options[0], options[1]); + /* \l is list databases */ + else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0) + success = listAllDbs(pset); + + + /* large object things */ + 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; + } + else + success = do_lo_export(pset, options[0], options[1]); + } + + else if (strcmp(cmd + 3, "import") == 0) + { + if (!options[0]) + { + fputs("Usage: \\lo_import <filename> [<description>]\n", stderr); + success = false; + } + else + success = do_lo_import(pset, options[0], options[1]); + } + + else if (strcmp(cmd + 3, "list") == 0) + success = do_lo_list(pset); + + else if (strcmp(cmd + 3, "unlink") == 0) + { + if (!options[0]) + { + fputs("Usage: \\lo_unlink <loid>\n", stderr); + success = false; + } + else + success = do_lo_unlink(pset, options[0]); + } + + else + status = CMD_UNKNOWN; } - else if (strcmp(cmd+3, "list") == 0) - success = do_lo_list(pset); + /* \o -- set query output */ + else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0) + success = setQFout(options[0], pset); - else if (strcmp(cmd+3, "unlink") == 0) { - if (!options[0]) { - fputs("Usage: \\lo_unlink <loid>\n", stderr); - success = false; - } - else - success = do_lo_unlink(pset, options[0]); + + /* \p prints the current query buffer */ + else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0) + { + if (query_buf && query_buf->len > 0) + puts(query_buf->data); + else if (!GetVariableBool(pset->vars, "quiet")) + puts("Query buffer is empty."); } - else - status = CMD_UNKNOWN; - } - - /* \o -- set query output */ - else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0) - success = setQFout(options[0], pset); - - - /* \p prints the current query buffer */ - else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0 ) - { - if (query_buf && query_buf->len > 0) - puts(query_buf->data); - else if (!GetVariableBool(pset->vars, "quiet")) - puts("Query buffer is empty."); - } - - /* \pset -- set printing parameters */ - else if (strcmp(cmd, "pset")==0) { - if (!options[0]) { - fputs("Usage: \\pset <parameter> [<value>]\n", stderr); - success = false; + /* \pset -- set printing parameters */ + else if (strcmp(cmd, "pset") == 0) + { + if (!options[0]) + { + fputs("Usage: \\pset <parameter> [<value>]\n", stderr); + success = false; + } + else + success = do_pset(options[0], options[1], &pset->popt, quiet); } - else - success = do_pset(options[0], options[1], &pset->popt, quiet); - } - - /* \q or \quit */ - else if (strcmp(cmd, "q")==0 || strcmp(cmd, "quit")==0) - status = CMD_TERMINATE; - - /* \qecho */ - 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); - } - - /* reset(clear) the buffer */ - else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0) - { - resetPQExpBuffer(query_buf); - if (!quiet) puts("Query buffer reset (cleared)."); - } - - - /* \s save history in a file or show it on the screen */ - else if (strcmp(cmd, "s")==0) - { - const char * fname; - if (!options[0]) - fname = "/dev/tty"; - else - fname = options[0]; - - success = saveHistory(fname); - - if (success && !quiet && options[0]) - printf("Wrote history to %s.\n", fname); - } - - - /* \set -- generalized set option command */ - else if (strcmp(cmd, "set")==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.) */ - 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; + + /* \q or \quit */ + else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0) + status = CMD_TERMINATE; + + /* \qecho */ + 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); } - else { - if (!SetVariable(pset->vars, options[0], options[1])) { - fprintf(stderr, "Set variable failed.\n"); - success = false; - } + + /* reset(clear) the buffer */ + else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0) + { + resetPQExpBuffer(query_buf); + if (!quiet) + puts("Query buffer reset (cleared)."); } - } - /* \t -- turn off headers and row count */ - else if (strcmp(cmd, "t")==0) - success = do_pset("tuples_only", NULL, &pset->popt, quiet); + /* \s save history in a file or show it on the screen */ + else if (strcmp(cmd, "s") == 0) + { + const char *fname; + + if (!options[0]) + fname = "/dev/tty"; + else + fname = options[0]; - /* \T -- define html <table ...> attributes */ - else if (strcmp(cmd, "T")==0) - success = do_pset("tableattr", options[0], &pset->popt, quiet); + success = saveHistory(fname); + if (success && !quiet && options[0]) + printf("Wrote history to %s.\n", fname); + } - /* \w -- write query buffer to file */ - else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0 ) - { - FILE *fd = NULL; - bool pipe = false; - if (!options[0]) { - fprintf(stderr, "Usage \\%s <filename>\n", cmd); - success = false; + /* \set -- generalized set option command */ + else if (strcmp(cmd, "set") == 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.) + */ + 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])) + { + fprintf(stderr, "Set variable failed.\n"); + success = false; + } + } } - else { - if (options[0][0] == '|') { - pipe = true; + + /* \t -- turn off headers and row count */ + else if (strcmp(cmd, "t") == 0) + success = do_pset("tuples_only", NULL, &pset->popt, quiet); + + + /* \T -- define html <table ...> attributes */ + else if (strcmp(cmd, "T") == 0) + success = do_pset("tableattr", options[0], &pset->popt, quiet); + + + /* \w -- write query buffer to file */ + else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0) + { + FILE *fd = NULL; + bool pipe = false; + + if (!options[0]) + { + fprintf(stderr, "Usage \\%s <filename>\n", cmd); + success = false; + } + else + { + if (options[0][0] == '|') + { + pipe = true; #ifndef __CYGWIN32__ - fd = popen(&options[0][1], "w"); + fd = popen(&options[0][1], "w"); #else - fd = popen(&options[0][1], "wb"); + fd = popen(&options[0][1], "wb"); #endif - } - else { + } + else + { #ifndef __CYGWIN32__ - fd = fopen(options[0], "w"); + fd = fopen(options[0], "w"); #else - fd = fopen(options[0], "wb"); + fd = fopen(options[0], "wb"); #endif - } + } - if (!fd) { - perror(options[0]); - success = false; - } - } + if (!fd) + { + perror(options[0]); + success = false; + } + } - if (fd) { - int result; + if (fd) + { + int result; - if (query_buf && query_buf->len > 0) - fprintf(fd, "%s\n", query_buf->data); + if (query_buf && query_buf->len > 0) + fprintf(fd, "%s\n", query_buf->data); - if (pipe) - result = pclose(fd); - else - result = fclose(fd); + if (pipe) + result = pclose(fd); + else + result = fclose(fd); - if (result == EOF) { - perror("close"); - success = false; - } + if (result == EOF) + { + perror("close"); + success = false; + } + } } - } - /* \x -- toggle expanded table representation */ - else if (strcmp(cmd, "x")==0) - success = do_pset("expanded", NULL, &pset->popt, quiet); + /* \x -- toggle expanded table representation */ + else if (strcmp(cmd, "x") == 0) + success = do_pset("expanded", NULL, &pset->popt, quiet); - /* list table rights (grant/revoke) */ - else if (strcmp(cmd, "z")==0) - success = permissionsList(options[0], pset); - + /* list table rights (grant/revoke) */ + else if (strcmp(cmd, "z") == 0) + success = permissionsList(options[0], pset); - else if (strcmp(cmd, "!")==0) - success = do_shell(options_string); - else if (strcmp(cmd, "?")==0) - slashUsage(pset); + else if (strcmp(cmd, "!") == 0) + success = do_shell(options_string); + + else if (strcmp(cmd, "?") == 0) + slashUsage(pset); #ifdef NOT_USED - /* 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]); - } + + /* + * 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 { - status = CMD_UNKNOWN; - } + else + status = CMD_UNKNOWN; - if (!success) status = CMD_ERROR; - return status; + if (!success) + status = CMD_ERROR; + return status; } @@ -617,104 +694,119 @@ exec_command(const char * cmd, * The return value is malloc()'ed. */ static char * -unescape(const char * source, PsqlSettings * pset) +unescape(const char *source, PsqlSettings *pset) { - unsigned char *p; - bool esc = false; /* Last character we saw was the - escape character */ - char *destination, *tmp; - size_t length; + unsigned char *p; + bool esc = false; /* Last character we saw was the escape + * character */ + char *destination, + *tmp; + size_t length; #ifdef USE_ASSERT_CHECKING - assert(source); + assert(source); #endif - length = strlen(source)+1; - - tmp = destination = (char *) malloc(length); - if (!tmp) { - perror("malloc"); - exit(EXIT_FAILURE); - } - - for (p = (char *) source; *p; p += PQmblen(p)) { - if (esc) { - char c; - - switch (*p) - { - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - 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': - { - long int l; - char * end; - l = strtol(p, &end, 0); - c = l; - p = end-1; - break; - } - default: - c = *p; - } - *tmp++ = c; - esc = false; - } + length = strlen(source) + 1; - else if (*p == '\\') { - esc = true; + tmp = destination = (char *) malloc(length); + if (!tmp) + { + perror("malloc"); + exit(EXIT_FAILURE); } - else if (*p == '$') + for (p = (char *) source; *p; p += PQmblen(p)) { - if (*(p+1) == '{') { - unsigned int len; - char *copy; - const char *value; - void * new; - len = strcspn(p+2, "}"); - copy = xstrdup(p+2); - copy[len] = '\0'; - value = interpolate_var(copy, pset); - - length += strlen(value) - (len+3); - new = realloc(destination, length); - if (!new) { - perror("realloc"); - exit(EXIT_FAILURE); + if (esc) + { + char c; + + switch (*p) + { + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + 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': + { + long int l; + char *end; + + l = strtol(p, &end, 0); + c = l; + p = end - 1; + break; + } + default: + c = *p; + } + *tmp++ = c; + esc = false; + } + + else if (*p == '\\') + esc = true; + + else if (*p == '$') + { + if (*(p + 1) == '{') + { + unsigned int len; + char *copy; + const char *value; + void *new; + + len = strcspn(p + 2, "}"); + copy = xstrdup(p + 2); + copy[len] = '\0'; + value = interpolate_var(copy, pset); + + length += strlen(value) - (len + 3); + new = realloc(destination, length); + if (!new) + { + perror("realloc"); + exit(EXIT_FAILURE); + } + tmp = new + (tmp - destination); + destination = new; + + strcpy(tmp, value); + tmp += strlen(value); + p += len + 2; + free(copy); + } + else + *tmp++ = '$'; } - tmp = new + (tmp - destination); - destination = new; - - strcpy(tmp, value); - tmp += strlen(value); - p += len + 2; - free(copy); - } - else { - *tmp++ = '$'; - } - } - else { - *tmp++ = *p; - esc = false; + else + { + *tmp++ = *p; + esc = false; + } } - } - *tmp = '\0'; - return destination; + *tmp = '\0'; + return destination; } @@ -731,109 +823,120 @@ unescape(const char * source, PsqlSettings * pset) * but the old one was set back. Otherwise it terminates the program. */ bool -do_connect(const char *new_dbname, const char *new_user, PsqlSettings * pset) +do_connect(const char *new_dbname, const char *new_user, PsqlSettings *pset) { - PGconn *oldconn = pset->db; - const char *dbparam = NULL; - const char *userparam = NULL; - char *pwparam = NULL; - char * prompted_password = NULL; - char * prompted_user = NULL; - bool need_pass; - bool success = false; - - /* If dbname is "-" then use old name, else new one (even if NULL) */ - if (new_dbname && PQdb(oldconn) && (strcmp(new_dbname, "-") == 0 || strcmp(new_dbname, PQdb(oldconn))==0)) - dbparam = PQdb(oldconn); - else - 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 )) { - 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() */ - else - userparam = new_user; - - /* need to prompt for password? */ - if (pset->getPassword) - 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) */ - if (!pwparam) - pwparam = PQpass(oldconn); + PGconn *oldconn = pset->db; + const char *dbparam = NULL; + const char *userparam = NULL; + char *pwparam = NULL; + char *prompted_password = NULL; + char *prompted_user = NULL; + bool need_pass; + bool success = false; + + /* If dbname is "-" then use old name, else new one (even if NULL) */ + if (new_dbname && PQdb(oldconn) && (strcmp(new_dbname, "-") == 0 || strcmp(new_dbname, PQdb(oldconn)) == 0)) + dbparam = PQdb(oldconn); + else + 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)) + 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() */ + else + userparam = new_user; + + /* need to prompt for password? */ + if (pset->getPassword) + 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) + */ + 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 - */ - - if (!pset->has_client_encoding) - putenv("PGCLIENTENCODING="); + + /* + * 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 { - 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) { - need_pass = true; - free(prompted_password); - prompted_password = NULL; - pwparam = prompted_password = simple_prompt("Password: ", 100, false); - } - } while (need_pass); - - 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 (!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 */ - fputs("Terminating.\n", stderr); - if (oldconn) - PQfinish(oldconn); - pset->db = NULL; - } - else { - fputs("Keeping old connection.\n", stderr); - pset->db = oldconn; - } - } - 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 */ - printf("You are now connected to database %s as user %s.\n", - PQdb(pset->db), PQuser(pset->db)); + 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) + { + need_pass = true; + free(prompted_password); + prompted_password = NULL; + pwparam = prompted_password = simple_prompt("Password: ", 100, false); + } + } while (need_pass); + + 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 (!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 */ + fputs("Terminating.\n", stderr); + if (oldconn) + PQfinish(oldconn); + pset->db = NULL; + } + else + { + fputs("Keeping old connection.\n", stderr); + pset->db = oldconn; + } } + 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 */ + printf("You are now connected to database %s as user %s.\n", + PQdb(pset->db), PQuser(pset->db)); + } - if (oldconn) - PQfinish(oldconn); + if (oldconn) + PQfinish(oldconn); - success = true; - } + success = true; + } - return success; + return success; } @@ -848,35 +951,36 @@ do_connect(const char *new_dbname, const char *new_user, PsqlSettings * pset) static bool editFile(const char *fname) { - char *editorName; - char *sys; - int result; + char *editorName; + char *sys; + int result; #ifdef USE_ASSERT_CHECKING - assert(fname); + assert(fname); #else - if (!fname) return false; + if (!fname) + return false; #endif - /* Find an editor to use */ - editorName = getenv("PSQL_EDITOR"); - if (!editorName) - editorName = getenv("EDITOR"); - if (!editorName) - editorName = getenv("VISUAL"); - if (!editorName) - editorName = DEFAULT_EDITOR; - - sys = malloc(strlen(editorName) + strlen(fname) + 32 + 1); - if (!sys) - return false; - sprintf(sys, "exec %s %s", editorName, fname); - result = system(sys); - if (result == -1 || result == 127) - perror(sys); - free(sys); - - return result==0; + /* Find an editor to use */ + editorName = getenv("PSQL_EDITOR"); + if (!editorName) + editorName = getenv("EDITOR"); + if (!editorName) + editorName = getenv("VISUAL"); + if (!editorName) + editorName = DEFAULT_EDITOR; + + sys = malloc(strlen(editorName) + strlen(fname) + 32 + 1); + if (!sys) + return false; + sprintf(sys, "exec %s %s", editorName, fname); + result = system(sys); + if (result == -1 || result == 127) + perror(sys); + free(sys); + + return result == 0; } @@ -884,117 +988,135 @@ editFile(const char *fname) static bool do_edit(const char *filename_arg, PQExpBuffer query_buf) { - char fnametmp[64]; - FILE * stream; - const char *fname; - bool error = false; + char fnametmp[64]; + 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); + assert(query_buf); #else - if (!query_buf) return false; + if (!query_buf) + return false; #endif - if (filename_arg) - fname = filename_arg; + if (filename_arg) + fname = filename_arg; - else { - /* make a temp file to edit */ + else + { + /* make a temp file to edit */ #ifndef WIN32 - mode_t oldumask; + mode_t oldumask; - sprintf(fnametmp, "/tmp/psql.edit.%ld.%ld", (long) geteuid(), (long) getpid()); + sprintf(fnametmp, "/tmp/psql.edit.%ld.%ld", (long) geteuid(), (long) getpid()); #else - GetTempFileName(".", "psql", 0, fnametmp); + GetTempFileName(".", "psql", 0, fnametmp); #endif - fname = (const char *)fnametmp; + fname = (const char *) fnametmp; #ifndef WIN32 - oldumask = umask(0177); + oldumask = umask(0177); #endif - stream = fopen(fname, "w"); + stream = fopen(fname, "w"); #ifndef WIN32 - umask(oldumask); + umask(oldumask); #endif - if (!stream) { - perror(fname); - error = true; + if (!stream) + { + perror(fname); + error = true; + } + else + { + unsigned int ql = query_buf->len; + + if (ql == 0 || query_buf->data[ql - 1] != '\n') + { + appendPQExpBufferChar(query_buf, '\n'); + ql++; + } + + if (fwrite(query_buf->data, 1, ql, stream) != ql) + { + perror(fname); + fclose(stream); + remove(fname); + error = true; + } + else + fclose(stream); + } } - else { - unsigned int ql = query_buf->len; - if (ql == 0 || query_buf->data[ql - 1] != '\n') { - appendPQExpBufferChar(query_buf, '\n'); - ql++; - } - - if (fwrite(query_buf->data, 1, ql, stream) != ql) { + +#ifndef WIN32 + if (!error && stat(fname, &before) != 0) + { perror(fname); - fclose(stream); - remove(fname); error = true; - } - else - fclose(stream); } - } - -#ifndef WIN32 - if (!error && stat(fname, &before) != 0) { - perror(fname); - error = true; - } #endif - /* call editor */ - if (!error) - error = !editFile(fname); + /* call editor */ + if (!error) + error = !editFile(fname); #ifndef WIN32 - if (!error && stat(fname, &after) !=0) { - perror(fname); - error = true; - } + 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) { - perror(fname); - error = true; - } - else { - /* read file back in */ - char line[1024]; - size_t result; - - resetPQExpBuffer(query_buf); - do { - result = fread(line, 1, 1024, stream); - if (ferror(stream)) { - perror(fname); - error = true; - break; + stream = fopen(fname, "r"); + if (!stream) + { + perror(fname); + error = true; + } + else + { + /* read file back in */ + char line[1024]; + size_t result; + + resetPQExpBuffer(query_buf); + do + { + result = fread(line, 1, 1024, stream); + if (ferror(stream)) + { + perror(fname); + error = true; + break; + } + appendBinaryPQExpBuffer(query_buf, line, result); + } while (!feof(stream)); + appendPQExpBufferChar(query_buf, '\0'); + + fclose(stream); } - appendBinaryPQExpBuffer(query_buf, line, result); - } while (!feof(stream)); - appendPQExpBufferChar(query_buf, '\0'); - fclose(stream); + /* remove temp file */ + if (!filename_arg) + remove(fname); } - /* remove temp file */ - if (!filename_arg) - remove(fname); - } - - return !error; + return !error; } @@ -1008,26 +1130,27 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf) bool process_file(const char *filename, PsqlSettings *pset) { - FILE *fd; - int result; + FILE *fd; + int result; - if (!filename) - return false; + if (!filename) + return false; #ifdef __CYGWIN32__ - fd = fopen(filename, "rb"); + fd = fopen(filename, "rb"); #else - fd = fopen(filename, "r"); + fd = fopen(filename, "r"); #endif - if (!fd) { - perror(filename); - return false; - } + if (!fd) + { + perror(filename); + return false; + } - result = MainLoop(pset, fd); - fclose(fd); - return (result == EXIT_SUCCESS); + result = MainLoop(pset, fd); + fclose(fd); + return (result == EXIT_SUCCESS); } @@ -1039,158 +1162,178 @@ process_file(const char *filename, PsqlSettings *pset) static const char * _align2string(enum printFormat in) { - switch (in) { - case PRINT_NOTHING: - return "nothing"; - break; - case PRINT_UNALIGNED: - return "unaligned"; - break; - case PRINT_ALIGNED: - return "aligned"; - break; - case PRINT_HTML: - return "html"; - break; - case PRINT_LATEX: - return "latex"; - break; - } - return "unknown"; + switch (in) + { + case PRINT_NOTHING: + return "nothing"; + break; + case PRINT_UNALIGNED: + return "unaligned"; + break; + case PRINT_ALIGNED: + return "aligned"; + break; + case PRINT_HTML: + return "html"; + break; + case PRINT_LATEX: + return "latex"; + break; + } + return "unknown"; } bool -do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet) +do_pset(const char *param, const char *value, printQueryOpt * popt, bool quiet) { - size_t vallen = 0; + size_t vallen = 0; + #ifdef USE_ASSERT_CHECKING - assert(param); + 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 (!value) - ; - else if (strncasecmp("unaligned", value, vallen)==0) - popt->topt.format = PRINT_UNALIGNED; - else if (strncasecmp("aligned", value, vallen)==0) - popt->topt.format = PRINT_ALIGNED; - else if (strncasecmp("html", value, vallen)==0) - popt->topt.format = PRINT_HTML; - else if (strncasecmp("latex", value, vallen)==0) - popt->topt.format = PRINT_LATEX; - else { - fprintf(stderr, "Allowed formats are unaligned, aligned, html, latex.\n"); - return false; + if (value) + vallen = strlen(value); + + /* set format */ + if (strcmp(param, "format") == 0) + { + if (!value) + ; + else if (strncasecmp("unaligned", value, vallen) == 0) + popt->topt.format = PRINT_UNALIGNED; + else if (strncasecmp("aligned", value, vallen) == 0) + popt->topt.format = PRINT_ALIGNED; + else if (strncasecmp("html", value, vallen) == 0) + popt->topt.format = PRINT_HTML; + else if (strncasecmp("latex", value, vallen) == 0) + popt->topt.format = PRINT_LATEX; + else + { + fprintf(stderr, "Allowed formats are unaligned, aligned, html, latex.\n"); + return false; + } + + if (!quiet) + printf("Output format is %s.\n", _align2string(popt->topt.format)); } - if (!quiet) - printf("Output format is %s.\n", _align2string(popt->topt.format)); - } + /* set border style/width */ + else if (strcmp(param, "border") == 0) + { + if (value) + popt->topt.border = atoi(value); - /* set border style/width */ - else if (strcmp(param, "border")==0) { - if (value) - popt->topt.border = atoi(value); - - if (!quiet) - printf("Border style is %d.\n", popt->topt.border); - } - - /* set expanded/vertical mode */ - 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) { - free(popt->nullPrint); - popt->nullPrint = xstrdup(value); - } - if (!quiet) - printf("Null display is \"%s\".\n", popt->nullPrint ? popt->nullPrint : ""); - } - - /* field separator for unaligned text */ - else if (strcmp(param, "fieldsep")==0) { - if (value) { - free(popt->topt.fieldSep); - popt->topt.fieldSep = xstrdup(value); + if (!quiet) + printf("Border style is %d.\n", popt->topt.border); } - if (!quiet) - printf("Field separator is \"%s\".\n", popt->topt.fieldSep); - } - - /* toggle between full and barebones format */ - else if (strcmp(param, "t")==0 || strcmp(param, "tuples_only")==0) { - popt->topt.tuples_only = !popt->topt.tuples_only; - if (!quiet) { - if (popt->topt.tuples_only) - puts("Showing only tuples."); - else - puts("Tuples only is off."); + + /* set expanded/vertical mode */ + 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"); } - } - /* set title override */ - else if (strcmp(param, "title")==0) { - free(popt->title); - if (!value) - popt->title = NULL; - else - popt->title = xstrdup(value); - - if (!quiet) { - if (popt->title) - printf("Title is \"%s\".\n", popt->title); - else - printf("Title is unset.\n"); + /* null display */ + else if (strcmp(param, "null") == 0) + { + if (value) + { + free(popt->nullPrint); + popt->nullPrint = xstrdup(value); + } + if (!quiet) + printf("Null display is \"%s\".\n", popt->nullPrint ? popt->nullPrint : ""); } - } - /* set HTML table tag options */ - 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); + /* field separator for unaligned text */ + else if (strcmp(param, "fieldsep") == 0) + { + if (value) + { + free(popt->topt.fieldSep); + popt->topt.fieldSep = xstrdup(value); + } + if (!quiet) + printf("Field separator is \"%s\".\n", popt->topt.fieldSep); + } - if (!quiet) { - if (popt->topt.tableAttr) - printf("Table attribute is \"%s\".\n", popt->topt.tableAttr); - else - printf("Table attributes unset.\n"); + /* toggle between full and barebones format */ + else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0) + { + popt->topt.tuples_only = !popt->topt.tuples_only; + if (!quiet) + { + if (popt->topt.tuples_only) + puts("Showing only tuples."); + else + puts("Tuples only is off."); + } + } + + /* set title override */ + else if (strcmp(param, "title") == 0) + { + free(popt->title); + if (!value) + popt->title = NULL; + else + popt->title = xstrdup(value); + + if (!quiet) + { + if (popt->title) + printf("Title is \"%s\".\n", popt->title); + else + printf("Title is unset.\n"); + } } - } - - /* toggle use of pager */ - else if (strcmp(param, "pager")==0) { - popt->topt.pager = !popt->topt.pager; - if (!quiet) { - if (popt->topt.pager) - puts("Using pager is on."); - else - puts("Using pager is off."); + + /* set HTML table tag options */ + 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 (popt->topt.tableAttr) + printf("Table attribute is \"%s\".\n", popt->topt.tableAttr); + else + printf("Table attributes unset.\n"); + } } - } - - else { - fprintf(stderr, "Unknown option: %s\n", param); - return false; - } + /* toggle use of pager */ + else if (strcmp(param, "pager") == 0) + { + popt->topt.pager = !popt->topt.pager; + if (!quiet) + { + if (popt->topt.pager) + puts("Using pager is on."); + else + puts("Using pager is off."); + } + } - return true; + + else + { + fprintf(stderr, "Unknown option: %s\n", param); + return false; + } + + return true; } @@ -1200,29 +1343,31 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet static bool do_shell(const char *command) { - int result; + int result; - if (!command) { - char *sys; - char *shellName; + if (!command) + { + char *sys; + char *shellName; + + shellName = getenv("SHELL"); + if (shellName == NULL) + shellName = DEFAULT_SHELL; + + sys = malloc(strlen(shellName) + 16); + if (!sys) + return false; + sprintf(sys, "exec %s", shellName); + result = system(sys); + free(sys); + } + else + result = system(command); - shellName = getenv("SHELL"); - if (shellName == NULL) - shellName = DEFAULT_SHELL; - - sys = malloc(strlen(shellName) + 16); - if (!sys) - return false; - sprintf(sys, "exec %s", shellName); - result = system(sys); - free(sys); - } - else - result = system(command); - - if (result==127 || result==-1) { - perror("system"); - return false; - } - return true; + if (result == 127 || result == -1) + { + perror("system"); + return false; + } + return true; } |