235 lines
10 KiB
Groff
235 lines
10 KiB
Groff
'\"
|
|
'\" Copyright (c) 2003 Donal K. Fellows
|
|
'\"
|
|
'\" See the file "license.terms" for information on usage and redistribution
|
|
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
'\"
|
|
.TH Tcl_DictObj 3 8.5 Tcl "Tcl Library Procedures"
|
|
.so man.macros
|
|
.BS
|
|
'\" Note: do not modify the .SH NAME line immediately below!
|
|
.SH 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
|
|
.SH SYNOPSIS
|
|
.nf
|
|
\fB#include <tcl.h>\fR
|
|
.sp
|
|
Tcl_Obj *
|
|
\fBTcl_NewDictObj\fR()
|
|
.sp
|
|
int
|
|
\fBTcl_DictObjGet\fR(\fIinterp, dictPtr, keyPtr, valuePtrPtr\fR)
|
|
.sp
|
|
int
|
|
\fBTcl_DictObjPut\fR(\fIinterp, dictPtr, keyPtr, valuePtr\fR)
|
|
.sp
|
|
int
|
|
\fBTcl_DictObjRemove\fR(\fIinterp, dictPtr, keyPtr\fR)
|
|
.sp
|
|
int
|
|
\fBTcl_DictObjSize\fR(\fIinterp, dictPtr, sizePtr\fR)
|
|
.sp
|
|
int
|
|
\fBTcl_DictObjFirst\fR(\fIinterp, dictPtr, searchPtr,
|
|
keyPtrPtr, valuePtrPtr, donePtr\fR)
|
|
.sp
|
|
void
|
|
\fBTcl_DictObjNext\fR(\fIsearchPtr, keyPtrPtr, valuePtrPtr, donePtr\fR)
|
|
.sp
|
|
void
|
|
\fBTcl_DictObjDone\fR(\fIsearchPtr\fR)
|
|
.sp
|
|
int
|
|
\fBTcl_DictObjPutKeyList\fR(\fIinterp, dictPtr, keyc, keyv, valuePtr\fR)
|
|
.sp
|
|
int
|
|
\fBTcl_DictObjRemoveKeyList\fR(\fIinterp, dictPtr, keyc, keyv\fR)
|
|
.SH ARGUMENTS
|
|
.AS Tcl_DictSearch "**valuePtrPtr" in/out
|
|
.AP 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 \fIinterp\fR is NULL.
|
|
.AP Tcl_Obj *dictPtr in/out
|
|
Points to the dictionary value to be manipulated.
|
|
If \fIdictPtr\fR does not already point to a dictionary value,
|
|
an attempt will be made to convert it to one.
|
|
.AP Tcl_Obj *keyPtr in
|
|
Points to the key for the key/value pair being manipulated within the
|
|
dictionary value.
|
|
.AP 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.
|
|
.AP Tcl_Obj *valuePtr in
|
|
Points to the value for the key/value pair being manipulated within the
|
|
dictionary value (or sub-value, in the case of
|
|
\fBTcl_DictObjPutKeyList\fR.)
|
|
.AP Tcl_Obj **valuePtrPtr out
|
|
Points to a variable that will have the value from a key/value pair
|
|
placed within it. For \fBTcl_DictObjFirst\fR and
|
|
\fBTcl_DictObjNext\fR, this may be NULL to indicate that the caller is
|
|
not interested in the value.
|
|
.AP int *sizePtr out
|
|
Points to a variable that will have the number of key/value pairs
|
|
contained within the dictionary placed within it.
|
|
.AP 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 \fBTcl_DictObjFirst\fR. If the enumerating
|
|
is to be terminated before all values in the dictionary have been
|
|
returned, the search record \fImust\fR be passed to
|
|
\fBTcl_DictObjDone\fR to enable the internal locks to be released.
|
|
.AP 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 otherwise.
|
|
.AP int keyc in
|
|
Indicates the number of keys that will be supplied in the \fIkeyv\fR
|
|
array.
|
|
.AP "Tcl_Obj *const" *keyv in
|
|
Array of \fIkeyc\fR pointers to values that
|
|
\fBTcl_DictObjPutKeyList\fR and \fBTcl_DictObjRemoveKeyList\fR will
|
|
use to locate the key/value pair to manipulate within the
|
|
sub-dictionaries of the main dictionary value passed to them.
|
|
.BE
|
|
|
|
.SH DESCRIPTION
|
|
.PP
|
|
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
|
|
modulo 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.
|
|
.PP
|
|
The procedures described in this man page are used to
|
|
create, modify, index, and iterate over dictionary values from C code.
|
|
.PP
|
|
\fBTcl_NewDictObj\fR creates a new, empty dictionary value. The
|
|
string representation of the value will be invalid, and the reference
|
|
count of the value will be zero.
|
|
.PP
|
|
\fBTcl_DictObjGet\fR looks up the given key within the given
|
|
dictionary and writes a pointer to the value associated with that key
|
|
into the variable pointed to by \fIvaluePtrPtr\fR, or a NULL if the
|
|
key has no mapping within the dictionary. The result of this
|
|
procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be
|
|
converted to a dictionary.
|
|
.PP
|
|
\fBTcl_DictObjPut\fR 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 \fBTCL_OK\fR, or
|
|
\fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be converted to a dictionary.
|
|
.PP
|
|
\fBTcl_DictObjRemove\fR 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 \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be
|
|
converted to a dictionary.
|
|
.PP
|
|
\fBTcl_DictObjSize\fR updates the given variable with the number of
|
|
key/value pairs currently in the given dictionary. The result of this
|
|
procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be
|
|
converted to a dictionary.
|
|
.PP
|
|
\fBTcl_DictObjFirst\fR 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 \fIkeyPtrPtr\fR and \fIvaluePtrPtr\fR
|
|
arguments (which may be NULL to indicate that the caller is
|
|
uninterested in they key or variable respectively.) The next
|
|
key/value pair in the dictionary may be retrieved with
|
|
\fBTcl_DictObjNext\fR. Concurrent updates of the dictionary's
|
|
internal representation will not modify the iteration processing
|
|
unless the dictionary is unshared, when this will trigger premature
|
|
termination of the iteration instead (which Tcl scripts cannot trigger
|
|
via the \fBdict\fR command.) The \fIsearchPtr\fR 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
|
|
\fBTcl_DictObjFirst\fR. The \fIdonePtr\fR argument points to a
|
|
variable that is updated to be zero of there are further key/value
|
|
pairs to be iterated over, or non-zero if the iteration is complete.
|
|
The order of iteration is implementation-defined. If the
|
|
\fIdictPtr\fR argument cannot be converted to a dictionary,
|
|
\fBTcl_DictObjFirst\fR returns \fBTCL_ERROR\fR and the iteration is not
|
|
commenced, and otherwise it returns \fBTCL_OK\fR.
|
|
.PP
|
|
When \fBTcl_DictObjFirst\fR 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 iteration. Because of
|
|
this, once the iteration over a dictionary's keys has finished (whether
|
|
because all values have been iterated over as indicated by the variable
|
|
indicated by the \fIdonePtr\fR argument being set to one, or because no
|
|
further values are required) the \fBTcl_DictObjDone\fR function must be called
|
|
with the same \fIsearchPtr\fR as was passed to \fBTcl_DictObjFirst\fR so that
|
|
the internal locks can be released. Once a particular \fIsearchPtr\fR is
|
|
passed to \fBTcl_DictObjDone\fR, passing it to \fBTcl_DictObjNext\fR (without
|
|
first initializing it with \fBTcl_DictObjFirst\fR) will result in no values
|
|
being produced and the variable pointed to by \fIdonePtr\fR being set to one.
|
|
It is safe to call \fBTcl_DictObjDone\fR multiple times on the same
|
|
\fIsearchPtr\fR for each call to \fBTcl_DictObjFirst\fR.
|
|
.PP
|
|
The procedures \fBTcl_DictObjPutKeyList\fR and
|
|
\fBTcl_DictObjRemoveKeyList\fR are the close analogues of
|
|
\fBTcl_DictObjPut\fR and \fBTcl_DictObjRemove\fR respectively, 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 \fIkeyc\fR and
|
|
\fIkeyv\fR 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
|
|
\fBTcl_DictObjGet\fR. With \fBTcl_DictObjPutKeyList\fR, nested
|
|
dictionaries are created for non-terminal keys where they do not
|
|
already exist. With \fBTcl_DictObjRemoveKeyList\fR, all non-terminal
|
|
keys must exist and have dictionaries as their values.
|
|
.SH EXAMPLE
|
|
Using the dictionary iteration interface to search determine if there
|
|
is a key that maps to itself:
|
|
.PP
|
|
.CS
|
|
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 (\fBTcl_DictObjFirst\fR(interp, objPtr, &search,
|
|
&key, &value, &done) != TCL_OK) {
|
|
return TCL_ERROR;
|
|
}
|
|
for (; !done ; \fBTcl_DictObjNext\fR(&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;
|
|
}
|
|
}
|
|
\fBTcl_DictObjDone\fR(&search);
|
|
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!done));
|
|
return TCL_OK;
|
|
.CE
|
|
.SH "SEE ALSO"
|
|
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_InitObjHashTable
|
|
.SH KEYWORDS
|
|
dict, dict value, dictionary, dictionary value, hash table, iteration, value
|