1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
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
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
|
'\"
'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tcl_ListObj 3 9.1 Tcl "Tcl Library Procedures"
.so man.macros
.BS
.SH NAME
Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace, Tcl_ListObjRange, Tcl_ListObjRepeat, Tcl_ListObjReverse \- manipulate Tcl values as lists
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
int
\fBTcl_ListObjAppendList\fR(\fIinterp, listPtr, elemListPtr\fR)
.sp
int
\fBTcl_ListObjAppendElement\fR(\fIinterp, listPtr, objPtr\fR)
.sp
Tcl_Obj *
\fBTcl_NewListObj\fR(\fIobjc, objv\fR)
.sp
\fBTcl_SetListObj\fR(\fIobjPtr, objc, objv\fR)
.sp
int
\fBTcl_ListObjGetElements\fR(\fIinterp, listPtr, objcPtr, objvPtr\fR)
.sp
int
\fBTcl_ListObjLength\fR(\fIinterp, listPtr, lengthPtr\fR)
.sp
int
\fBTcl_ListObjIndex\fR(\fIinterp, listPtr, index, objPtrPtr\fR)
.sp
int
\fBTcl_ListObjReplace\fR(\fIinterp, listPtr, first, count, objc, objv\fR)
.sp
int
\fBTcl_ListObjRange\fR(\fIinterp, listPtr, first, last, objPtrPtr\fR)
.sp
int
\fBTcl_ListObjRepeat\fR(\fIinterp, count, objc, objv, objPtrPtr\fR)
.sp
int
\fBTcl_ListObjReverse\fR(\fIinterp, listPtr, objPtrPtr\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Obj *const" *elemListPtr in/out
.AP Tcl_Interp *interp in
If an error occurs while converting a value to be a list value,
an error message is left in the interpreter's result value
unless \fIinterp\fR is NULL.
.AP Tcl_Obj *listPtr in/out
Points to the input list value.
If \fIlistPtr\fR does not already point to a list value,
an attempt will be made to convert it to one.
Some functions may store a reference to it internally so
care must be taken when managing its reference count.
See the \fBREFERENCE COUNT MANAGEMENT\fR section below.
.AP Tcl_Obj *elemListPtr in/out
For \fBTcl_ListObjAppendList\fR, this points to a list value
containing elements to be appended onto \fIlistPtr\fR.
Each element of *\fIelemListPtr\fR will
become a new element of \fIlistPtr\fR.
If *\fIelemListPtr\fR is not NULL and
does not already point to a list value,
an attempt will be made to convert it to one.
.AP Tcl_Obj *objPtr in
For \fBTcl_ListObjAppendElement\fR,
points to the Tcl value that will be appended to \fIlistPtr\fR.
For \fBTcl_SetListObj\fR,
this points to the Tcl value that will be converted to a list value
containing the \fIobjc\fR elements of the array referenced by \fIobjv\fR.
.AP "Tcl_Size \&| int" *objcPtr in
Points to location where \fBTcl_ListObjGetElements\fR
stores the number of element values in \fIlistPtr\fR.
May be (Tcl_Size *)NULL when not used. If it points to a variable which
type is not \fBTcl_Size\fR, a compiler warning will be generated.
If your extensions is compiled with \fB\-DTCL_8_API\fR, this function will return
NULL for lists with more than INT_MAX elements (which should
trigger proper error-handling), otherwise expect it to crash.
.AP Tcl_Obj ***objvPtr out
A location where \fBTcl_ListObjGetElements\fR stores a pointer to an array
of pointers to the element values of \fIlistPtr\fR.
.AP Tcl_Size objc in
The number of Tcl values in the \fIobjv\fR array.
.AP "Tcl_Obj *const" objv[] in
An array of pointers to Tcl values.
.AP "Tcl_Size \&| int" *lengthPtr out
Points to location where \fBTcl_ListObjLength\fR
stores the length of the list.
May be (Tcl_Size *)NULL when not used. If it points to a variable which
type is not \fBTcl_Size\fR, a compiler warning will be generated.
If your extensions is compiled with \fB-DTCL_8_API\fR, this function will return
TCL_ERROR for lists with more than INT_MAX elements (which should
trigger proper error-handling), otherwise expect it to crash.
.AP Tcl_Size index in
Index of the list element that \fBTcl_ListObjIndex\fR
is to return.
The first element has index 0.
.AP Tcl_Obj **objPtrPtr out
Points to location to store an output list or element value. No assumptions
should be made about the reference count of the returned value.
See the \fBREFERENCE COUNT MANAGEMENT\fR section below.
.AP Tcl_Size first in
Index of the first element in a range of elements in a list.
.AP Tcl_Size last in
Index of the last element in a range of elements in a list.
.AP Tcl_Size count in
The number of elements to be operated on or a repetition count.
.BE
.SH DESCRIPTION
.PP
Tcl list values have an internal representation that supports
the efficient indexing and appending.
The procedures described in this man page are used to
create, modify, access, and transform Tcl list values from C code.
.PP
\fBTcl_ListObjAppendList\fR and \fBTcl_ListObjAppendElement\fR
both add one or more values
to the end of the list value referenced by \fIlistPtr\fR.
\fBTcl_ListObjAppendList\fR appends each element of the list value
referenced by \fIelemListPtr\fR while
\fBTcl_ListObjAppendElement\fR appends the single value
referenced by \fIobjPtr\fR.
Both procedures will convert the value referenced by \fIlistPtr\fR
to a list value if necessary.
If an error occurs during conversion,
both procedures return \fBTCL_ERROR\fR and leave an error message
in the interpreter's result value if \fIinterp\fR is not NULL.
Similarly, if \fIelemListPtr\fR does not already refer to a list value,
\fBTcl_ListObjAppendList\fR will attempt to convert it to one
and if an error occurs during conversion,
will return \fBTCL_ERROR\fR
and leave an error message in the interpreter's result value
if interp is not NULL.
Both procedures invalidate any old string representation of \fIlistPtr\fR
and, if it was converted to a list value,
free any old internal representation.
Similarly, \fBTcl_ListObjAppendList\fR frees any old internal representation
of \fIelemListPtr\fR if it converts it to a list value.
After appending each element in \fIelemListPtr\fR,
\fBTcl_ListObjAppendList\fR increments the element's reference count
since \fIlistPtr\fR now also refers to it.
For the same reason, \fBTcl_ListObjAppendElement\fR
increments \fIobjPtr\fR's reference count.
If no error occurs,
the two procedures return \fBTCL_OK\fR after appending the values.
.PP
\fBTcl_NewListObj\fR and \fBTcl_SetListObj\fR
create a new value or modify an existing value to hold
the \fIobjc\fR elements of the array referenced by \fIobjv\fR
where each element is a pointer to a Tcl value.
If \fIobjc\fR is less than or equal to zero,
they return an empty value. If \fIobjv\fR is NULL, the resulting list
contains 0 elements, with reserved space in an internal representation
for \fIobjc\fR more elements (to avoid its reallocation later).
The new value's string representation is left invalid.
The two procedures increment the reference counts
of the elements in \fIobjc\fR since the list value now refers to them.
The new list value returned by \fBTcl_NewListObj\fR
has reference count zero.
.PP
\fBTcl_ListObjGetElements\fR returns a count and a pointer to an array of
the elements in a list value. It returns the count by storing it in the
address \fIobjcPtr\fR. Similarly, it returns the array pointer by storing
it in the address \fIobjvPtr\fR.
The memory pointed to is managed by Tcl and should not be freed or written
to by the caller. If the list is empty, 0 is stored at \fIobjcPtr\fR
and NULL at \fIobjvPtr\fR. If \fIobjcPtr\fR points to a variable
of type \fBint\fR and the list contains more than 2**31 elements, the
function returns \fBTCL_ERROR\fR.
If \fIlistPtr\fR is not already a list value, \fBTcl_ListObjGetElements\fR
will attempt to convert it to one; if the conversion fails, it returns
\fBTCL_ERROR\fR and leaves an error message in the interpreter's result
value if \fIinterp\fR is not NULL.
Otherwise it returns \fBTCL_OK\fR after storing the count and array pointer.
.PP
\fBTcl_ListObjLength\fR returns the number of elements in the list value
referenced by \fIlistPtr\fR.
If the value is not already a list value,
\fBTcl_ListObjLength\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
and leaves an error message in the interpreter's result value
if \fIinterp\fR is not NULL.
Otherwise it returns \fBTCL_OK\fR after storing the list's length.
.PP
The procedure \fBTcl_ListObjIndex\fR returns a pointer to the value
at element \fIindex\fR in the list referenced by \fIlistPtr\fR.
It returns this value by storing a pointer to it
in the address \fIobjPtrPtr\fR.
If \fIlistPtr\fR does not already refer to a list value,
\fBTcl_ListObjIndex\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
and leaves an error message in the interpreter's result value
if \fIinterp\fR is not NULL.
If the index is out of range,
that is, \fIindex\fR is negative or
greater than or equal to the number of elements in the list,
\fBTcl_ListObjIndex\fR stores a NULL in \fIobjPtrPtr\fR
and returns \fBTCL_OK\fR.
Otherwise it returns \fBTCL_OK\fR after storing the element's
value pointer.
The reference count for the list element is not incremented;
the caller must do that if it needs to retain a pointer to the
element, or "bounce" the reference count when the element is no longer
needed. This is because a returned element may have a reference count
of 0. Abstract Lists create a new element Obj on demand, and do not
retain any element Obj values. Therefore, the caller is responsible for
freeing the element when it is no longer needed. Note that this is a
change from Tcl 8 where all list elements always have a reference
count of at least 1. (See \fBABSTRACT LIST TYPES\fR, \fBSTORAGE
MANAGEMENT OF VALUES\fR, Tcl_BounceRefCount(3), and lseq(n) for more
information.)
.PP
\fBTcl_ListObjReplace\fR replaces zero or more elements
of the list referenced by \fIlistPtr\fR
with the \fIobjc\fR values in the array referenced by \fIobjv\fR.
If \fIlistPtr\fR does not point to a list value,
\fBTcl_ListObjReplace\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
and leaves an error message in the interpreter's result value
if \fIinterp\fR is not NULL.
Otherwise, it returns \fBTCL_OK\fR after replacing the values.
If \fIobjv\fR is NULL, no new elements are added.
If the argument \fIfirst\fR is zero or negative,
it refers to the first element.
If \fIfirst\fR is greater than or equal to the
number of elements in the list, then no elements are deleted;
the new elements are appended to the list.
\fIcount\fR gives the number of elements to replace.
If \fIcount\fR is zero or negative then no elements are deleted;
the new elements are simply inserted before the one
designated by \fIfirst\fR.
\fBTcl_ListObjReplace\fR invalidates \fIlistPtr\fR's
old string representation.
The reference counts of any elements inserted from \fIobjv\fR
are incremented since the resulting list now refers to them.
Similarly, the reference counts for any replaced values are decremented.
.PP
Because \fBTcl_ListObjReplace\fR combines
both element insertion and deletion,
it can be used to implement a number of list operations.
For example, the following code inserts the \fIobjc\fR values
referenced by the array of value pointers \fIobjv\fR
just before the element \fIindex\fR of the list referenced by \fIlistPtr\fR:
.PP
.CS
result = \fBTcl_ListObjReplace\fR(interp, listPtr, index, 0,
objc, objv);
.CE
.PP
Similarly, the following code appends the \fIobjc\fR values
referenced by the array \fIobjv\fR
to the end of the list \fIlistPtr\fR:
.PP
.CS
result = \fBTcl_ListObjLength\fR(interp, listPtr, &length);
if (result == TCL_OK) {
result = \fBTcl_ListObjReplace\fR(interp, listPtr, length, 0,
objc, objv);
}
.CE
.PP
The \fIcount\fR list elements starting at \fIfirst\fR can be deleted
by simply calling \fBTcl_ListObjReplace\fR
with a NULL \fIobjvPtr\fR:
.PP
.CS
result = \fBTcl_ListObjReplace\fR(interp, listPtr, first, count,
0, NULL);
.CE
.PP
\fBTcl_ListObjRange\fR stores in \fIobjPtrPtr\fR a pointer to a list value
containing all elements in the passed input list \fIlistPtr\fR at indices
between \fIfirst\fR and \fIlast\fR, both inclusive. An empty
list is returned in the case of \fIfirst\fR being greater than \fIlast\fR.
.PP
\fBTcl_ListObjRepeat\fR stores in \fIobjPtrPtr\fR a pointer to a list value
whose elements are the \fIobjc\fR elements passed in \fIobjv\fR, repeated
\fIcount\fR number of times. An error is raised if \fIcount\fR is negative.
.PP
\fBTcl_ListObjReverse\fR stores in \fIobjPtrPtr\fR a pointer to a list value
containing all elements of the input list \fIlistPtr\fR in reverse order.
.PP
For all three functions, \fBTcl_ListObjRange\fR, \fBTcl_ListObjRepeat\fR and
\fBTcl_ListObjReverse\fR, the value passed in \fIlistPtr\fR need not be unshared.
The pointer stored at \fIobjPtrPtr\fR is guaranteed to be different from
\fIlistPtr\fR but no assumptions should be made about its reference count.
In case of errors, the location addressed by \fIobjPtrPtr\fR may have been
modified and should be treated by the caller as undefined.
.SH "REFERENCE COUNT MANAGEMENT"
.PP
Care must be taken by callers when managing the reference count
of values passed in as well as values returned from the above functions.
.PP
Unless specified otherwise below, the above functions may internally
keep a reference to the value passed in \fIlistPtr\fR and increment its
reference count. Therefore, if \fIlistPtr\fR is newly allocated and has
a zero reference count, it should not be freed after the call with
\fBTcl_DecrRefCount\fR. Rather, use \fBTcl_BounceRefCount\fR instead.
Furthermore, if \fIlistPtr\fR was retrieved from the interpreter result
(e.g. via \fBTcl_GetObjResult\fR) and that is the only reference to the
value, it may be deleted if a function sets the interpreter result on
error. The more general and safe method for passing values is to
increment their reference counts with \fBTcl_IncrRefCount\fR prior to
the call and release them with \fBTcl_DecrRefCount\fR when the call
returns. However, this may preclude certain optimizations based on
modifying unshared values in-place.
.PP
\fBTcl_NewListObj\fR always returns a zero-reference object, much like
\fBTcl_NewObj\fR. If a non-NULL \fIobjv\fR argument is given, the reference
counts of the first \fIobjc\fR values in that array are incremented.
.PP
\fBTcl_SetListObj\fR does not modify the reference count of its \fIobjPtr\fR
argument, but does require that the object be unshared. The reference counts
of the first \fIobjc\fR values in the \fIobjv\fR array are incremented.
.PP
\fBTcl_ListObjGetElements\fR, \fBTcl_ListObjIndex\fR, and
\fBTcl_ListObjLength\fR do not modify the reference count of the
\fIlistPtr\fR argument except on error when the interpreter
result holds a reference to it as described earlier.
.PP
\fBTcl_ListObjAppendList\fR, \fBTcl_ListObjAppendElement\fR, and
\fBTcl_ListObjReplace\fR require an unshared \fIlistPtr\fR argument.
\fBTcl_ListObjAppendList\fR only reads its \fIelemListPtr\fR argument.
\fBTcl_ListObjAppendElement\fR increments the reference count of its
\fIobjPtr\fR on success. \fBTcl_ListObjReplace\fR increments the
reference count of the first \fIobjc\fR values in the \fIobjv\fR array
on success. Note that the same caveat stated earlier applies if the
interpreter result holds a reference to \fIlistPtr\fR.
.PP
The pointer to a result value returned in \fIobjPtrPtr\fR by the
functions \fBTcl_ListObjRange\fR,
\fBTcl_ListObjRepeat\fR and \fBTcl_ListObjReverse\fR is guaranteed
to be different from the \fBlistPtr\fR passed in. It is therefore
safe to manage its reference count independently from that of
\fBlistPtr\fR. No assumptions should be made about its reference
count and the standard reference counting idiom should be followed.
The caller can pass it to a function such as \fBTcl_SetObjResult\fR,
\fBTcl_ListObjAppendElement\fR etc. which take ownership of
its reference count management or dispose of the value itself
with either a \fBTcl_IncrRefCount\fR/\fBTcl_DecrRefCount\fR pair or
\fBTcl_BounceRefCount\fR.
.SH "SEE ALSO"
Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_GetObjResult(3)
.SH KEYWORDS
append, index, insert, internal representation, length, list, list value,
list type, value, value type, replace, string representation
|