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
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.
If \fIindex\fR is negative, then the given element will be prepended
to the list.
.PP
If \fIindex\fR is equal to the number of elements in \fI$varName\fR,
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
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 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.
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
(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
      \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
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)->typePtr == &tclIntType) && ((endValue) >= -1)) \
	    && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \
	    ? ((*(idxPtr) = ((objPtr)->internalRep.wideValue >= 0) \
	    ? ((((objPtr)->internalRep.wideValue > (endValue))) ? ((endValue) + 1) \
	    ? (int)(objPtr)->internalRep.wideValue : TCL_INDEX_NONE), TCL_OK) \
	    : ((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
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++;

	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) {
	    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 == elemCount) {
	    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
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 == len) {
    } 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
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
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 {
test lpop-1.4 {error conditions} -body {
    set no "x y"
    lpop no -1
} -result {list index out of range}
test lpop-1.5 {error conditions} -returnCodes error -body {
} -result {}
test lpop-1.5 {error conditions} -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 {
} -result {}
test lpop-1.6 {error conditions} -body {
    set no "x y"
    lpop no end+1
} -result {list index out of range}
} -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} -returnCodes error -body {
test lpop-1.8 {error conditions} -body {
    set no "x y"
    lpop no 0 0 0 0 1
} -result {list index out of range}
} -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
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}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
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}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
} {1 {list index out of range}}
} {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
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 }"
} {{{ 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 } } { 3 4 }"
} {{{ 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
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}"
} {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 } } { 3 4 }"
} {{{ 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
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}"
} {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 } } { 3 4 }"
} {{{ 1 2 } {3 4 5}} {3 4 5}}

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

# cleanup
::tcltest::cleanupTests
return