summaryrefslogtreecommitdiff
path: root/bin/ksh
diff options
context:
space:
mode:
authorDavid Leonard <d@cvs.openbsd.org>1999-11-14 22:04:03 +0000
committerDavid Leonard <d@cvs.openbsd.org>1999-11-14 22:04:03 +0000
commit927e778570087ee7dbae3245e2bd0cd787d7ce6b (patch)
tree9a2285f36a2026cbe0d6a75b912482292fc19d71 /bin/ksh
parent44878276ee07b9b57ddadb0f9a8694c887f5b926 (diff)
quote metachars when completing filenames from jdolecek@netbsd. ok millert@
Diffstat (limited to 'bin/ksh')
-rw-r--r--bin/ksh/edit.c63
-rw-r--r--bin/ksh/edit.h3
-rw-r--r--bin/ksh/emacs.c22
-rw-r--r--bin/ksh/vi.c23
4 files changed, 98 insertions, 13 deletions
diff --git a/bin/ksh/edit.c b/bin/ksh/edit.c
index 79bee4ab6df..6b383785f8b 100644
--- a/bin/ksh/edit.c
+++ b/bin/ksh/edit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: edit.c,v 1.10 1999/06/15 01:18:33 millert Exp $ */
+/* $OpenBSD: edit.c,v 1.11 1999/11/14 22:04:02 d Exp $ */
/*
* Command line editing - common code
@@ -555,7 +555,7 @@ x_file_glob(flags, str, slen, wordsp)
{
char *toglob;
char **words;
- int nwords;
+ int nwords, i, idx, escaping;
XPtrV w;
struct source *s, *sold;
@@ -564,6 +564,20 @@ x_file_glob(flags, str, slen, wordsp)
toglob = add_glob(str, slen);
+ /* remove all escaping backward slashes */
+ escaping = 0;
+ for(i = 0, idx = 0; toglob[i]; i++) {
+ if (toglob[i] == '\\' && !escaping) {
+ escaping = 1;
+ continue;
+ }
+
+ toglob[idx] = toglob[i];
+ idx++;
+ if (escaping) escaping = 0;
+ }
+ toglob[idx] = '\0';
+
/*
* Convert "foo*" (toglob) to an array of strings (words)
*/
@@ -750,11 +764,14 @@ x_locate_word(buf, buflen, pos, startp, is_commandp)
/* Keep going backwards to start of word (has effect of allowing
* one blank after the end of a word)
*/
- for (; start > 0 && IS_WORDC(buf[start - 1]); start--)
+ for (; (start > 0 && IS_WORDC(buf[start - 1]))
+ || (start > 1 && buf[start-2] == '\\'); start--)
;
/* Go forwards to end of word */
- for (end = start; end < buflen && IS_WORDC(buf[end]); end++)
- ;
+ for (end = start; end < buflen && IS_WORDC(buf[end]); end++) {
+ if (buf[end] == '\\' && (end+1) < buflen && buf[end+1] == ' ')
+ end++;
+ }
if (is_commandp) {
int iscmd;
@@ -1021,4 +1038,40 @@ glob_path(flags, pat, wp, path)
Xfree(xs, xp);
}
+/*
+ * if argument string contains any special characters, they will
+ * be escaped and the result will be put into edit buffer by
+ * keybinding-specific function
+ */
+int
+x_escape(s, len, putbuf_func)
+ const char *s;
+ size_t len;
+ int putbuf_func ARGS((const char *s, size_t len));
+{
+ size_t add, wlen;
+ const char *ifs = str_val(local("IFS", 0));
+ int rval=0;
+
+ for (add = 0, wlen = len; wlen - add > 0; add++) {
+ if (strchr("\\$(){}*&;|<>\"'", s[add]) || strchr(ifs, s[add])) {
+ if (putbuf_func(s, add) != 0) {
+ rval = -1;
+ break;
+ }
+
+ putbuf_func("\\", 1);
+ putbuf_func(&s[add], 1);
+
+ add++;
+ wlen -= add;
+ s += add;
+ add = -1; /* after the increment it will go to 0 */
+ }
+ }
+ if (wlen > 0 && rval == 0)
+ rval = putbuf_func(s, wlen);
+
+ return (rval);
+}
#endif /* EDIT */
diff --git a/bin/ksh/edit.h b/bin/ksh/edit.h
index fd29701cc06..d8f3641d399 100644
--- a/bin/ksh/edit.h
+++ b/bin/ksh/edit.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: edit.h,v 1.2 1996/08/19 20:08:48 downsj Exp $ */
+/* $OpenBSD: edit.h,v 1.3 1999/11/14 22:04:02 d Exp $ */
/* NAME:
* edit.h - globals for edit modes
@@ -57,6 +57,7 @@ int x_cf_glob ARGS((int flags, const char *buf, int buflen, int pos, int *startp
int x_longest_prefix ARGS((int nwords, char *const *words));
int x_basename ARGS((const char *s, const char *se));
void x_free_words ARGS((int nwords, char **words));
+int x_escape ARGS((const char *, size_t, int (*)(const char *s, size_t len)));
/* emacs.c */
int x_emacs ARGS((char *buf, size_t len));
void x_init_emacs ARGS((void));
diff --git a/bin/ksh/emacs.c b/bin/ksh/emacs.c
index ea035cf4cd0..44a9b5b6632 100644
--- a/bin/ksh/emacs.c
+++ b/bin/ksh/emacs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: emacs.c,v 1.11 1999/08/04 19:11:13 millert Exp $ */
+/* $OpenBSD: emacs.c,v 1.12 1999/11/14 22:04:02 d Exp $ */
/*
* Emacs-like command line editing and history
@@ -144,6 +144,7 @@ static int x_comment ARGS((int c));
static int x_fold_case ARGS((int c));
static char *x_lastcp ARGS((void));
static void do_complete ARGS((int flags, Comp_type type));
+static int x_emacs_putbuf ARGS((const char *s, size_t len));
/* The lines between START-FUNC-TAB .. END-FUNC-TAB are run through a
@@ -472,6 +473,21 @@ x_ins(s)
return 0;
}
+/*
+ * this is used for x_escape() in do_complete()
+ */
+static int
+x_emacs_putbuf(s, len)
+ const char *s;
+ size_t len;
+{
+ int rval;
+
+ if ((rval = x_do_ins(s, len)) != 0)
+ return (rval);
+ return (rval);
+}
+
static int
x_del_back(c)
int c;
@@ -1832,8 +1848,8 @@ do_complete(flags, type)
if (nlen > 0) {
x_goto(xbuf + start);
x_delete(end - start, FALSE);
- words[0][nlen] = '\0';
- x_ins(words[0]);
+ x_escape(words[0], nlen, x_emacs_putbuf);
+ x_adjust();
/* If single match is not a directory, add a
* space to the end...
*/
diff --git a/bin/ksh/vi.c b/bin/ksh/vi.c
index 607c571d180..ad7b67b3802 100644
--- a/bin/ksh/vi.c
+++ b/bin/ksh/vi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vi.c,v 1.7 1999/07/14 13:37:24 millert Exp $ */
+/* $OpenBSD: vi.c,v 1.8 1999/11/14 22:04:02 d Exp $ */
/*
* vi command editing
@@ -65,6 +65,7 @@ static void x_vi_zotc ARGS((int c));
static void vi_pprompt ARGS((int full));
static void vi_error ARGS((void));
static void vi_macro_reset ARGS((void));
+static int x_vi_putbuf ARGS((const char *s, size_t len));
#define C_ 0x1 /* a valid command that isn't a M_, E_, U_ */
#define M_ 0x2 /* movement command (h, l, etc.) */
@@ -1472,6 +1473,17 @@ edit_reset(buf, len)
holdlen = 0;
}
+/*
+ * this is used for calling x_escape() in complete_word()
+ */
+static int
+x_vi_putbuf(s, len)
+ const char *s;
+ size_t len;
+{
+ return putbuf(s, len, 0);
+}
+
static int
putbuf(buf, len, repl)
const char *buf;
@@ -2070,9 +2082,12 @@ complete_word(command, count)
buf = save_edstate(es);
del_range(start, end);
es->cursor = start;
- if (putbuf(match, match_len, 0) != 0)
- rval = -1;
- else if (is_unique) {
+
+ /* escape all shell-sensitive characters and put the result into
+ * command buffer */
+ rval = x_escape(match, match_len, x_vi_putbuf);
+
+ if (rval == 0 && is_unique) {
/* If exact match, don't undo. Allows directory completions
* to be used (ie, complete the next portion of the path).
*/