summaryrefslogtreecommitdiff
path: root/Src/Zle/computil.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2009-08-05 10:14:53 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2009-08-05 10:14:53 +0000
commit207acdfe8916f6853430058c75706b5891808cc9 (patch)
treec2a84bd48854d6eab8c2c0016772a234eefcbece /Src/Zle/computil.c
parenta0b5ea6ffe482e1d4d8642eda4ffaf51d140fe9d (diff)
downloadzsh-207acdfe8916f6853430058c75706b5891808cc9.tar.gz
zsh-207acdfe8916f6853430058c75706b5891808cc9.zip
27211: handle Cygwin device files & drives specially in compfiles
Diffstat (limited to 'Src/Zle/computil.c')
-rw-r--r--Src/Zle/computil.c74
1 files changed, 66 insertions, 8 deletions
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index aa5983b94..f323574ee 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -3931,6 +3931,22 @@ bin_comptry(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
#define PATH_MAX2 (PATH_MAX * 2)
+/*
+ * Return a list of files we should accept exactly, without
+ * trying pattern matching.
+ *
+ * This is based on the accept-exact style, which may be
+ * an array so is passed in via "accept". The trial files
+ * are input in "names". "skipped" is passed down straight
+ * from the file completion function: it's got something to
+ * do with other components in the path but it's hard to work out
+ * quite what.
+ *
+ * There is one extra trick here for Cygwin. Regardless of the style,
+ * if the file ends in a colon it has to be a drive or a special device
+ * file and we always accept it exactly because treating it as a pattern
+ * won't work.
+ */
static LinkList
cfp_test_exact(LinkList names, char **accept, char *skipped)
{
@@ -3939,16 +3955,41 @@ cfp_test_exact(LinkList names, char **accept, char *skipped)
struct stat st;
LinkNode node;
LinkList ret = newlinklist(), alist = NULL;
+#ifdef __CYGWIN__
+ int accept_off = 0;
+#endif
- if ((!(compprefix && *compprefix) && !(compsuffix && *compsuffix)) ||
- (!accept || !*accept ||
- ((!strcmp(*accept, "false") || !strcmp(*accept, "no") ||
- !strcmp(*accept, "off") || !strcmp(*accept, "0")) && !accept[1])))
+ /*
+ * Don't do this unless completion has provided either a
+ * prefix or suffix from the command line.
+ */
+ if (!(compprefix && *compprefix) && !(compsuffix && *compsuffix))
return NULL;
- if (accept[1] ||
- (strcmp(*accept, "true") && strcmp(*accept, "yes") &&
- strcmp(*accept, "on") && strcmp(*accept, "1"))) {
+ /*
+ * See if accept-exact is off, implicitly or explicitly.
+ */
+ if (!accept || !*accept ||
+ ((!strcmp(*accept, "false") || !strcmp(*accept, "no") ||
+ !strcmp(*accept, "off") || !strcmp(*accept, "0")) && !accept[1])) {
+#ifdef __CYGWIN__
+ accept_off = 1;
+#else
+ /* If not Cygwin, nothing to do here. */
+ return NULL;
+#endif
+ }
+
+ /*
+ * See if the style is something other than just a boolean.
+ */
+ if (
+#ifdef __CYGWIN__
+ !accept_off &&
+#endif
+ (accept[1] ||
+ (strcmp(*accept, "true") && strcmp(*accept, "yes") &&
+ strcmp(*accept, "on") && strcmp(*accept, "1")))) {
Patprog prog;
alist = newlinklist();
@@ -3963,6 +4004,10 @@ cfp_test_exact(LinkList names, char **accept, char *skipped)
addlinknode(alist, prog);
}
}
+ /*
+ * Assemble the bits other than the set of file names:
+ * the other components, and the prefix and suffix.
+ */
sl = strlen(skipped) + (compprefix ? strlen(compprefix) : 0) +
(compsuffix ? strlen(compsuffix) : 0);
@@ -3976,8 +4021,21 @@ cfp_test_exact(LinkList names, char **accept, char *skipped)
if (l + sl < PATH_MAX2) {
strcpy(buf, p);
strcpy(buf + l, suf);
-
+#ifdef __CYGWIN__
+ /*
+ * If accept-exact is not set, accept this only if
+ * it looks like a special file such as a drive.
+ * We still test if it exists.
+ */
+ if (accept_off &&
+ (strchr(buf, '/') || buf[strlen(buf)-1] != ':'))
+ continue;
+#endif
if (!ztat(buf, &st, 0)) {
+ /*
+ * File exists; if accept-exact contained non-boolean
+ * values it must match those, too.
+ */
if (alist) {
LinkNode anode;