Provided by: tcl9.0-doc_9.0.1+dfsg-1_all bug

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)

       Tcl_DictObjNext(searchPtr, keyPtrPtr, valuePtrPtr, donePtr)

       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 manipulated
                                                  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  manipulated
                                                  within  the  dictionary  value  (or  sub-value, in the case of
                                                  Tcl_DictObjPutKeyList.)

       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.

       Tcl_Size | int *sizePtr (out)              Points to a variable that will have the  number  of  key/value
                                                  pairs  contained  within the dictionary placed within it.  May
                                                  be (Tcl_Size *)NULL when not used. If it points to a  variable
                                                  which  type  is  not  Tcl_Size,  a  compiler  warning  will be
                                                  generated.  If your extensions is compiled  with  -DTCL_8_API,
                                                  this  function  will  return NULL for dictionaries larger than
                                                  INT_MAX  (which   should   trigger   proper   error-handling),
                                                  otherwise expect it to crash.

       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 terminated
                                                  before all values in the dictionary have  been  returned,  the
                                                  search  record must be passed to Tcl_DictObjDone to enable the
                                                  internal 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 otherwise.

       Tcl_Size 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_DictObjPutKeyList
                                                  and  Tcl_DictObjRemoveKeyList 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 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.

       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 representation 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 variable 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
       dictionary.

       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
       dictionary or if sizePtr points to a variable of type int and the dict contains more than 2**31 key/value
       pairs.

       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  variable  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 termination 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  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  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
       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 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  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 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_DictObjPutKeyList, 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.

REFERENCE COUNT MANAGEMENT

       Tcl_NewDictObj always returns a zero-reference object, much like Tcl_NewObj.

       Tcl_DictObjPut  does  not  modify  the reference count of its dictPtr argument, but does require that the
       object be unshared.  If Tcl_DictObjPut returns TCL_ERROR it does not manipulate any reference counts; but
       if it returns TCL_OK then it definitely increments the reference count of valuePtr and may increment  the
       reference  count  of keyPtr; the latter case happens exactly when the key did not previously exist in the
       dictionary.  Note however that this function may set the interpreter result; if that is  the  only  place
       that is holding a reference to an object, it will be deleted.

       Tcl_DictObjGet  only reads from its dictPtr and keyPtr arguments, and does not manipulate their reference
       counts at all.  If the valuePtrPtr argument  is  not  set  to  NULL  (and  the  function  doesn't  return
       TCL_ERROR), it will be set to a value with a reference count of at least 1, with a reference owned by the
       dictionary.   Note  however  that this function may set the interpreter result; if that is the only place
       that is holding a reference to an object, it will be deleted.

       Tcl_DictObjRemove does not modify the reference count of its dictPtr argument, but does require that  the
       object  be  unshared.  It  does  not  manipulate the reference count of its keyPtr argument at all.  Note
       however that this function may set the interpreter result; if that is the only place that  is  holding  a
       reference to an object, it will be deleted.

       Tcl_DictObjSize does not modify the reference count of its dictPtr argument; it only reads.  Note however
       that  this function may set the interpreter result; if that is the only place that is holding a reference
       to the dictionary object, it will be deleted.

       Tcl_DictObjFirst does not modify the reference  count  of  its  dictPtr  argument;  it  only  reads.  The
       variables  given  by  the  keyPtrPtr  and  valuePtrPtr arguments (if not NULL) will be updated to contain
       references to the relevant values in the dictionary; their reference counts will be at least  1  (due  to
       the  dictionary  holding  a reference to them). It may also manipulate internal references; these are not
       exposed to user code, but require a matching Tcl_DictObjDone call.  Note however that this  function  may
       set  the  interpreter  result;  if  that  is the only place that is holding a reference to the dictionary
       object, it will be deleted.

       Similarly for Tcl_DictObjNext; the variables given by the keyPtrPtr and  valuePtrPtr  arguments  (if  not
       NULL)  will  be  updated  to contain references to the relevant values in the dictionary; their reference
       counts will be at least 1 (due to the dictionary holding a reference to them).

       Tcl_DictObjDone does not manipulate (user-visible) reference counts.

       Tcl_DictObjPutKeyList is similar to Tcl_DictObjPut; it does not modify the reference count of its dictPtr
       argument, but does require that the object be unshared. It may increment the reference count of any value
       passed in the keyv argument, and will increment the reference count of the valuePtr argument on  success.
       It  is  recommended  that  values  passed  via keyv and valuePtr do not have zero reference counts.  Note
       however that this function may set the interpreter result; if that is the only place that  is  holding  a
       reference to an object, it will be deleted.

       Tcl_DictObjRemoveKeyList  is  similar to Tcl_DictObjRemove; it does not modify the reference count of its
       dictPtr argument, but does require that the object be unshared, and does not modify the reference  counts
       of  any  of  the  values  passed  in  the  keyv  argument.   Note  however that this function may set the
       interpreter result; if that is the only place that is holding a  reference  to  an  object,  it  will  be
       deleted.

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(3tcl)