aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/stringutils.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2012-02-28 01:06:29 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2012-02-28 01:06:29 -0300
commit41e3c94cac0e68257126b2d264dc5e877e892490 (patch)
treed581501cc8819ea933329d71a3373109a25db794 /src/bin/psql/stringutils.c
parentcb3a7c2b95a28e57c56562d48d2a3aa5eeb7fa29 (diff)
downloadpostgresql-41e3c94cac0e68257126b2d264dc5e877e892490.tar.gz
postgresql-41e3c94cac0e68257126b2d264dc5e877e892490.zip
psql: when tab-completing, use quotes on file names that need them
psql backslash commands that deal with file or directory names require quotes around those that have spaces, single quotes, or backslashes. However, tab-completing such names does not provide said quotes, and is thus almost useless with them. This patch fixes the problem by having a wrapper function around rl_filename_completion_function that dequotes on input and quotes on output. This eases dealing with such names. Author: Noah Misch
Diffstat (limited to 'src/bin/psql/stringutils.c')
-rw-r--r--src/bin/psql/stringutils.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/bin/psql/stringutils.c b/src/bin/psql/stringutils.c
index 3b5ce1ba4bf..77387dcf3de 100644
--- a/src/bin/psql/stringutils.c
+++ b/src/bin/psql/stringutils.c
@@ -272,3 +272,72 @@ strip_quotes(char *source, char quote, char escape, int encoding)
*dst = '\0';
}
+
+
+/*
+ * quote_if_needed
+ *
+ * Opposite of strip_quotes(). If "source" denotes itself literally without
+ * quoting or escaping, returns NULL. Otherwise, returns a malloc'd copy with
+ * quoting and escaping applied:
+ *
+ * source - string to parse
+ * entails_quote - any of these present? need outer quotes
+ * quote - doubled within string, affixed to both ends
+ * escape - doubled within string
+ * encoding - the active character-set encoding
+ *
+ * Do not use this as a substitute for PQescapeStringConn(). Use it for
+ * strings to be parsed by strtokx() or psql_scan_slash_option().
+ */
+char *
+quote_if_needed(const char *source, const char *entails_quote,
+ char quote, char escape, int encoding)
+{
+ const char *src;
+ char *ret;
+ char *dst;
+ bool need_quotes = false;
+
+ psql_assert(source);
+ psql_assert(quote);
+
+ src = source;
+ dst = ret = pg_malloc(2 * strlen(src) + 3); /* excess */
+
+ *dst++ = quote;
+
+ while (*src)
+ {
+ char c = *src;
+ int i;
+
+ if (c == quote)
+ {
+ need_quotes = true;
+ *dst++ = quote;
+ }
+ else if (c == escape)
+ {
+ need_quotes = true;
+ *dst++ = escape;
+ }
+ else if (strchr(entails_quote, c))
+ need_quotes = true;
+
+ i = PQmblen(src, encoding);
+ while (i--)
+ *dst++ = *src++;
+ }
+
+ *dst++ = quote;
+ *dst = '\0';
+
+ if (!need_quotes)
+ {
+ free(ret);
+ ret = NULL;
+ }
+
+ return ret;
+}