about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/builtins.yo37
-rw-r--r--Src/builtin.c47
3 files changed, 62 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog
index 582faf109..6a699cba0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2003-02-07  Peter Stephenson  <pws@csr.com>
+
+	* 18204: Doc/Zsh/builtins.yo, Src/builtin.c: KSH_ARRAYS gives
+	ksh behaviour with set -A <optargs> <args>.
+
 2003-02-06  Peter Stephenson  <pws@csr.com>
 
 	* 18202: Functions/TCP/*, Doc/Makefile.in, Doc/zsh.yo,
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 7512e9acf..eb1d62755 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -966,6 +966,7 @@ cindex(parameters, listing)
 cindex(parameters, positional)
 cindex(parameters, setting array)
 cindex(array parameters, setting)
+pindex(KSH_ARRAYS, use of)
 item(tt(set) [ {tt(PLUS())|tt(-)}var(options) | {tt(PLUS())|tt(-)}tt(o) var(option_name) ] ... [ {tt(PLUS())|tt(-)}tt(A) [ var(name) ] ] [ var(arg) ... ])(
 Set the options for the shell and/or set the positional parameters, or
 declare and set an array.  If the tt(-s) option is given, it causes the
@@ -976,14 +977,34 @@ ifzman(zmanref(zshoptions))\
 ifnzman(noderef(Options))\
 .  Flags may be specified by name using the tt(-o) option.
 
-If the tt(-A) flag is specified, var(name) is
-set to an array containing the given var(arg)s. if tt(PLUS()A) is used and
-var(name) is an array, the given arguments will replace the initial
-elements of that array; if no var(name) is specified, all arrays are
-printed.  Otherwise the positional parameters are set.  If no arguments are
-given, then the names and values of all parameters are printed on the
-standard output.  If the only argument is `tt(PLUS())',
-the names of all parameters are printed.
+If the tt(-A) flag is specified, var(name) is set to an array containing
+the given var(arg)s; if no var(name) is specified, all arrays are printed
+together with their values.
+
+If tt(PLUS()A) is used and var(name) is an array, the
+given arguments will replace the initial elements of that array; if no
+var(name) is specified, all arrays are printed without their values.
+
+The behaviour of arguments after tt(-A) var(name) or tt(PLUS()A) var(name)
+depends on whether the option tt(KSH_ARRAYS) is set.  If it is not set, all
+arguments following var(name) are treated as values for the array,
+regardless of their form.  If the option is set, normal option processing
+continues at that point; only regular arguments are treated as values for
+the array.  This means that
+
+example(set -A array -x -- foo)
+
+sets tt(array) to `tt(-x -- foo)' if tt(KSH_ARRAYS) is not set, but sets
+the array to tt(foo) and turns on the option `tt(-x)' if it is set.
+
+If the tt(-A) flag is not present, but there are arguments beyond the
+options, the positional parameters are set.  If the option list (if any)
+is terminated by `tt(-)tt(-)', and there are no further arguments, the
+positional parameters will be unset.
+
+If no arguments and no `tt(-)tt(-)' are given, then the names and values of
+all parameters are printed on the standard output.  If the only argument is
+`tt(PLUS())', the names of all parameters are printed.
 )
 module(setcap)(zsh/cap)
 findex(setopt)
diff --git a/Src/builtin.c b/Src/builtin.c
index a8871b9a6..cd622f0ed 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -531,7 +531,7 @@ bin_set(char *nam, char **args, Options ops, int func)
 {
     int action, optno, array = 0, hadopt = 0,
 	hadplus = 0, hadend = 0, sort = 0;
-    char **x;
+    char **x, *arrayname = NULL;
 
     /* Obsolescent sh compatibility: set - is the same as set +xv *
      * and set - args is the same as set +xv -- args              */
@@ -575,7 +575,15 @@ bin_set(char *nam, char **args, Options ops, int func)
 		if(!*++*args)
 		    args++;
 		array = action ? 1 : -1;
-		goto doneoptions;
+		arrayname = *args;
+		if (!arrayname)
+		    goto doneoptions;
+		else if  (!isset(KSHARRAYS))
+		{
+		    args++;
+		    goto doneoptions;
+		}
+		break;
 	    } else if (**args == 's')
 		sort = action ? 1 : -1;
 	    else {
@@ -592,30 +600,31 @@ bin_set(char *nam, char **args, Options ops, int func)
 
     /* Show the parameters, possibly with values */
     queue_signals();
-    if (!hadopt && !*args)
-	scanhashtable(paramtab, 1, 0, 0, paramtab->printnode,
-		      hadplus ? PRINT_NAMEONLY : 0);
-
-    if (array && !*args) {
-	/* display arrays */
-	scanhashtable(paramtab, 1, PM_ARRAY, 0, paramtab->printnode,
-		      hadplus ? PRINT_NAMEONLY : 0);
-    }
-    if (!*args && !hadend) {
-	unqueue_signals();
-	return 0;
+    if (!arrayname)
+    {
+	if (!hadopt && !*args)
+	    scanhashtable(paramtab, 1, 0, 0, paramtab->printnode,
+			  hadplus ? PRINT_NAMEONLY : 0);
+
+	if (array) {
+	    /* display arrays */
+	    scanhashtable(paramtab, 1, PM_ARRAY, 0, paramtab->printnode,
+			  hadplus ? PRINT_NAMEONLY : 0);
+	}
+	if (!*args && !hadend) {
+	    unqueue_signals();
+	    return 0;
+	}
     }
-    if (array)
-	args++;
     if (sort)
 	qsort(args, arrlen(args), sizeof(char *),
 	      sort > 0 ? strpcmp : invstrpcmp);
     if (array) {
 	/* create an array with the specified elements */
-	char **a = NULL, **y, *name = args[-1];
+	char **a = NULL, **y;
 	int len = arrlen(args);
 
-	if (array < 0 && (a = getaparam(name))) {
+	if (array < 0 && (a = getaparam(arrayname))) {
 	    int al = arrlen(a);
 
 	    if (al > len)
@@ -627,7 +636,7 @@ bin_set(char *nam, char **args, Options ops, int func)
 	    *y++ = ztrdup(*args++);
 	}
 	*y++ = NULL;
-	setaparam(name, x);
+	setaparam(arrayname, x);
     } else {
 	/* set shell arguments */
 	freearray(pparams);