Tcl Source Code

Changes On Branch lset-index
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch lset-index Excluding Merge-Ins

This is equivalent to a diff from d3d2b49204 to 69c8d35a07

2020-02-21
08:52
Merge 8.6 check-in: 10d8a95829 user: jan.nijtmans tags: core-8-branch
2020-02-19
20:18
Merge 8.7 (this makes Travis build pass again) check-in: 8a48c3a5d0 user: jan.nijtmans tags: dgp-review
10:31
Handle endValue < -1. Improve documentation of new behavior. Leaf check-in: 69c8d35a07 user: jan.nijtmans tags: lset-index
2020-02-18
12:32
Handle invalid "lset" arguments better. Restrict Tcl_GetIntForIndex() index results between -1 (nega... check-in: 0245735b8a user: jan.nijtmans tags: lset-index
2020-02-13
22:06
Merge 8.7 check-in: c59e305ca6 user: jan.nijtmans tags: cplusplus
2020-02-12
13:26
Merge 8.7 Closed-Leaf check-in: ba5fe2748a user: jan.nijtmans tags: unicode-13
13:25
Merge 8.7 check-in: 1df476859c user: jan.nijtmans tags: death-to-dbgx
13:25
Merge 8.7 Closed-Leaf check-in: 6a19552cea user: jan.nijtmans tags: deprecate-channel-type-1-4
13:24
Merge 8.7 check-in: eea71a4ef7 user: jan.nijtmans tags: tip-558
13:19
Merge 8.7 check-in: 7deb4251a7 user: jan.nijtmans tags: trunk
13:18
Merge 8.6 check-in: d3d2b49204 user: jan.nijtmans tags: core-8-branch
13:12
Fix travis build, due to the change of Windows image. check-in: 113bf3a18d user: jan.nijtmans tags: core-8-6-branch
2020-02-05
16:41
merge-mark check-in: 8047caf34f user: jan.nijtmans tags: core-8-branch

Changes to doc/lset.n.

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
interpreter; however, variable
substitution and command substitution do not occur.
The command constructs a new list in which the designated element is
replaced with \fInewValue\fR.  This new list is stored in the
variable \fIvarName\fR, and is also the return value from the \fBlset\fR
command.
.PP
If \fIindex\fR is negative or greater than the number
of elements in \fI$varName\fR, then an error occurs.
.PP
If \fIindex\fR is equal to the number of elements in \fI$varName\fR,
then the given element is appended to the list.
.PP
The interpretation of each simple \fIindex\fR value is the same as
for the command \fBstring index\fR, supporting simple index
arithmetic and indices relative to the end of the list.
.PP
If additional \fIindex\fR arguments are supplied, then each argument is







|
|

|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
interpreter; however, variable
substitution and command substitution do not occur.
The command constructs a new list in which the designated element is
replaced with \fInewValue\fR.  This new list is stored in the
variable \fIvarName\fR, and is also the return value from the \fBlset\fR
command.
.PP
If \fIindex\fR is negative, then the given element will be prepended
to the list.
.PP
If \fIindex\fR is greater or equal to the number of elements in \fI$varName\fR,
then the given element is appended to the list.
.PP
The interpretation of each simple \fIindex\fR value is the same as
for the command \fBstring index\fR, supporting simple index
arithmetic and indices relative to the end of the list.
.PP
If additional \fIindex\fR arguments are supplied, then each argument is
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
.PP
.CS
\fBlset\fR a {1 2} newValue
.CE
.PP
replaces element 2 of sublist 1 with \fInewValue\fR.
.PP
The integer appearing in each \fIindex\fR argument must be greater
than or equal to zero.  The integer appearing in each \fIindex\fR
argument must be less than or equal to the length of the corresponding
list.  In other words, the \fBlset\fR command can change the size

of a list only by appending an element (setting the one after the current
end).  If an index is outside the permitted range, an error is reported.
.SH EXAMPLES
.PP
In each of these examples, the initial value of \fIx\fR is:
.PP
.CS
set x [list [list a b c] [list d e f] [list g h i]]
      \fI\(-> {a b c} {d e f} {g h i}\fR
.CE
.PP
The indicated return value also becomes the new value of \fIx\fR
(except in the last case, which is an error which leaves the value of
\fIx\fR unchanged.)
.PP
.CS
\fBlset\fR x {j k l}
      \fI\(-> j k l\fR
\fBlset\fR x {} {j k l}
      \fI\(-> j k l\fR
\fBlset\fR x 0 j
      \fI\(-> j {d e f} {g h i}\fR
\fBlset\fR x 2 j
      \fI\(-> {a b c} {d e f} j\fR
\fBlset\fR x end j
      \fI\(-> {a b c} {d e f} j\fR
\fBlset\fR x end-1 j
      \fI\(-> {a b c} j {g h i}\fR
\fBlset\fR x 2 1 j
      \fI\(-> {a b c} {d e f} {g j i}\fR
\fBlset\fR x {2 1} j
      \fI\(-> {a b c} {d e f} {g j i}\fR
\fBlset\fR x {2 3} j
      \fI\(-> list index out of range\fR
.CE
.PP
In the following examples, the initial value of \fIx\fR is:
.PP
.CS
set x [list [list [list a b] [list c d]] \e
            [list [list e f] [list g h]]]







<
<
<
|
>
|
|










<
<



















|







75
76
77
78
79
80
81



82
83
84
85
86
87
88
89
90
91
92
93
94
95


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
.PP
.CS
\fBlset\fR a {1 2} newValue
.CE
.PP
replaces element 2 of sublist 1 with \fInewValue\fR.
.PP



The \fBlset\fR command can change the size
of a list only by prepending an element (setting the first argument, moving the
remaining ones up) or appending an element (setting the one after the current
end).
.SH EXAMPLES
.PP
In each of these examples, the initial value of \fIx\fR is:
.PP
.CS
set x [list [list a b c] [list d e f] [list g h i]]
      \fI\(-> {a b c} {d e f} {g h i}\fR
.CE
.PP
The indicated return value also becomes the new value of \fIx\fR


.PP
.CS
\fBlset\fR x {j k l}
      \fI\(-> j k l\fR
\fBlset\fR x {} {j k l}
      \fI\(-> j k l\fR
\fBlset\fR x 0 j
      \fI\(-> j {d e f} {g h i}\fR
\fBlset\fR x 2 j
      \fI\(-> {a b c} {d e f} j\fR
\fBlset\fR x end j
      \fI\(-> {a b c} {d e f} j\fR
\fBlset\fR x end-1 j
      \fI\(-> {a b c} j {g h i}\fR
\fBlset\fR x 2 1 j
      \fI\(-> {a b c} {d e f} {g j i}\fR
\fBlset\fR x {2 1} j
      \fI\(-> {a b c} {d e f} {g j i}\fR
\fBlset\fR x {2 3} j
      \fI\(-> {a b c} {d e f} {g h i j}\fR
.CE
.PP
In the following examples, the initial value of \fIx\fR is:
.PP
.CS
set x [list [list [list a b] [list c d]] \e
            [list [list e f] [list g h]]]

Changes to generic/tclInt.h.

2507
2508
2509
2510
2511
2512
2513
2514
2515
2516

2517
2518
2519
2520
2521
2522
2523
2524
#define TclGetIntFromObj(interp, objPtr, intPtr) \
    (((objPtr)->typePtr == &tclIntType \
	    && (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(INT_MIN) \
	    && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \
	    ? ((*(intPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \
	    : Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
    (((objPtr)->typePtr == &tclIntType \
	    && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \
	    ? ((*(idxPtr) = ((objPtr)->internalRep.wideValue >= 0) \

	    ? (int)(objPtr)->internalRep.wideValue : TCL_INDEX_NONE), TCL_OK) \
	    : Tcl_GetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))

/*
 * Macro used to save a function call for common uses of
 * Tcl_GetWideIntFromObj(). The ANSI C "prototype" is:
 *
 * MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,







|
<

>
|







2507
2508
2509
2510
2511
2512
2513
2514

2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
#define TclGetIntFromObj(interp, objPtr, intPtr) \
    (((objPtr)->typePtr == &tclIntType \
	    && (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(INT_MIN) \
	    && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \
	    ? ((*(intPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \
	    : Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
    ((((objPtr)->typePtr == &tclIntType) && ((endValue) >= -1)) \

	    ? ((*(idxPtr) = ((objPtr)->internalRep.wideValue >= 0) \
	    ? ((((objPtr)->internalRep.wideValue > (endValue))) ? ((endValue) + 1) \
	    : ((int)(objPtr)->internalRep.wideValue)) : TCL_INDEX_NONE), TCL_OK) \
	    : Tcl_GetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))

/*
 * Macro used to save a function call for common uses of
 * Tcl_GetWideIntFromObj(). The ANSI C "prototype" is:
 *
 * MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,

Changes to generic/tclListObj.c.

1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646


1647
1648
1649
1650
1651
1652
1653
	    /* ...the index we're trying to use isn't an index at all. */
	    result = TCL_ERROR;
	    indexArray++;
	    break;
	}
	indexArray++;

	if (index < 0 || index > elemCount
		|| (valuePtr == NULL && index >= elemCount)) {
	    /* ...the index points outside the sublist. */
	    if (interp != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj("list index out of range", -1));
		Tcl_SetErrorCode(interp, "TCL", "OPERATION",
			valuePtr == NULL ? "LPOP" : "LSET",
			"BADINDEX", NULL);
	    }
	    result = TCL_ERROR;
	    break;
	}

	/*
	 * No error conditions.  As long as we're not yet on the last index,
	 * determine the next sublist for the next pass through the loop, and
	 * take steps to make sure it is an unshared copy, as we intend to
	 * modify it.
	 */

	if (--indexCount) {
	    parentList = subListPtr;
	    if (index == elemCount) {
		subListPtr = Tcl_NewObj();
	    } else {
		subListPtr = elemPtrs[index];
	    }
	    if (Tcl_IsShared(subListPtr)) {
		subListPtr = Tcl_DuplicateObj(subListPtr);
	    }

	    /*
	     * Replace the original elemPtr[index] in parentList with a copy
	     * we know to be unshared.  This call will also deal with the
	     * situation where parentList shares its intrep with other
	     * Tcl_Obj's.  Dealing with the shared intrep case can cause
	     * subListPtr to become shared again, so detect that case and make
	     * and store another copy.
	     */

	    if (index == elemCount) {


		Tcl_ListObjAppendElement(NULL, parentList, subListPtr);
	    } else {
		TclListObjSetElement(NULL, parentList, index, subListPtr);
	    }
	    if (Tcl_IsShared(subListPtr)) {
		subListPtr = Tcl_DuplicateObj(subListPtr);
		TclListObjSetElement(NULL, parentList, index, subListPtr);







<
<
<
<
<
<
<
<
<
<
<
<
<
<









|

















|
>
>







1598
1599
1600
1601
1602
1603
1604














1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
	    /* ...the index we're trying to use isn't an index at all. */
	    result = TCL_ERROR;
	    indexArray++;
	    break;
	}
	indexArray++;















	/*
	 * No error conditions.  As long as we're not yet on the last index,
	 * determine the next sublist for the next pass through the loop, and
	 * take steps to make sure it is an unshared copy, as we intend to
	 * modify it.
	 */

	if (--indexCount) {
	    parentList = subListPtr;
	    if (index >= elemCount || index < 0) {
		subListPtr = Tcl_NewObj();
	    } else {
		subListPtr = elemPtrs[index];
	    }
	    if (Tcl_IsShared(subListPtr)) {
		subListPtr = Tcl_DuplicateObj(subListPtr);
	    }

	    /*
	     * Replace the original elemPtr[index] in parentList with a copy
	     * we know to be unshared.  This call will also deal with the
	     * situation where parentList shares its intrep with other
	     * Tcl_Obj's.  Dealing with the shared intrep case can cause
	     * subListPtr to become shared again, so detect that case and make
	     * and store another copy.
	     */

	    if (index < 0) {
		Tcl_ListObjReplace(NULL, parentList, 0, 0, 1, &subListPtr);
	    } else if (index >= elemCount) {
		Tcl_ListObjAppendElement(NULL, parentList, subListPtr);
	    } else {
		TclListObjSetElement(NULL, parentList, index, subListPtr);
	    }
	    if (Tcl_IsShared(subListPtr)) {
		subListPtr = Tcl_DuplicateObj(subListPtr);
		TclListObjSetElement(NULL, parentList, index, subListPtr);
1728
1729
1730
1731
1732
1733
1734

1735



1736

1737
1738
1739
1740
1741
1742
1743
     * proper list - or something convertible to one - above).
     */

    len = -1;
    TclListObjLength(NULL, subListPtr, &len);
    if (valuePtr == NULL) {
	Tcl_ListObjReplace(NULL, subListPtr, index, 1, 0, NULL);

    } else if (index == len) {



	Tcl_ListObjAppendElement(NULL, subListPtr, valuePtr);

    } else {
	TclListObjSetElement(NULL, subListPtr, index, valuePtr);
	TclInvalidateStringRep(subListPtr);
    }
    Tcl_IncrRefCount(retValuePtr);
    return retValuePtr;
}







>
|
>
>
>

>







1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
     * proper list - or something convertible to one - above).
     */

    len = -1;
    TclListObjLength(NULL, subListPtr, &len);
    if (valuePtr == NULL) {
	Tcl_ListObjReplace(NULL, subListPtr, index, 1, 0, NULL);
	TclInvalidateStringRep(subListPtr);
    } else if (index < 0) {
	Tcl_ListObjReplace(NULL, subListPtr, 0, 0, 1, &valuePtr);
	TclInvalidateStringRep(subListPtr);
    } else if (index >= len) {
	Tcl_ListObjAppendElement(NULL, subListPtr, valuePtr);
	TclInvalidateStringRep(subListPtr);
    } else {
	TclListObjSetElement(NULL, subListPtr, index, valuePtr);
	TclInvalidateStringRep(subListPtr);
    }
    Tcl_IncrRefCount(retValuePtr);
    return retValuePtr;
}

Changes to generic/tclUtil.c.

3884
3885
3886
3887
3888
3889
3890


3891
3892
3893
3894
3895
3896
3897
    Tcl_WideInt wide;

    if (GetWideForIndex(interp, objPtr, endValue, &wide) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (wide < 0) {
	*indexPtr = -1;


    } else if (wide > INT_MAX) {
	*indexPtr = INT_MAX;
    } else {
	*indexPtr = (int) wide;
    }
    return TCL_OK;
}







>
>







3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
    Tcl_WideInt wide;

    if (GetWideForIndex(interp, objPtr, endValue, &wide) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (wide < 0) {
	*indexPtr = -1;
    } else if ((wide > endValue) && (endValue >= -1)) {
	*indexPtr = endValue + 1;
    } else if (wide > INT_MAX) {
	*indexPtr = INT_MAX;
    } else {
	*indexPtr = (int) wide;
    }
    return TCL_OK;
}

Changes to tests/lpop.test.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
test lpop-1.2 {error conditions} -returnCodes error -body {
    lpop no 0
} -result {can't read "no": no such variable}
test lpop-1.3 {error conditions} -returnCodes error -body {
    set no "x {}x"
    lpop no
} -result {list element in braces followed by "x" instead of space}
test lpop-1.4 {error conditions} -returnCodes error -body {
    set no "x y"
    lpop no -1
} -result {list index out of range}
test lpop-1.5 {error conditions} -returnCodes error -body {
    set no "x y z"
    lpop no 3
} -result {list index out of range} ;#-errorCode {TCL OPERATION LPOP BADINDEX}
test lpop-1.6 {error conditions} -returnCodes error -body {
    set no "x y"
    lpop no end+1
} -result {list index out of range}
test lpop-1.7 {error conditions} -returnCodes error -body {
    set no "x y"
    lpop no {}
} -match glob -result {bad index *}
test lpop-1.8 {error conditions} -returnCodes error -body {
    set no "x y"
    lpop no 0 0 0 0 1
} -result {list index out of range}
test lpop-1.9 {error conditions} -returnCodes error -body {
    set no "x y"
    lpop no {1 0}
} -match glob -result {bad index *}

test lpop-2.1 {basic functionality} -body {
    set l "x y z"







|


|
|


|
|


|




|


|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
test lpop-1.2 {error conditions} -returnCodes error -body {
    lpop no 0
} -result {can't read "no": no such variable}
test lpop-1.3 {error conditions} -returnCodes error -body {
    set no "x {}x"
    lpop no
} -result {list element in braces followed by "x" instead of space}
test lpop-1.4 {error conditions} -body {
    set no "x y"
    lpop no -1
} -result {}
test lpop-1.5 {error conditions} -body {
    set no "x y z"
    lpop no 3
} -result {}
test lpop-1.6 {error conditions} -body {
    set no "x y"
    lpop no end+1
} -result {}
test lpop-1.7 {error conditions} -returnCodes error -body {
    set no "x y"
    lpop no {}
} -match glob -result {bad index *}
test lpop-1.8 {error conditions} -body {
    set no "x y"
    lpop no 0 0 0 0 1
} -result {}
test lpop-1.9 {error conditions} -returnCodes error -body {
    set no "x y"
    lpop no {1 0}
} -match glob -result {bad index *}

test lpop-2.1 {basic functionality} -body {
    set l "x y z"

Changes to tests/lset.test.

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    } msg] $msg
} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
test lset-4.3 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list -1] w}
    } msg] $msg
} {1 {list index out of range}}
test lset-4.4 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list 4] w}
    } msg] $msg
} {1 {list index out of range}}
test lset-4.5a {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list end--2] w}
    } msg] $msg
} {1 {list index out of range}}
test lset-4.5b {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list end+2] w}
    } msg] $msg
} {1 {list index out of range}}
test lset-4.6 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list end-3] w}
    } msg] $msg
} {1 {list index out of range}}
test lset-4.7 {lset, not compiled, 3 args, not a list} testevalex {
    set a "x \{"
    list [catch {
	testevalex {lset a 0 y}
    } msg] $msg
} {1 {unmatched open brace in list}}
test lset-4.8 {lset, not compiled, 3 args, bad index} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a 2a2 w}
    } msg] $msg
} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
test lset-4.9 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a -1 w}
    } msg] $msg
} {1 {list index out of range}}
test lset-4.10 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a 4 w}
    } msg] $msg
} {1 {list index out of range}}
test lset-4.11a {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a end--2 w}
    } msg] $msg
} {1 {list index out of range}}
test lset-4.11 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a end+2 w}
    } msg] $msg
} {1 {list index out of range}}
test lset-4.12 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a end-3 w}
    } msg] $msg
} {1 {list index out of range}}

test lset-5.1 {lset, not compiled, 3 args, can't set variable} testevalex {
    list [catch {
	testevalex {lset noWrite 0 d}
    } msg] $msg $noWrite
} {1 {can't set "noWrite": trace failed} {d b c}}
test lset-5.2 {lset, not compiled, 3 args, can't set variable} testevalex {







|





|





|





|





|

















|





|





|





|





|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    } msg] $msg
} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
test lset-4.3 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list -1] w}
    } msg] $msg
} {0 {w x y z}}
test lset-4.4 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list 4] w}
    } msg] $msg
} {0 {x y z w}}
test lset-4.5a {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list end--2] w}
    } msg] $msg
} {0 {x y z w}}
test lset-4.5b {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list end+2] w}
    } msg] $msg
} {0 {x y z w}}
test lset-4.6 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a [list end-3] w}
    } msg] $msg
} {0 {w x y z}}
test lset-4.7 {lset, not compiled, 3 args, not a list} testevalex {
    set a "x \{"
    list [catch {
	testevalex {lset a 0 y}
    } msg] $msg
} {1 {unmatched open brace in list}}
test lset-4.8 {lset, not compiled, 3 args, bad index} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a 2a2 w}
    } msg] $msg
} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
test lset-4.9 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a -1 w}
    } msg] $msg
} {0 {w x y z}}
test lset-4.10 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a 4 w}
    } msg] $msg
} {0 {x y z w}}
test lset-4.11a {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a end--2 w}
    } msg] $msg
} {0 {x y z w}}
test lset-4.11 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a end+2 w}
    } msg] $msg
} {0 {x y z w}}
test lset-4.12 {lset, not compiled, 3 args, index out of range} testevalex {
    set a {x y z}
    list [catch {
	testevalex {lset a end-3 w}
    } msg] $msg
} {0 {w x y z}}

test lset-5.1 {lset, not compiled, 3 args, can't set variable} testevalex {
    list [catch {
	testevalex {lset noWrite 0 d}
    } msg] $msg $noWrite
} {1 {can't set "noWrite": trace failed} {d b c}}
test lset-5.2 {lset, not compiled, 3 args, can't set variable} testevalex {
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
test lset-8.4 {lset, not compiled, bad second index} testevalex {
    set a {{b c} {d e}}
    list [catch {testevalex {lset a {0 2a2} f}} msg] $msg
} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
test lset-8.5 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 -1 h}} msg] $msg
} {1 {list index out of range}}
test lset-8.6 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 -1} h}} msg] $msg
} {1 {list index out of range}}
test lset-8.7 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 3 h}} msg] $msg
} {1 {list index out of range}}
test lset-8.8 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 3} h}} msg] $msg
} {1 {list index out of range}}
test lset-8.9a {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 end--2 h}} msg] $msg
} {1 {list index out of range}}
test lset-8.9b {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 end+2 h}} msg] $msg
} {1 {list index out of range}}
test lset-8.10a {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 end--2} h}} msg] $msg
} {1 {list index out of range}}
test lset-8.10b {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 end+2} h}} msg] $msg
} {1 {list index out of range}}
test lset-8.11 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 end-2 h}} msg] $msg
} {1 {list index out of range}}
test lset-8.12 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 end-2} h}} msg] $msg
} {1 {list index out of range}}

test lset-9.1 {lset, not compiled, entire variable} testevalex {
    set a x
    list [testevalex {lset a y}] $a
} {y y}
test lset-9.2 {lset, not compiled, entire variable} testevalex {
    set a x







|



|



|



|



|



|



|



|



|



|







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
test lset-8.4 {lset, not compiled, bad second index} testevalex {
    set a {{b c} {d e}}
    list [catch {testevalex {lset a {0 2a2} f}} msg] $msg
} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
test lset-8.5 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 -1 h}} msg] $msg
} {0 {{b c} {d e} {h f g}}}
test lset-8.6 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 -1} h}} msg] $msg
} {0 {{b c} {d e} {h f g}}}
test lset-8.7 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 3 h}} msg] $msg
} {0 {{b c} {d e} {f g h}}}
test lset-8.8 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 3} h}} msg] $msg
} {0 {{b c} {d e} {f g h}}}
test lset-8.9a {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 end--2 h}} msg] $msg
} {0 {{b c} {d e} {f g h}}}
test lset-8.9b {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 end+2 h}} msg] $msg
} {0 {{b c} {d e} {f g h}}}
test lset-8.10a {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 end--2} h}} msg] $msg
} {0 {{b c} {d e} {f g h}}}
test lset-8.10b {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 end+2} h}} msg] $msg
} {0 {{b c} {d e} {f g h}}}
test lset-8.11 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a 2 end-2 h}} msg] $msg
} {0 {{b c} {d e} {h f g}}}
test lset-8.12 {lset, not compiled, second index out of range} testevalex {
    set a {{b c} {d e} {f g}}
    list [catch {testevalex {lset a {2 end-2} h}} msg] $msg
} {0 {{b c} {d e} {h f g}}}

test lset-9.1 {lset, not compiled, entire variable} testevalex {
    set a x
    list [testevalex {lset a y}] $a
} {y y}
test lset-9.2 {lset, not compiled, entire variable} testevalex {
    set a x
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
    list [testevalex {lset a $a {gag me}}] $a
} {{{{{{gag me}}}} 0 0 0} {{{{{gag me}}}} 0 0 0}}

test lset-14.1 {lset, not compiled, list args, is string rep preserved?} testevalex {
    set a { { 1 2 } { 3 4 } }
    catch { testevalex {lset a {1 5} 5} }
    list $a [lindex $a 1]
} "{ { 1 2 } { 3 4 } } { 3 4 }"
test lset-14.2 {lset, not compiled, flat args, is string rep preserved?} testevalex {
    set a { { 1 2 } { 3 4 } }
    catch { testevalex {lset a 1 5 5} }
    list $a [lindex $a 1]
} "{ { 1 2 } { 3 4 } } { 3 4 }"

testConstraint testobj [llength [info commands testobj]]
test lset-15.1 {lset: shared intrep [Bug 1677512]} -setup {
    teststringobj set 1 {{1 2} 3}
    testobj convert 1 list
    testobj duplicate 1 2
    variable x [teststringobj get 1]







|




|







400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
    list [testevalex {lset a $a {gag me}}] $a
} {{{{{{gag me}}}} 0 0 0} {{{{{gag me}}}} 0 0 0}}

test lset-14.1 {lset, not compiled, list args, is string rep preserved?} testevalex {
    set a { { 1 2 } { 3 4 } }
    catch { testevalex {lset a {1 5} 5} }
    list $a [lindex $a 1]
} {{{ 1 2 } {3 4 5}} {3 4 5}}
test lset-14.2 {lset, not compiled, flat args, is string rep preserved?} testevalex {
    set a { { 1 2 } { 3 4 } }
    catch { testevalex {lset a 1 5 5} }
    list $a [lindex $a 1]
} {{{ 1 2 } {3 4 5}} {3 4 5}}

testConstraint testobj [llength [info commands testobj]]
test lset-15.1 {lset: shared intrep [Bug 1677512]} -setup {
    teststringobj set 1 {{1 2} 3}
    testobj convert 1 list
    testobj duplicate 1 2
    variable x [teststringobj get 1]

Changes to tests/lsetComp.test.

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
} "0 {{1 2} {3 5}}"

test lsetComp-2.8 {lset, compiled, list of args, error } {
    evalInProc {
	set x { {1 2} {3 4} }
	lset x {1 5} 5
    }
} "1 {list index out of range}"

test lsetComp-2.9 {lset, compiled, list of args, error - is string preserved} {
    set ::x { { 1 2 } { 3 4 } }
    evalInProc {
	lset ::x { 1 5 } 5
    }
    list $::x [lindex $::x 1]
} "{ { 1 2 } { 3 4 } } { 3 4 }"

test lsetComp-3.1 {lset, compiled, flat args, not a simple var name} {
    evalInProc {
	set y x
	set x {{1 2} {3 4}}
	lset $y 1 1 5
    }







|







|







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
} "0 {{1 2} {3 5}}"

test lsetComp-2.8 {lset, compiled, list of args, error } {
    evalInProc {
	set x { {1 2} {3 4} }
	lset x {1 5} 5
    }
} {0 {{1 2} {3 4 5}}}

test lsetComp-2.9 {lset, compiled, list of args, error - is string preserved} {
    set ::x { { 1 2 } { 3 4 } }
    evalInProc {
	lset ::x { 1 5 } 5
    }
    list $::x [lindex $::x 1]
} {{{ 1 2 } {3 4 5}} {3 4 5}}

test lsetComp-3.1 {lset, compiled, flat args, not a simple var name} {
    evalInProc {
	set y x
	set x {{1 2} {3 4}}
	lset $y 1 1 5
    }
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
} "0 {{1 2} {3 5}}"

test lsetComp-3.8 {lset, compiled, flat args, error } {
    evalInProc {
	set x { {1 2} {3 4} }
	lset x 1 5 5
    }
} "1 {list index out of range}"

test lsetComp-3.9 {lset, compiled, flat args, error - is string preserved} {
    set ::x { { 1 2 } { 3 4 } }
    evalInProc {
	lset ::x 1 5 5
    }
    list $::x [lindex $::x 1]
} "{ { 1 2 } { 3 4 } } { 3 4 }"

catch { rename evalInProc {} }
catch { unset ::x }
catch { unset ::y }

# cleanup
::tcltest::cleanupTests
return







|







|








408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
} "0 {{1 2} {3 5}}"

test lsetComp-3.8 {lset, compiled, flat args, error } {
    evalInProc {
	set x { {1 2} {3 4} }
	lset x 1 5 5
    }
} {0 {{1 2} {3 4 5}}}

test lsetComp-3.9 {lset, compiled, flat args, error - is string preserved} {
    set ::x { { 1 2 } { 3 4 } }
    evalInProc {
	lset ::x 1 5 5
    }
    list $::x [lindex $::x 1]
} {{{ 1 2 } {3 4 5}} {3 4 5}}

catch { rename evalInProc {} }
catch { unset ::x }
catch { unset ::y }

# cleanup
::tcltest::cleanupTests
return