about summary refs log tree commit diff
path: root/Src/Zle/complete.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/complete.c')
-rw-r--r--Src/Zle/complete.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 71d114de9..342611f1f 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -518,7 +518,7 @@ parse_class(Cpattern p, char *iptr)
 	    ch = range_type((char *)iptr, nptr-iptr);
 	    iptr = nptr + 2;
 	    if (ch != PP_UNKWN)
-		*optr++ = STOUC(Meta) + ch;
+		*optr++ = (unsigned char) Meta + ch;
 	} else {
 	    /* characters stay metafied */
 	    char *ptr1 = iptr;
@@ -607,6 +607,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     char *oarg = NULL; /* argument of -o option */
     int added; /* return value */
     Cmatcher match = NULL;
+    size_t dparlen = 0, dparsize = 0; /* no. of -D options and array size */
 
     if (incompfunc != 1) {
 	zwarnnam(name, "can only be called from completion function");
@@ -614,7 +615,8 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     }
     dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = dat.mesg =
 	dat.pre = dat.suf = dat.group = dat.rems = dat.remf = dat.disp =
-	dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL;
+	dat.ign = dat.exp = dat.apar = dat.opar = NULL;
+    dat.dpar = NULL;
     dat.match = NULL;
     dat.flags = 0;
     dat.aflags = CAF_MATCH;
@@ -741,7 +743,12 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 		e = "parameter name expected after -%c";
 		break;
 	    case 'D':
-		sp = &(dat.dpar);
+		if (dparsize <= dparlen + 1) {
+		    dparsize = (dparsize + 1) * 2;
+		    dat.dpar = (char **)zrealloc(dat.dpar, sizeof(char *) * dparsize);
+		}
+		sp = dat.dpar + dparlen++;
+		*sp = dat.dpar[dparlen] = NULL;
 		e = "parameter name expected after -%c";
 		break;
 	    case 'd':
@@ -768,11 +775,13 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
                 } else {
                     zwarnnam(name, "number expected after -%c", *p);
 		    zsfree(mstr);
+		    zfree(dat.dpar, dparsize);
                     return 1;
                 }
                 if (dat.dummies < 0) {
                     zwarnnam(name, "invalid number: %d", dat.dummies);
 		    zsfree(mstr);
+		    zfree(dat.dpar, dparsize);
                     return 1;
                 }
 		break;
@@ -782,6 +791,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 	    default:
 		zwarnnam(name, "bad option: -%c", *p);
 		zsfree(mstr);
+		zfree(dat.dpar, dparsize);
 		return 1;
 	    }
 	    if (sp) {
@@ -802,6 +812,7 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 		    /* Missing argument: argv[N] == "-X", argv[N+1] == NULL. */
 		    zwarnnam(name, e, *p);
 		    zsfree(mstr);
+		    zfree(dat.dpar, dparsize);
 		    return 1;
 		}
 		if (m) {
@@ -818,19 +829,25 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
 
  ca_args:
 
-    if (mstr && (match = parse_cmatcher(name, mstr)) == pcm_err) {
+    if (mstr && (dat.aflags & CAF_MATCH) &&
+	    (match = parse_cmatcher(name, mstr)) == pcm_err)
+    {
 	zsfree(mstr);
+	zfree(dat.dpar, dparsize);
 	return 1;
     }
     zsfree(mstr);
 
     if (!*argv && !dat.group && !dat.mesg &&
-	!(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL)))
+	!(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL))) {
+	zfree(dat.dpar, dparsize);
 	return 1;
+    }
 
     dat.match = match = cpcmatcher(match);
     added = addmatches(&dat, argv);
     freecmatcher(match);
+    zfree(dat.dpar, dparsize);
 
     return added;
 }