Tcl_DictObj(3) Tcl Library Procedures Tcl_DictObj(3)______________________________________________________________________________NAME
Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove,
Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone,
Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList - manipulate Tcl values
as dictionaries
SYNOPSIS
#include <tcl.h>
Tcl_Obj *
Tcl_NewDictObj()
int
Tcl_DictObjGet(interp, dictPtr, keyPtr, valuePtrPtr)
int
Tcl_DictObjPut(interp, dictPtr, keyPtr, valuePtr)
int
Tcl_DictObjRemove(interp, dictPtr, keyPtr)
int
Tcl_DictObjSize(interp, dictPtr, sizePtr)
int
Tcl_DictObjFirst(interp, dictPtr, searchPtr,
keyPtrPtr, valuePtrPtr, donePtr)
void
Tcl_DictObjNext(searchPtr, keyPtrPtr, valuePtrPtr, donePtr)
void
Tcl_DictObjDone(searchPtr)
int
Tcl_DictObjPutKeyList(interp, dictPtr, keyc, keyv, valuePtr)
int
Tcl_DictObjRemoveKeyList(interp, dictPtr, keyc, keyv)
ARGUMENTS
Tcl_Interp *interp (in) If an error occurs while
converting a value to be a
dictionary value, an error
message is left in the
interpreter's result value
unless interp is NULL.
Tcl_Obj *dictPtr (in/out) Points to the dictionary
value to be manipulated. If
dictPtr does not already
point to a dictionary value,
an attempt will be made to
convert it to one.
Tcl_Obj *keyPtr (in) Points to the key for the
key/value pair being manipu‐
lated within the dictionary
value.
Tcl_Obj **keyPtrPtr (out) Points to a variable that
will have the key from a
key/value pair placed within
it. May be NULL to indicate
that the caller is not
interested in the key.
Tcl_Obj *valuePtr (in) Points to the value for the
key/value pair being manipu‐
lated within the dictionary
value (or sub-value, in the
case of Tcl_DictOb‐
jPutKeyList.)
Tcl_Obj **valuePtrPtr (out) Points to a variable that
will have the value from a
key/value pair placed within
it. For Tcl_DictObjFirst
and Tcl_DictObjNext, this
may be NULL to indicate that
the caller is not interested
in the value.
int *sizePtr (out) Points to a variable that
will have the number of
key/value pairs contained
within the dictionary placed
within it.
Tcl_DictSearch *searchPtr (in/out) Pointer to record to use to
keep track of progress in
enumerating all key/value
pairs in a dictionary. The
contents of the record will
be initialized by the call
to Tcl_DictObjFirst. If the
enumerating is to be termi‐
nated before all values in
the dictionary have been
returned, the search record
must be passed to Tcl_DictO‐
bjDone to enable the inter‐
nal locks to be released.
int *donePtr (out) Points to a variable that
will have a non-zero value
written into it when the
enumeration of the key/value
pairs in a dictionary has
completed, and a zero other‐
wise.
int keyc (in) Indicates the number of keys
that will be supplied in the
keyv array.
Tcl_Obj *const *keyv (in) Array of keyc pointers to
values that Tcl_DictOb‐
jPutKeyList and Tcl_DictOb‐
jRemoveKeyList will use to
locate the key/value pair to
manipulate within the sub-
dictionaries of the main
dictionary value passed to
them.
_________________________________________________________________DESCRIPTION
Tcl dictionary values have an internal representation that supports
efficient mapping from keys to values and which guarantees that the
particular ordering of keys within the dictionary remains the same mod‐
ulo any keys being deleted (which removes them from the order) or added
(which adds them to the end of the order). If reinterpreted as a list,
the values at the even-valued indices in the list will be the keys of
the dictionary, and each will be followed (in the odd-valued index) by
the value associated with that key.
The procedures described in this man page are used to create, modify,
index, and iterate over dictionary values from C code.
Tcl_NewDictObj creates a new, empty dictionary value. The string rep‐
resentation of the value will be invalid, and the reference count of
the value will be zero.
Tcl_DictObjGet looks up the given key within the given dictionary and
writes a pointer to the value associated with that key into the vari‐
able pointed to by valuePtrPtr, or a NULL if the key has no mapping
within the dictionary. The result of this procedure is TCL_OK, or
TCL_ERROR if the dictPtr cannot be converted to a dictionary.
Tcl_DictObjPut updates the given dictionary so that the given key maps
to the given value; any key may exist at most once in any particular
dictionary. The dictionary must not be shared, but the key and value
may be. This procedure may increase the reference count of both key
and value if it proves necessary to store them. Neither key nor value
should be NULL. The result of this procedure is TCL_OK, or TCL_ERROR
if the dictPtr cannot be converted to a dictionary.
Tcl_DictObjRemove updates the given dictionary so that the given key
has no mapping to any value. The dictionary must not be shared, but
the key may be. The key actually stored in the dictionary will have
its reference count decremented if it was present. It is not an error
if the key did not previously exist. The result of this procedure is
TCL_OK, or TCL_ERROR if the dictPtr cannot be converted to a dictio‐
nary.
Tcl_DictObjSize updates the given variable with the number of key/value
pairs currently in the given dictionary. The result of this procedure
is TCL_OK, or TCL_ERROR if the dictPtr cannot be converted to a dictio‐
nary.
Tcl_DictObjFirst commences an iteration across all the key/value pairs
in the given dictionary, placing the key and value in the variables
pointed to by the keyPtrPtr and valuePtrPtr arguments (which may be
NULL to indicate that the caller is uninterested in they key or vari‐
able respectively.) The next key/value pair in the dictionary may be
retrieved with Tcl_DictObjNext. Concurrent updates of the dictionary's
internal representation will not modify the iteration processing unless
the dictionary is unshared, when this will trigger premature termina‐
tion of the iteration instead (which Tcl scripts cannot trigger via the
dict command.) The searchPtr argument points to a piece of context
that is used to identify which particular iteration is being performed,
and is initialized by the call to Tcl_DictObjFirst. The donePtr argu‐
ment points to a variable that is updated to be zero of there are fur‐
ther key/value pairs to be iterated over, or non-zero if the iteration
is complete. The order of iteration is implementation-defined. If the
dictPtr argument cannot be converted to a dictionary, Tcl_DictObjFirst
returns TCL_ERROR and the iteration is not commenced, and otherwise it
returns TCL_OK.
When Tcl_DictObjFirst is called upon a dictionary, a lock is placed on
the dictionary to enable that dictionary to be iterated over safely
without regard for whether the dictionary is modified during the itera‐
tion. Because of this, once the iteration over a dictionary's keys has
finished (whether because all values have been iterated over as indi‐
cated by the variable indicated by the donePtr argument being set to
one, or because no further values are required) the Tcl_DictObjDone
function must be called with the same searchPtr as was passed to
Tcl_DictObjFirst so that the internal locks can be released. Once a
particular searchPtr is passed to Tcl_DictObjDone, passing it to
Tcl_DictObjNext (without first initializing it with Tcl_DictObjFirst)
will result in no values being produced and the variable pointed to by
donePtr being set to one. It is safe to call Tcl_DictObjDone multiple
times on the same searchPtr for each call to Tcl_DictObjFirst.
The procedures Tcl_DictObjPutKeyList and Tcl_DictObjRemoveKeyList are
the close analogues of Tcl_DictObjPut and Tcl_DictObjRemove respec‐
tively, except that instead of working with a single dictionary, they
are designed to operate on a nested tree of dictionaries, with inner
dictionaries stored as values inside outer dictionaries. The keyc and
keyv arguments specify a list of keys (with outermost keys first) that
acts as a path to the key/value pair to be affected. Note that there
is no corresponding operation for reading a value for a path as this is
easy to construct from repeated use of Tcl_DictObjGet. With Tcl_DictOb‐
jPutKeyList, nested dictionaries are created for non-terminal keys
where they do not already exist. With Tcl_DictObjRemoveKeyList, all
non-terminal keys must exist and have dictionaries as their values.
EXAMPLE
Using the dictionary iteration interface to search determine if there
is a key that maps to itself:
Tcl_DictSearch search;
Tcl_Obj *key, *value;
int done;
/*
* Assume interp and objPtr are parameters. This is the
* idiomatic way to start an iteration over the dictionary; it
* sets a lock on the internal representation that ensures that
* there are no concurrent modification issues when normal
* reference count management is also used. The lock is
* released automatically when the loop is finished, but must
* be released manually when an exceptional exit from the loop
* is performed. However it is safe to try to release the lock
* even if we've finished iterating over the loop.
*/
if (Tcl_DictObjFirst(interp, objPtr, &search,
&key, &value, &done) != TCL_OK) {
return TCL_ERROR;
}
for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
/*
* Note that strcmp() is not a good way of comparing
* values and is just used here for demonstration
* purposes.
*/
if (!strcmp(Tcl_GetString(key), Tcl_GetString(value))) {
break;
}
}
Tcl_DictObjDone(&search);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!done));
return TCL_OK;
SEE ALSO
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_InitObjHashTable
KEYWORDS
dict, dict value, dictionary, dictionary value, hash table, iteration,
value
Tcl 8.5 Tcl_DictObj(3)