about summary refs log tree commit diff
path: root/Src/builtin.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/builtin.c')
-rw-r--r--Src/builtin.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/Src/builtin.c b/Src/builtin.c
index 063644efb..2a2b22d3b 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -30,6 +30,8 @@
 /* this is defined so we get the prototype for open_memstream */
 #define _GNU_SOURCE 1
 
+#include <assert.h>
+
 #include "zsh.mdh"
 #include "builtin.pro"
 
@@ -53,7 +55,7 @@ static struct builtin builtins[] =
     BUILTIN("cd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL),
     BUILTIN("chdir", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL),
     BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL),
-    BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klmprtuxz", NULL),
+    BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "ACE:%F:%HL:%R:%TUZ:%acfghi:%klmprtuxz", NULL),
     BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL),
     BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL),
     BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
@@ -86,7 +88,7 @@ static struct builtin builtins[] =
     BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
     BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -1, 0, NULL, NULL),
     BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL),
-    BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%ahi:%lprtux", NULL),
+    BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "ACE:%F:%HL:%R:%TUZ:%achi:%lprtux", NULL),
     BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL),
     BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL),
 
@@ -106,7 +108,7 @@ static struct builtin builtins[] =
     BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
     BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "IlLnr", NULL),
     BUILTIN("read", 0, bin_read, 0, -1, 0, "cd:ek:%lnpqrst:%zu:AE", NULL),
-    BUILTIN("readonly", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, BIN_READONLY, "AE:%F:%HL:%R:%TUZ:%afghi:%lptux", "r"),
+    BUILTIN("readonly", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, BIN_READONLY, "ACE:%F:%HL:%R:%TUZ:%acfghi:%lptux", "r"),
     BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "df", "r"),
     BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL),
     BUILTIN("set", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_set, 0, -1, 0, NULL, NULL),
@@ -120,7 +122,7 @@ static struct builtin builtins[] =
     BUILTIN("trap", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_trap, 0, -1, 0, NULL, NULL),
     BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL),
     BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"),
-    BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klprtuxmz", NULL),
+    BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "ACE:%F:%HL:%R:%TUZ:%acfghi:%klprtuxmz", NULL),
     BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL),
     BUILTIN("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL),
     BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"),
@@ -673,11 +675,9 @@ bin_set(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
     if (array) {
 	/* create an array with the specified elements */
 	char **a = NULL, **y;
-	int len = arrlen(args);
-
-	if (array < 0 && (a = getaparam(arrayname))) {
-	    int al = arrlen(a);
+	int len = arrlen(args), al;
 
+	if (array < 0 && (a = getaparam(arrayname, &al))) {
 	    if (al > len)
 		len = al;
 	}
@@ -2579,6 +2579,17 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 	else if (OPT_PLUS(ops,optval))
 	    off |= bit;
     }
+
+    /* Special case, ran out of bit<<1 positions for optstr */
+    if (OPT_MINUS(ops,'c'))
+	on |= PM_CACHELEN;
+    else if (OPT_PLUS(ops,'c'))
+	off |= PM_CACHELEN;
+    if (OPT_MINUS(ops,'C'))
+	on |= PM_CHECKLEN;
+    else if (OPT_PLUS(ops,'C'))
+	off |= PM_CHECKLEN;
+
     roff = off;
 
     /* Sanity checks on the options.  Remove conflicting options. */
@@ -3611,7 +3622,10 @@ bin_unset(char *name, char **argv, Options ops, int func)
 		    } else {
 			/* start is after the element for reverse index */
 			int start = vbuf.start - !!(vbuf.flags & VALFLAG_INV);
-			if (arrlen_gt(vbuf.pm->u.arr, start)) {
+			if (!(vbuf.pm->node.flags & PM_CACHELEN))
+			    vbuf.pm->length = arrlen(vbuf.pm->u.arr);
+			assert(vbuf.pm->length == arrlen(vbuf.pm->u.arr));
+			if (start < vbuf.pm->length) {
 			    char *arr[2];
 			    arr[0] = "";
 			    arr[1] = 0;
@@ -5264,7 +5278,7 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func))
 
     /* optional argument can be either numeric or an array */
     queue_signals();
-    if (*argv && !getaparam(*argv))
+    if (*argv && !getaparam(*argv, NULL))
         num = mathevali(*argv++);
 
     if (num < 0) {
@@ -5274,9 +5288,10 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func))
     }
 
     if (*argv) {
+	int len = 0;
         for (; *argv; argv++)
-            if ((s = getaparam(*argv))) {
-                if (arrlen_lt(s, num)) {
+            if ((s = getaparam(*argv, &len))) {
+                if (num > len) {
 		    zwarnnam(name, "shift count must be <= $#");
 		    ret++;
 		    continue;
@@ -5284,7 +5299,7 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func))
 		if (OPT_ISSET(ops,'p')) {
 		    char **s2, **src, **dst;
 		    int count;
-		    l = arrlen(s);
+		    l = len;
 		    src = s;
 		    dst = s2 = (char **)zalloc((l - num + 1) * sizeof(char *));
 		    for (count = l - num; count; count--)