summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--Src/builtin.c19
-rw-r--r--Test/B02typeset.ztst243
3 files changed, 269 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 76a6cfecd..56ae7f59a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,12 @@
-2001-08-08 Sven Wischnowsky <wischnow@zsh.org>
+2001-08-13 Bart Schaefer <schaefer@brasslantern.com>
+
+ * 15613 (plus unposted additions): Test/B02typeset.ztst: Tests for
+ correct behavior of typeset options and arguments.
+
+ * 15611: Src/builtin.c: Fix crash bug when assigning to array
+ elements in a function in the arguments of typeset or local.
+
+2001-08-13 Sven Wischnowsky <wischnow@zsh.org>
* 15615: Completion/Unix/Type/_path_files: -[12n] options don't
get arguments
diff --git a/Src/builtin.c b/Src/builtin.c
index c5491eb6b..388a94643 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -1586,6 +1586,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
int on, int off, int roff, char *value, Param altpm)
{
int usepm, tc, keeplocal = 0, newspecial = 0;
+ char *subscript;
/*
* Do we use the existing pm? Note that this isn't the end of the
@@ -1793,12 +1794,24 @@ typeset_single(char *cname, char *pname, Param pm, int func,
pm->ct = auxlen;
else
pm->ct = 0;
- } else if (strchr(pname, '[')) {
+ } else if ((subscript = strchr(pname, '['))) {
if (on & PM_READONLY) {
zerrnam(cname,
"%s: can't create readonly array elements", pname, 0);
return NULL;
- } else if (PM_TYPE(on) == PM_SCALAR) {
+ } else if (on & PM_LOCAL) {
+ *subscript = 0;
+ pm = (Param) (paramtab == realparamtab ?
+ gethashnode2(paramtab, pname) :
+ paramtab->getnode(paramtab, pname));
+ *subscript = '[';
+ if (!pm || pm->level != locallevel) {
+ zerrnam(cname,
+ "%s: can't create local array elements", pname, 0);
+ return NULL;
+ }
+ }
+ if (PM_TYPE(on) == PM_SCALAR) {
/*
* This will either complain about bad identifiers, or will set
* a hash element or array slice. This once worked by accident,
@@ -1808,6 +1821,8 @@ typeset_single(char *cname, char *pname, Param pm, int func,
if (!(pm = setsparam(pname, ztrdup(value ? value : ""))))
return NULL;
value = NULL;
+ keeplocal = 0;
+ on = pm->flags;
} else {
zerrnam(cname,
"%s: array elements must be scalar", pname, 0);
diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst
new file mode 100644
index 000000000..2dc015d31
--- /dev/null
+++ b/Test/B02typeset.ztst
@@ -0,0 +1,243 @@
+# There are certain usages of typeset and its synonyms that it is not
+# possible to test here, because they must appear at the top level and
+# everything that follows is processed by an "eval" within a function.
+
+# Equivalences:
+# declare typeset but declare does not accept -m
+# export typeset -x and typeset -x implies -g
+# float typeset -E
+# functions typeset -f
+# integer typeset -i
+# local typeset +g -m approximately
+# readonly typeset -r
+
+# Tested elsewhere:
+# Equivalence of autoload and typeset -fu A05execution
+# Associative array creation & assignment D04parameter, D06subscript
+# Effects of GLOBAL_EXPORT E01options
+# Function tracing (typeset -ft) E02xtrace
+
+# Not yet tested:
+# Justification (-L, -R, -Z)
+# Case conversion (-l, -u)
+# Assorted illegal flag combinations
+
+%prep
+
+ setopt noglob
+
+ scalar=scalar
+ array=(a r r a y)
+
+ scope00() {
+ typeset scalar
+ scalar=local
+ typeset -a array
+ array=(l o c a l)
+ print $scalar $array
+ }
+ scope01() {
+ local scalar
+ scalar=local
+ local -a array
+ array=(l o c a l)
+ print $scalar $array
+ }
+ scope02() {
+ declare scalar
+ scalar=local
+ declare -a array
+ array=(l o c a l)
+ print $scalar $array
+ }
+ scope10() {
+ export outer=outer
+ /bin/sh -fc 'echo $outer'
+ }
+ scope11() {
+ typeset -x outer=outer
+ /bin/sh -fc 'echo $outer'
+ }
+ scope12() {
+ local -x outer=inner
+ /bin/sh -fc 'echo $outer'
+ }
+ scope13() {
+ local -xT OUTER outer
+ outer=(i n n e r)
+ /bin/sh -fc 'echo $OUTER'
+ }
+
+ # Bug? `typeset -h' complains that ! # $ * - ? @ are not identifiers.
+ stress00() {
+ typeset -h +g -m [[:alpha:]_]*
+ unset -m [[:alpha:]_]*
+ typeset +m [[:alpha:]_]*
+ }
+
+%test
+
+ typeset +m scalar array
+0:Report types of parameters with typeset +m
+>scalar
+>array array
+
+ scope00
+ print $scalar $array
+0:Simple local declarations
+>local l o c a l
+>scalar a r r a y
+
+ scope01
+ print $scalar $array
+0:Equivalence of local and typeset in functions
+>local l o c a l
+>scalar a r r a y
+
+ scope02
+ print $scalar $array
+0:Basic equivalence of declare and typeset
+>local l o c a l
+>scalar a r r a y
+
+ declare +m
+1:Differences of declare and typeset
+?(eval):1: bad option: -m
+
+ scope10
+ print $outer
+0:Global export
+>outer
+>outer
+
+ scope11
+ print $outer
+0:Equivalence of export and typeset -x
+>outer
+>outer
+
+ scope12
+ print $outer
+0:Local export
+>inner
+>outer
+
+ float f=3.14159
+ typeset +m f
+ float -E3 f
+ print $f
+ float -F f
+ print $f
+0:Floating point, adding a precision, and fixed point
+>float local f
+>3.14e+00
+>3.142
+
+ integer i=3.141
+ typeset +m i
+ integer -i2 i
+ print $i
+0:Integer and changing the base
+>integer local i
+>2#11
+
+ float -E3 f=3.141
+ typeset +m f
+ integer -i2 f
+ typeset +m f
+ print $f
+0:Conversion of floating point to integer
+>float local f
+>integer local f
+>2#11
+
+ typeset -f
+0q:Equivalence of functions and typeset -f
+>$(functions)
+
+ readonly r=success
+ print $r
+ r=failure
+1:Readonly declaration
+>success
+?(eval):3: read-only variable: r
+
+ typeset r=success
+ readonly r
+ print $r
+ r=failure
+1:Convert to readonly
+>success
+?(eval):4: read-only variable: r
+
+ typeset -gU array
+ print $array
+0:Uniquified arrays and non-local scope
+>a r y
+
+ typeset -T SCALAR=l:o:c:a:l array
+ print $array
+ typeset -U SCALAR
+ print $SCALAR $array
+0:Tied parameters and uniquified colon-arrays
+>l o c a l
+>l:o:c:a l o c a
+
+ typeset -T SCALAR array
+ typeset +T SCALAR
+1:Untying is prohibited
+?(eval):typeset:2: use unset to remove tied variables
+
+ OUTER=outer
+ scope13
+ print $OUTER
+0:Export of tied parameters
+>i:n:n:e:r
+>outer
+
+ local array[2]=x
+1:Illegal local array element assignment
+?(eval):local:1: array[2]: can't create local array elements
+
+ local -a array
+ typeset array[1]=a array[2]=b array[3]=c
+ print $array
+0:Legal local array element assignment
+>a b c
+
+ local -A assoc
+ local b=1 ;: to stomp assoc[1] if assoc[b] is broken
+ typeset assoc[1]=a assoc[b]=2 assoc[3]=c
+ print $assoc[1] $assoc[b] $assoc[3]
+0:Legal local associative array element assignment
+>a 2 c
+
+ local scalar scalar[1]=a scalar[2]=b scalar[3]=c
+ print $scalar
+0:Local scalar subscript assignment
+>abc
+
+ stress00
+ print $scalar $array
+0q:Stress test: all parameters are local and unset, using -m
+>scalar a r y
+
+ # The first declare works around the "not an identifier" bug with -h
+ declare \! \# \$ * - ? @
+ typeset -h +g -m *
+ unset -m *
+ integer i=9
+ float -H f=9
+ declare -t scalar
+ declare -H -a array
+ typeset
+ typeset +
+0:Parameter hiding and tagging, printing types and values
+>array local array
+>float local f
+>integer local i=9
+>local tagged scalar=''
+>array local array
+>float local f
+>integer local i
+>local tagged scalar