[25] | 1 | '\" |
---|
| 2 | '\" Copyright (c) 2003 Donal K. Fellows |
---|
| 3 | '\" |
---|
| 4 | '\" See the file "license.terms" for information on usage and redistribution |
---|
| 5 | '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
| 6 | '\" |
---|
| 7 | '\" RCS: @(#) $Id: DictObj.3,v 1.11 2007/12/13 15:22:31 dgp Exp $ |
---|
| 8 | '\" |
---|
| 9 | .so man.macros |
---|
| 10 | .TH Tcl_DictObj 3 8.5 Tcl "Tcl Library Procedures" |
---|
| 11 | .BS |
---|
| 12 | '\" Note: do not modify the .SH NAME line immediately below! |
---|
| 13 | .SH NAME |
---|
| 14 | Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove, Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone, Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList \- manipulate Tcl objects as dictionaries |
---|
| 15 | .SH SYNOPSIS |
---|
| 16 | .nf |
---|
| 17 | \fB#include <tcl.h>\fR |
---|
| 18 | .sp |
---|
| 19 | Tcl_Obj * |
---|
| 20 | \fBTcl_NewDictObj\fR() |
---|
| 21 | .sp |
---|
| 22 | int |
---|
| 23 | \fBTcl_DictObjGet\fR(\fIinterp, dictPtr, keyPtr, valuePtrPtr\fR) |
---|
| 24 | .sp |
---|
| 25 | int |
---|
| 26 | \fBTcl_DictObjPut\fR(\fIinterp, dictPtr, keyPtr, valuePtr\fR) |
---|
| 27 | .sp |
---|
| 28 | int |
---|
| 29 | \fBTcl_DictObjRemove\fR(\fIinterp, dictPtr, keyPtr\fR) |
---|
| 30 | .sp |
---|
| 31 | int |
---|
| 32 | \fBTcl_DictObjSize\fR(\fIinterp, dictPtr, sizePtr\fR) |
---|
| 33 | .sp |
---|
| 34 | int |
---|
| 35 | \fBTcl_DictObjFirst\fR(\fIinterp, dictPtr, searchPtr, |
---|
| 36 | keyPtrPtr, valuePtrPtr, donePtr\fR) |
---|
| 37 | .sp |
---|
| 38 | void |
---|
| 39 | \fBTcl_DictObjNext\fR(\fIsearchPtr, keyPtrPtr, valuePtrPtr, donePtr\fR) |
---|
| 40 | .sp |
---|
| 41 | void |
---|
| 42 | \fBTcl_DictObjDone\fR(\fIsearchPtr\fR) |
---|
| 43 | .sp |
---|
| 44 | int |
---|
| 45 | \fBTcl_DictObjPutKeyList\fR(\fIinterp, dictPtr, keyc, keyv, valuePtr\fR) |
---|
| 46 | .sp |
---|
| 47 | int |
---|
| 48 | \fBTcl_DictObjRemoveKeyList\fR(\fIinterp, dictPtr, keyc, keyv\fR) |
---|
| 49 | .SH ARGUMENTS |
---|
| 50 | .AS Tcl_DictSearch "**valuePtrPtr" in/out |
---|
| 51 | .AP Tcl_Interp *interp in |
---|
| 52 | If an error occurs while converting an object to be a dictionary object, |
---|
| 53 | an error message is left in the interpreter's result object |
---|
| 54 | unless \fIinterp\fR is NULL. |
---|
| 55 | .AP Tcl_Obj *dictPtr in/out |
---|
| 56 | Points to the dictionary object to be manipulated. |
---|
| 57 | If \fIdictPtr\fR does not already point to a dictionary object, |
---|
| 58 | an attempt will be made to convert it to one. |
---|
| 59 | .AP Tcl_Obj *keyPtr in |
---|
| 60 | Points to the key for the key/value pair being manipulated within the |
---|
| 61 | dictionary object. |
---|
| 62 | .AP Tcl_Obj **keyPtrPtr out |
---|
| 63 | Points to a variable that will have the key from a key/value pair |
---|
| 64 | placed within it. May be NULL to indicate that the caller is not |
---|
| 65 | interested in the key. |
---|
| 66 | .AP Tcl_Obj *valuePtr in |
---|
| 67 | Points to the value for the key/value pair being manipulate within the |
---|
| 68 | dictionary object (or sub-object, in the case of |
---|
| 69 | \fBTcl_DictObjPutKeyList\fR.) |
---|
| 70 | .AP Tcl_Obj **valuePtrPtr out |
---|
| 71 | Points to a variable that will have the value from a key/value pair |
---|
| 72 | placed within it. For \fBTcl_DictObjFirst\fR and |
---|
| 73 | \fBTcl_DictObjNext\fR, this may be NULL to indicate that the caller is |
---|
| 74 | not interested in the value. |
---|
| 75 | .AP int *sizePtr out |
---|
| 76 | Points to a variable that will have the number of key/value pairs |
---|
| 77 | contained within the dictionary placed within it. |
---|
| 78 | .AP Tcl_DictSearch *searchPtr in/out |
---|
| 79 | Pointer to record to use to keep track of progress in enumerating all |
---|
| 80 | key/value pairs in a dictionary. The contents of the record will be |
---|
| 81 | initialized by the call to \fBTcl_DictObjFirst\fR. If the enumerating |
---|
| 82 | is to be terminated before all values in the dictionary have been |
---|
| 83 | returned, the search record \fImust\fR be passed to |
---|
| 84 | \fBTcl_DictObjDone\fR to enable the internal locks to be released. |
---|
| 85 | .AP int *donePtr out |
---|
| 86 | Points to a variable that will have a non-zero value written into it |
---|
| 87 | when the enumeration of the key/value pairs in a dictionary has |
---|
| 88 | completed, and a zero otherwise. |
---|
| 89 | .AP int keyc in |
---|
| 90 | Indicates the number of keys that will be supplied in the \fIkeyv\fR |
---|
| 91 | array. |
---|
| 92 | .AP "Tcl_Obj *const" *keyv in |
---|
| 93 | Array of \fIkeyc\fR pointers to objects that |
---|
| 94 | \fBTcl_DictObjPutKeyList\fR and \fBTcl_DictObjRemoveKeyList\fR will |
---|
| 95 | use to locate the key/value pair to manipulate within the |
---|
| 96 | sub-dictionaries of the main dictionary object passed to them. |
---|
| 97 | .BE |
---|
| 98 | |
---|
| 99 | .SH DESCRIPTION |
---|
| 100 | .PP |
---|
| 101 | Tcl dictionary objects have an internal representation that supports |
---|
| 102 | efficient mapping from keys to values and which guarantees that the |
---|
| 103 | particular ordering of keys within the dictionary remains the same |
---|
| 104 | modulo any keys being deleted (which removes them from the order) or |
---|
| 105 | added (which adds them to the end of the order). If reinterpreted as a |
---|
| 106 | list, the values at the even-valued indices in the list will be the |
---|
| 107 | keys of the dictionary, and each will be followed (in the odd-valued |
---|
| 108 | index) bu the value associated with that key. |
---|
| 109 | .PP |
---|
| 110 | The procedures described in this man page are used to |
---|
| 111 | create, modify, index, and iterate over dictionary objects from C code. |
---|
| 112 | .PP |
---|
| 113 | \fBTcl_NewDictObj\fR creates a new, empty dictionary object. The |
---|
| 114 | string representation of the object will be invalid, and the reference |
---|
| 115 | count of the object will be zero. |
---|
| 116 | .PP |
---|
| 117 | \fBTcl_DictObjGet\fR looks up the given key within the given |
---|
| 118 | dictionary and writes a pointer to the value associated with that key |
---|
| 119 | into the variable pointed to by \fIvaluePtrPtr\fR, or a NULL if the |
---|
| 120 | key has no mapping within the dictionary. The result of this |
---|
| 121 | procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be |
---|
| 122 | converted to a dictionary. |
---|
| 123 | .PP |
---|
| 124 | \fBTcl_DictObjPut\fR updates the given dictionary so that the given |
---|
| 125 | key maps to the given value; any key may exist at most once in any |
---|
| 126 | particular dictionary. The dictionary must not be shared, but the key |
---|
| 127 | and value may be. This procedure may increase the reference count of |
---|
| 128 | both key and value if it proves necessary to store them. Neither key |
---|
| 129 | nor value should be NULL. The result of this procedure is \fBTCL_OK\fR, or |
---|
| 130 | \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be converted to a dictionary. |
---|
| 131 | .PP |
---|
| 132 | \fBTcl_DictObjRemove\fR updates the given dictionary so that the given |
---|
| 133 | key has no mapping to any value. The dictionary must not be shared, |
---|
| 134 | but the key may be. The key actually stored in the dictionary will |
---|
| 135 | have its reference count decremented if it was present. It is not an |
---|
| 136 | error if the key did not previously exist. The result of this |
---|
| 137 | procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be |
---|
| 138 | converted to a dictionary. |
---|
| 139 | .PP |
---|
| 140 | \fBTcl_DictObjSize\fR updates the given variable with the number of |
---|
| 141 | key/value pairs currently in the given dictionary. The result of this |
---|
| 142 | procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be |
---|
| 143 | converted to a dictionary. |
---|
| 144 | .PP |
---|
| 145 | \fBTcl_DictObjFirst\fR commences an iteration across all the key/value |
---|
| 146 | pairs in the given dictionary, placing the key and value in the |
---|
| 147 | variables pointed to by the \fIkeyPtrPtr\fR and \fIvaluePtrPtr\fR |
---|
| 148 | arguments (which may be NULL to indicate that the caller is |
---|
| 149 | uninterested in they key or variable respectively.) The next |
---|
| 150 | key/value pair in the dictionary may be retrieved with |
---|
| 151 | \fBTcl_DictObjNext\fR. Concurrent updates of the dictionary's |
---|
| 152 | internal representation will not modify the iteration processing |
---|
| 153 | unless the dictionary is unshared, when this will trigger premature |
---|
| 154 | termination of the iteration instead (which Tcl scripts cannot trigger |
---|
| 155 | via the \fBdict\fR command.) The \fIsearchPtr\fR argument points to a |
---|
| 156 | piece of context that is used to identify which particular iteration |
---|
| 157 | is being performed, and is initialized by the call to |
---|
| 158 | \fBTcl_DictObjFirst\fR. The \fIdonePtr\fR argument points to a |
---|
| 159 | variable that is updated to be zero of there are further key/value |
---|
| 160 | pairs to be iterated over, or non-zero if the iteration is complete. |
---|
| 161 | The order of iteration is implementation-defined. If the |
---|
| 162 | \fIdictPtr\fR argument cannot be converted to a dictionary, |
---|
| 163 | \fBTcl_DictObjFirst\fR returns \fBTCL_ERROR\fR and the iteration is not |
---|
| 164 | commenced, and otherwise it returns \fBTCL_OK\fR. |
---|
| 165 | .PP |
---|
| 166 | When \fBTcl_DictObjFirst\fR is called upon a dictionary, a lock is placed on |
---|
| 167 | the dictionary to enable that dictionary to be iterated over safely without |
---|
| 168 | regard for whether the dictionary is modified during the iteration. Because of |
---|
| 169 | this, once the iteration over a dictionary's keys has finished (whether |
---|
| 170 | because all values have been iterated over as indicated by the variable |
---|
| 171 | indicated by the \fIdonePtr\fR argument being set to one, or because no |
---|
| 172 | further values are required) the \fBTcl_DictObjDone\fR function must be called |
---|
| 173 | with the same \fIsearchPtr\fR as was passed to \fBTcl_DictObjFirst\fR so that |
---|
| 174 | the internal locks can be released. Once a particular \fIsearchPtr\fR is |
---|
| 175 | passed to \fBTcl_DictObjDone\fR, passing it to \fBTcl_DictObjNext\fR (without |
---|
| 176 | first initializing it with \fBTcl_DictObjFirst\fR) will result in no values |
---|
| 177 | being produced and the variable pointed to by \fIdonePtr\fR being set to one. |
---|
| 178 | It is safe to call \fBTcl_DictObjDone\fR multiple times on the same |
---|
| 179 | \fIsearchPtr\fR for each call to \fBTcl_DictObjFirst\fR. |
---|
| 180 | .PP |
---|
| 181 | The procedures \fBTcl_DictObjPutKeyList\fR and |
---|
| 182 | \fBTcl_DictObjRemoveKeyList\fR are the close analogues of |
---|
| 183 | \fBTcl_DictObjPut\fR and \fBTcl_DictObjRemove\fR respectively, except |
---|
| 184 | that instead of working with a single dictionary, they are designed to |
---|
| 185 | operate on a nested tree of dictionaries, with inner dictionaries |
---|
| 186 | stored as values inside outer dictionaries. The \fIkeyc\fR and |
---|
| 187 | \fIkeyv\fR arguments specify a list of keys (with outermost keys |
---|
| 188 | first) that acts as a path to the key/value pair to be affected. Note |
---|
| 189 | that there is no corresponding operation for reading a value for a |
---|
| 190 | path as this is easy to construct from repeated use of |
---|
| 191 | \fBTcl_DictObjGet\fR. With \fBTcl_DictObjPutKeyList\fR, nested |
---|
| 192 | dictionaries are created for non-terminal keys where they do not |
---|
| 193 | already exist. With \fBTcl_DictObjRemoveKeyList\fR, all non-terminal |
---|
| 194 | keys must exist and have dictionaries as their values. |
---|
| 195 | .SH EXAMPLE |
---|
| 196 | Using the dictionary iteration interface to search determine if there |
---|
| 197 | is a key that maps to itself: |
---|
| 198 | .PP |
---|
| 199 | .CS |
---|
| 200 | Tcl_DictSearch search; |
---|
| 201 | Tcl_Obj *key, *value; |
---|
| 202 | int done; |
---|
| 203 | |
---|
| 204 | /* |
---|
| 205 | * Assume interp and objPtr are parameters. This is the |
---|
| 206 | * idiomatic way to start an iteration over the dictionary; it |
---|
| 207 | * sets a lock on the internal representation that ensures that |
---|
| 208 | * there are no concurrent modification issues when normal |
---|
| 209 | * reference count management is also used. The lock is |
---|
| 210 | * released automatically when the loop is finished, but must |
---|
| 211 | * be released manually when an exceptional exit from the loop |
---|
| 212 | * is performed. However it is safe to try to release the lock |
---|
| 213 | * even if we've finished iterating over the loop. |
---|
| 214 | */ |
---|
| 215 | if (\fBTcl_DictObjFirst\fR(interp, objPtr, &search, |
---|
| 216 | &key, &value, &done) != TCL_OK) { |
---|
| 217 | return TCL_ERROR; |
---|
| 218 | } |
---|
| 219 | for (; done ; \fBTcl_DictObjNext\fR(&search, &key, &value, &done)) { |
---|
| 220 | /* |
---|
| 221 | * Note that strcmp() is not a good way of comparing |
---|
| 222 | * objects and is just used here for demonstration |
---|
| 223 | * purposes. |
---|
| 224 | */ |
---|
| 225 | if (!strcmp(Tcl_GetString(key), Tcl_GetString(value))) { |
---|
| 226 | break; |
---|
| 227 | } |
---|
| 228 | } |
---|
| 229 | \fBTcl_DictObjDone\fR(&search); |
---|
| 230 | Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!done)); |
---|
| 231 | return TCL_OK; |
---|
| 232 | .CE |
---|
| 233 | .SH "SEE ALSO" |
---|
| 234 | Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_InitObjHashTable |
---|
| 235 | .SH KEYWORDS |
---|
| 236 | dict, dict object, dictionary, dictionary object, hash table, iteration, object |
---|