Attached is the updated version of the patch, which matches

on words as opposed to lines, which means that all of the
following work in psql:

\d foo \d bar
\d foo; \d bar
\d foo \d bar;;
\d foo; <space>


This one also uses "true and false" and strips semicolons
for the following backslash commands: \C \c \d \e \i \o \s \z

Greg Sabino Mullane
This commit is contained in:
Bruce Momjian 2001-10-05 19:01:13 +00:00
parent b78efb6d82
commit 453ef3f81f

View File

@ -3,7 +3,7 @@
* *
* Copyright 2000 by PostgreSQL Global Development Group * Copyright 2000 by PostgreSQL Global Development Group
* *
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.58 2001/09/10 14:51:33 momjian Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.59 2001/10/05 19:01:13 momjian Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "command.h" #include "command.h"
@ -58,7 +58,7 @@ enum option_type
{ {
OT_NORMAL, OT_SQLID, OT_FILEPIPE OT_NORMAL, OT_SQLID, OT_FILEPIPE
}; };
static char *scan_option(char **string, enum option_type type, char *quote); static char *scan_option(char **string, enum option_type type, char *quote, bool semicolon);
static char *unescape(const unsigned char *source, size_t len); static char *unescape(const unsigned char *source, size_t len);
static bool do_edit(const char *filename_arg, PQExpBuffer query_buf); static bool do_edit(const char *filename_arg, PQExpBuffer query_buf);
@ -219,7 +219,7 @@ exec_command(const char *cmd,
/* \C -- override table title (formerly change HTML caption) */ /* \C -- override table title (formerly change HTML caption) */
else if (strcmp(cmd, "C") == 0) else if (strcmp(cmd, "C") == 0)
{ {
char *opt = scan_option(&string, OT_NORMAL, NULL); char *opt = scan_option(&string, OT_NORMAL, NULL, true);
success = do_pset("title", opt, &pset.popt, quiet); success = do_pset("title", opt, &pset.popt, quiet);
free(opt); free(opt);
@ -241,8 +241,8 @@ exec_command(const char *cmd,
char opt1q, char opt1q,
opt2q; opt2q;
opt1 = scan_option(&string, OT_SQLID, &opt1q); opt1 = scan_option(&string, OT_SQLID, &opt1q, true);
opt2 = scan_option(&string, OT_SQLID, &opt2q); opt2 = scan_option(&string, OT_SQLID, &opt2q, true);
if (opt2) if (opt2)
/* gave username */ /* gave username */
@ -262,7 +262,7 @@ exec_command(const char *cmd,
/* \cd */ /* \cd */
else if (strcmp(cmd, "cd") == 0) else if (strcmp(cmd, "cd") == 0)
{ {
char *opt = scan_option(&string, OT_NORMAL, NULL); char *opt = scan_option(&string, OT_NORMAL, NULL, true);
char *dir; char *dir;
if (opt) if (opt)
@ -315,8 +315,8 @@ exec_command(const char *cmd,
{ {
char *name; char *name;
bool show_verbose; bool show_verbose;
name = scan_option(&string, OT_SQLID, NULL, true);
name = scan_option(&string, OT_SQLID, NULL);
show_verbose = strchr(cmd, '+') ? true : false; show_verbose = strchr(cmd, '+') ? true : false;
switch (cmd[1]) switch (cmd[1])
@ -382,7 +382,7 @@ exec_command(const char *cmd,
} }
else else
{ {
fname = scan_option(&string, OT_NORMAL, NULL); fname = scan_option(&string, OT_NORMAL, NULL, true);
status = do_edit(fname, query_buf) ? CMD_NEWEDIT : CMD_ERROR; status = do_edit(fname, query_buf) ? CMD_NEWEDIT : CMD_ERROR;
free(fname); free(fname);
} }
@ -402,7 +402,7 @@ exec_command(const char *cmd,
else else
fout = stdout; fout = stdout;
while ((value = scan_option(&string, OT_NORMAL, &quoted))) while ((value = scan_option(&string, OT_NORMAL, &quoted, false)))
{ {
if (!quoted && strcmp(value, "-n") == 0) if (!quoted && strcmp(value, "-n") == 0)
no_newline = true; no_newline = true;
@ -423,7 +423,7 @@ exec_command(const char *cmd,
/* \encoding -- set/show client side encoding */ /* \encoding -- set/show client side encoding */
else if (strcmp(cmd, "encoding") == 0) else if (strcmp(cmd, "encoding") == 0)
{ {
char *encoding = scan_option(&string, OT_NORMAL, NULL); char *encoding = scan_option(&string, OT_NORMAL, NULL, false);
if (!encoding) if (!encoding)
/* show encoding */ /* show encoding */
@ -451,7 +451,7 @@ exec_command(const char *cmd,
/* \f -- change field separator */ /* \f -- change field separator */
else if (strcmp(cmd, "f") == 0) else if (strcmp(cmd, "f") == 0)
{ {
char *fname = scan_option(&string, OT_NORMAL, NULL); char *fname = scan_option(&string, OT_NORMAL, NULL, false);
success = do_pset("fieldsep", fname, &pset.popt, quiet); success = do_pset("fieldsep", fname, &pset.popt, quiet);
free(fname); free(fname);
@ -460,7 +460,7 @@ exec_command(const char *cmd,
/* \g means send query */ /* \g means send query */
else if (strcmp(cmd, "g") == 0) else if (strcmp(cmd, "g") == 0)
{ {
char *fname = scan_option(&string, OT_FILEPIPE, NULL); char *fname = scan_option(&string, OT_FILEPIPE, NULL, false);
if (!fname) if (!fname)
pset.gfname = NULL; pset.gfname = NULL;
@ -492,7 +492,7 @@ exec_command(const char *cmd,
/* \i is include file */ /* \i is include file */
else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0) else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
{ {
char *fname = scan_option(&string, OT_NORMAL, NULL); char *fname = scan_option(&string, OT_NORMAL, NULL, true);
if (!fname) if (!fname)
{ {
@ -520,8 +520,8 @@ exec_command(const char *cmd,
char *opt1, char *opt1,
*opt2; *opt2;
opt1 = scan_option(&string, OT_NORMAL, NULL); opt1 = scan_option(&string, OT_NORMAL, NULL, true);
opt2 = scan_option(&string, OT_NORMAL, NULL); opt2 = scan_option(&string, OT_NORMAL, NULL, true);
if (strcmp(cmd + 3, "export") == 0) if (strcmp(cmd + 3, "export") == 0)
{ {
@ -570,7 +570,7 @@ exec_command(const char *cmd,
/* \o -- set query output */ /* \o -- set query output */
else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0) else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
{ {
char *fname = scan_option(&string, OT_FILEPIPE, NULL); char *fname = scan_option(&string, OT_FILEPIPE, NULL, true);
success = setQFout(fname); success = setQFout(fname);
free(fname); free(fname);
@ -589,8 +589,8 @@ exec_command(const char *cmd,
/* \pset -- set printing parameters */ /* \pset -- set printing parameters */
else if (strcmp(cmd, "pset") == 0) else if (strcmp(cmd, "pset") == 0)
{ {
char *opt0 = scan_option(&string, OT_NORMAL, NULL); char *opt0 = scan_option(&string, OT_NORMAL, NULL, false);
char *opt1 = scan_option(&string, OT_NORMAL, NULL); char *opt1 = scan_option(&string, OT_NORMAL, NULL, false);
if (!opt0) if (!opt0)
{ {
@ -619,7 +619,7 @@ exec_command(const char *cmd,
/* \s save history in a file or show it on the screen */ /* \s save history in a file or show it on the screen */
else if (strcmp(cmd, "s") == 0) else if (strcmp(cmd, "s") == 0)
{ {
char *fname = scan_option(&string, OT_NORMAL, NULL); char *fname = scan_option(&string, OT_NORMAL, NULL, true);
success = saveHistory(fname ? fname : "/dev/tty"); success = saveHistory(fname ? fname : "/dev/tty");
@ -631,7 +631,7 @@ exec_command(const char *cmd,
/* \set -- generalized set variable/option command */ /* \set -- generalized set variable/option command */
else if (strcmp(cmd, "set") == 0) else if (strcmp(cmd, "set") == 0)
{ {
char *opt0 = scan_option(&string, OT_NORMAL, NULL); char *opt0 = scan_option(&string, OT_NORMAL, NULL, false);
if (!opt0) if (!opt0)
{ {
@ -656,11 +656,11 @@ exec_command(const char *cmd,
char *newval = NULL; char *newval = NULL;
char *opt; char *opt;
opt = scan_option(&string, OT_NORMAL, NULL); opt = scan_option(&string, OT_NORMAL, NULL, false);
newval = xstrdup(opt ? opt : ""); newval = xstrdup(opt ? opt : "");
free(opt); free(opt);
while ((opt = scan_option(&string, OT_NORMAL, NULL))) while ((opt = scan_option(&string, OT_NORMAL, NULL, false)))
{ {
newval = realloc(newval, strlen(newval) + strlen(opt) + 1); newval = realloc(newval, strlen(newval) + strlen(opt) + 1);
if (!newval) if (!newval)
@ -690,7 +690,7 @@ exec_command(const char *cmd,
/* \T -- define html <table ...> attributes */ /* \T -- define html <table ...> attributes */
else if (strcmp(cmd, "T") == 0) else if (strcmp(cmd, "T") == 0)
{ {
char *value = scan_option(&string, OT_NORMAL, NULL); char *value = scan_option(&string, OT_NORMAL, NULL, false);
success = do_pset("tableattr", value, &pset.popt, quiet); success = do_pset("tableattr", value, &pset.popt, quiet);
free(value); free(value);
@ -699,7 +699,7 @@ exec_command(const char *cmd,
/* \unset */ /* \unset */
else if (strcmp(cmd, "unset") == 0) else if (strcmp(cmd, "unset") == 0)
{ {
char *opt = scan_option(&string, OT_NORMAL, NULL); char *opt = scan_option(&string, OT_NORMAL, NULL, false);
if (!opt) if (!opt)
{ {
@ -728,7 +728,7 @@ exec_command(const char *cmd,
} }
else else
{ {
fname = scan_option(&string, OT_FILEPIPE, NULL); fname = scan_option(&string, OT_FILEPIPE, NULL, true);
if (!fname) if (!fname)
{ {
@ -783,7 +783,7 @@ exec_command(const char *cmd,
/* \z -- list table rights (grant/revoke) */ /* \z -- list table rights (grant/revoke) */
else if (strcmp(cmd, "z") == 0) else if (strcmp(cmd, "z") == 0)
{ {
char *opt = scan_option(&string, OT_SQLID, NULL); char *opt = scan_option(&string, OT_SQLID, NULL, true);
success = permissionsList(opt); success = permissionsList(opt);
free(opt); free(opt);
@ -814,7 +814,7 @@ exec_command(const char *cmd,
char *value; char *value;
fprintf(stderr, "+ optstr = |%s|\n", options_string); fprintf(stderr, "+ optstr = |%s|\n", options_string);
while ((value = scan_option(&string, OT_NORMAL, NULL))) while ((value = scan_option(&string, OT_NORMAL, NULL, true)))
{ {
fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value); fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value);
free(value); free(value);
@ -829,7 +829,7 @@ exec_command(const char *cmd,
status = CMD_ERROR; status = CMD_ERROR;
/* eat the rest of the options string */ /* eat the rest of the options string */
while ((val = scan_option(&string, OT_NORMAL, NULL))) while ((val = scan_option(&string, OT_NORMAL, NULL, false)))
{ {
if (status != CMD_UNKNOWN) if (status != CMD_UNKNOWN)
psql_error("\\%s: extra argument '%s' ignored\n", cmd, val); psql_error("\\%s: extra argument '%s' ignored\n", cmd, val);
@ -848,7 +848,7 @@ exec_command(const char *cmd,
* scan_option() * scan_option()
*/ */
static char * static char *
scan_option(char **string, enum option_type type, char *quote) scan_option(char **string, enum option_type type, char *quote, bool semicolon)
{ {
unsigned int pos = 0; unsigned int pos = 0;
char *options_string; char *options_string;
@ -905,6 +905,7 @@ scan_option(char **string, enum option_type type, char *quote)
* If this is expected to be an SQL identifier like option * If this is expected to be an SQL identifier like option
* then we strip out the double quotes * then we strip out the double quotes
*/ */
if (type == OT_SQLID) if (type == OT_SQLID)
{ {
unsigned int k, unsigned int k,
@ -1117,6 +1118,13 @@ scan_option(char **string, enum option_type type, char *quote)
strncpy(return_val, &options_string[pos], token_end); strncpy(return_val, &options_string[pos], token_end);
return_val[token_end] = 0; return_val[token_end] = 0;
/* Strip any trailing semi-colons for some types */
if (semicolon) {
int i;
for (i = strlen(return_val)-1; i && return_val[i]==';'; i--);
if (i<strlen(return_val)-1) return_val[i+1]='\0';
}
if (type == OT_SQLID) if (type == OT_SQLID)
for (cp = return_val; *cp; cp += PQmblen(cp, pset.encoding)) for (cp = return_val; *cp; cp += PQmblen(cp, pset.encoding))
if (isupper((unsigned char) *cp)) if (isupper((unsigned char) *cp))