1Tcl_DictObj(3) Tcl Library Procedures Tcl_DictObj(3)
2
3
4
5______________________________________________________________________________
6
8 Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove,
9 Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone,
10 Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList - manipulate Tcl values
11 as dictionaries
12
14 #include <tcl.h>
15
16 Tcl_Obj *
17 Tcl_NewDictObj()
18
19 int
20 Tcl_DictObjGet(interp, dictPtr, keyPtr, valuePtrPtr)
21
22 int
23 Tcl_DictObjPut(interp, dictPtr, keyPtr, valuePtr)
24
25 int
26 Tcl_DictObjRemove(interp, dictPtr, keyPtr)
27
28 int
29 Tcl_DictObjSize(interp, dictPtr, sizePtr)
30
31 int
32 Tcl_DictObjFirst(interp, dictPtr, searchPtr,
33 keyPtrPtr, valuePtrPtr, donePtr)
34
35 void
36 Tcl_DictObjNext(searchPtr, keyPtrPtr, valuePtrPtr, donePtr)
37
38 void
39 Tcl_DictObjDone(searchPtr)
40
41 int
42 Tcl_DictObjPutKeyList(interp, dictPtr, keyc, keyv, valuePtr)
43
44 int
45 Tcl_DictObjRemoveKeyList(interp, dictPtr, keyc, keyv)
46
48 Tcl_Interp *interp (in) If an error occurs while
49 converting a value to be a
50 dictionary value, an error
51 message is left in the in‐
52 terpreter's result value un‐
53 less interp is NULL.
54
55 Tcl_Obj *dictPtr (in/out) Points to the dictionary
56 value to be manipulated. If
57 dictPtr does not already
58 point to a dictionary value,
59 an attempt will be made to
60 convert it to one.
61
62 Tcl_Obj *keyPtr (in) Points to the key for the
63 key/value pair being manipu‐
64 lated within the dictionary
65 value.
66
67 Tcl_Obj **keyPtrPtr (out) Points to a variable that
68 will have the key from a
69 key/value pair placed within
70 it. May be NULL to indicate
71 that the caller is not in‐
72 terested in the key.
73
74 Tcl_Obj *valuePtr (in) Points to the value for the
75 key/value pair being manipu‐
76 lated within the dictionary
77 value (or sub-value, in the
78 case of Tcl_DictOb‐
79 jPutKeyList.)
80
81 Tcl_Obj **valuePtrPtr (out) Points to a variable that
82 will have the value from a
83 key/value pair placed within
84 it. For Tcl_DictObjFirst
85 and Tcl_DictObjNext, this
86 may be NULL to indicate that
87 the caller is not interested
88 in the value.
89
90 int *sizePtr (out) Points to a variable that
91 will have the number of
92 key/value pairs contained
93 within the dictionary placed
94 within it.
95
96 Tcl_DictSearch *searchPtr (in/out) Pointer to record to use to
97 keep track of progress in
98 enumerating all key/value
99 pairs in a dictionary. The
100 contents of the record will
101 be initialized by the call
102 to Tcl_DictObjFirst. If the
103 enumerating is to be termi‐
104 nated before all values in
105 the dictionary have been re‐
106 turned, the search record
107 must be passed to Tcl_DictO‐
108 bjDone to enable the inter‐
109 nal locks to be released.
110
111 int *donePtr (out) Points to a variable that
112 will have a non-zero value
113 written into it when the
114 enumeration of the key/value
115 pairs in a dictionary has
116 completed, and a zero other‐
117 wise.
118
119 int keyc (in) Indicates the number of keys
120 that will be supplied in the
121 keyv array.
122
123 Tcl_Obj *const *keyv (in) Array of keyc pointers to
124 values that Tcl_DictOb‐
125 jPutKeyList and Tcl_DictOb‐
126 jRemoveKeyList will use to
127 locate the key/value pair to
128 manipulate within the sub-
129 dictionaries of the main
130 dictionary value passed to
131 them.
132______________________________________________________________________________
133
134
136 Tcl dictionary values have an internal representation that supports ef‐
137 ficient mapping from keys to values and which guarantees that the par‐
138 ticular ordering of keys within the dictionary remains the same modulo
139 any keys being deleted (which removes them from the order) or added
140 (which adds them to the end of the order). If reinterpreted as a list,
141 the values at the even-valued indices in the list will be the keys of
142 the dictionary, and each will be followed (in the odd-valued index) by
143 the value associated with that key.
144
145 The procedures described in this man page are used to create, modify,
146 index, and iterate over dictionary values from C code.
147
148 Tcl_NewDictObj creates a new, empty dictionary value. The string rep‐
149 resentation of the value will be invalid, and the reference count of
150 the value will be zero.
151
152 Tcl_DictObjGet looks up the given key within the given dictionary and
153 writes a pointer to the value associated with that key into the vari‐
154 able pointed to by valuePtrPtr, or a NULL if the key has no mapping
155 within the dictionary. The result of this procedure is TCL_OK, or
156 TCL_ERROR if the dictPtr cannot be converted to a dictionary.
157
158 Tcl_DictObjPut updates the given dictionary so that the given key maps
159 to the given value; any key may exist at most once in any particular
160 dictionary. The dictionary must not be shared, but the key and value
161 may be. This procedure may increase the reference count of both key
162 and value if it proves necessary to store them. Neither key nor value
163 should be NULL. The result of this procedure is TCL_OK, or TCL_ERROR
164 if the dictPtr cannot be converted to a dictionary.
165
166 Tcl_DictObjRemove updates the given dictionary so that the given key
167 has no mapping to any value. The dictionary must not be shared, but
168 the key may be. The key actually stored in the dictionary will have
169 its reference count decremented if it was present. It is not an error
170 if the key did not previously exist. The result of this procedure is
171 TCL_OK, or TCL_ERROR if the dictPtr cannot be converted to a dictio‐
172 nary.
173
174 Tcl_DictObjSize updates the given variable with the number of key/value
175 pairs currently in the given dictionary. The result of this procedure
176 is TCL_OK, or TCL_ERROR if the dictPtr cannot be converted to a dictio‐
177 nary.
178
179 Tcl_DictObjFirst commences an iteration across all the key/value pairs
180 in the given dictionary, placing the key and value in the variables
181 pointed to by the keyPtrPtr and valuePtrPtr arguments (which may be
182 NULL to indicate that the caller is uninterested in they key or vari‐
183 able respectively.) The next key/value pair in the dictionary may be
184 retrieved with Tcl_DictObjNext. Concurrent updates of the dictionary's
185 internal representation will not modify the iteration processing unless
186 the dictionary is unshared, when this will trigger premature termina‐
187 tion of the iteration instead (which Tcl scripts cannot trigger via the
188 dict command.) The searchPtr argument points to a piece of context
189 that is used to identify which particular iteration is being performed,
190 and is initialized by the call to Tcl_DictObjFirst. The donePtr argu‐
191 ment points to a variable that is updated to be zero of there are fur‐
192 ther key/value pairs to be iterated over, or non-zero if the iteration
193 is complete. The order of iteration is implementation-defined. If the
194 dictPtr argument cannot be converted to a dictionary, Tcl_DictObjFirst
195 returns TCL_ERROR and the iteration is not commenced, and otherwise it
196 returns TCL_OK.
197
198 When Tcl_DictObjFirst is called upon a dictionary, a lock is placed on
199 the dictionary to enable that dictionary to be iterated over safely
200 without regard for whether the dictionary is modified during the itera‐
201 tion. Because of this, once the iteration over a dictionary's keys has
202 finished (whether because all values have been iterated over as indi‐
203 cated by the variable indicated by the donePtr argument being set to
204 one, or because no further values are required) the Tcl_DictObjDone
205 function must be called with the same searchPtr as was passed to
206 Tcl_DictObjFirst so that the internal locks can be released. Once a
207 particular searchPtr is passed to Tcl_DictObjDone, passing it to
208 Tcl_DictObjNext (without first initializing it with Tcl_DictObjFirst)
209 will result in no values being produced and the variable pointed to by
210 donePtr being set to one. It is safe to call Tcl_DictObjDone multiple
211 times on the same searchPtr for each call to Tcl_DictObjFirst.
212
213 The procedures Tcl_DictObjPutKeyList and Tcl_DictObjRemoveKeyList are
214 the close analogues of Tcl_DictObjPut and Tcl_DictObjRemove respec‐
215 tively, except that instead of working with a single dictionary, they
216 are designed to operate on a nested tree of dictionaries, with inner
217 dictionaries stored as values inside outer dictionaries. The keyc and
218 keyv arguments specify a list of keys (with outermost keys first) that
219 acts as a path to the key/value pair to be affected. Note that there
220 is no corresponding operation for reading a value for a path as this is
221 easy to construct from repeated use of Tcl_DictObjGet. With Tcl_DictOb‐
222 jPutKeyList, nested dictionaries are created for non-terminal keys
223 where they do not already exist. With Tcl_DictObjRemoveKeyList, all
224 non-terminal keys must exist and have dictionaries as their values.
225
227 Using the dictionary iteration interface to search determine if there
228 is a key that maps to itself:
229
230 Tcl_DictSearch search;
231 Tcl_Obj *key, *value;
232 int done;
233
234 /*
235 * Assume interp and objPtr are parameters. This is the
236 * idiomatic way to start an iteration over the dictionary; it
237 * sets a lock on the internal representation that ensures that
238 * there are no concurrent modification issues when normal
239 * reference count management is also used. The lock is
240 * released automatically when the loop is finished, but must
241 * be released manually when an exceptional exit from the loop
242 * is performed. However it is safe to try to release the lock
243 * even if we've finished iterating over the loop.
244 */
245 if (Tcl_DictObjFirst(interp, objPtr, &search,
246 &key, &value, &done) != TCL_OK) {
247 return TCL_ERROR;
248 }
249 for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
250 /*
251 * Note that strcmp() is not a good way of comparing
252 * values and is just used here for demonstration
253 * purposes.
254 */
255 if (!strcmp(Tcl_GetString(key), Tcl_GetString(value))) {
256 break;
257 }
258 }
259 Tcl_DictObjDone(&search);
260 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!done));
261 return TCL_OK;
262
264 Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_InitObjHashTable
265
267 dict, dict value, dictionary, dictionary value, hash table, iteration,
268 value
269
270
271
272Tcl 8.5 Tcl_DictObj(3)