[AMG]: Tcl arrays are enumerated via the [[[array names]]] or [[[array get]]] commands or by the (virtually obsolete) combination of [[[array startsearch]]], [[[array nextelement]]], [[[array anymore]]], and [[[array donesearch]]]. At present, they cannot be enumerated via the Tcl C API. The [FlightAware] [Tcl bounty programme] [https://github.com/flightaware/Tcl-bounties] seeks to address this and other Tcl shortcomings. I intend to implement a Tcl C API for enumerating array elements. I am patterning my API on Tcl API listed above and on the C API for accessing variables. The implementation will be obtained by rearranging existing code as much as possible to minimize the inadvertent introduction of new bugs. The above-listed [[[array]]] commands will be reimplemented as calls into the new C API so that it can be tested by the existing Tcl test suite. This will be my first [TIP] and my first case of Tcl core programming. Outside of random bug and documentation fixes, my Tcl C experience is writing proprietary Tcl extensions over the last 10-15 years, and my Tcl scripting experience goes back to 1999. ---- **Code** http://core.tcl.tk/tcl/timeline?r=amg-array-enum-c-api ---- **API** Here is my working API design. Please share any comments or questions you may have. I welcome opinions about the alternatives and wishes I outline below, and please feel free to add your own ideas. ***Types*** ****typedef struct ArraySearch *Tcl_ArraySearch;**** Tcl_ArraySearch is an opaque pointer to struct ArraySearch which has the search internals. The term "search" is reused for the C API even though it's actually a full enumeration. ***Arguments*** ****Tcl_Interp *interp (in)**** Interpreter containing array variable. ****Tcl_Obj *varNamePtr (in)**** Points to a Tcl object containing the variable's name. The name may include a series of :: namespace qualifiers to specify an array varaible in a particular namespace. ****int *objcPtr (out)**** In flux. ****Tcl_Obj ***objvPtr (out)**** In flux. ****Tcl_ArraySearch search (in)**** Search token obtained from Tcl_ArraySearchStart(). ****int flags (in)**** OR-ed combination of bits providing additional information. Can be TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG. ***Functions*** ****int Tcl_ArraySize(interp, varNamePtr, flags)**** Returns array size or -1 on error. Alternative: Take an intPtr argument and return TCL_OK or TCL_ERROR. This approach matches Tcl_ListObjLength(). Wish: Optional exact/glob/regexp filter like [[[array names]]]. ****Tcl_ArraySearch Tcl_ArraySearchStart(interp, varNamePtr, flags)**** Returns a Tcl_ArraySearch on success or NULL on error. Wish: Optional exact/glob/regexp filter like [array names]. ****Tcl_Obj *Tcl_ArraySearchNext(search)**** Returns name of next element or NULL if finished. ****void Tcl_ArraySearchDone(search)**** Cleans up array search internals. Alternative name: Tcl_ArraySearchStop(). ****int Tcl_ArrayNames(interp, varNamePtr, objcPtr, objvPtr, flags)**** Gets a list of all array element names. Call ckfree() on objvPtr when done. Alternative: Give caller the option to manage objvPtr memory directly. Only automatically allocate if *objvPtr is NULL, otherwise assume it points to a block of memory big enough for Tcl_ArraySize() Tcl_Obj pointers. Alternative: Hybrid approach. If *objvPtr is not NULL and *objcPtr is at least Tcl_ArraySize(), use it directly as described above. If *objvPtr is not NULL but *objcPtr is insufficient, attemptckrealloc() *objvPtr to the minimum required size. This way, Tcl_ArrayGetNames() can be used many times in a row without allocating and freeing memory more than needed. Changes objcPtr and objvPtr to be (in/out). Even if glob filter wish is implemented, would still allocate to match the array size just in case the filter ends up matching everything. Alternative name: Tcl_ArrayGetNames(). Alternative: Store results into a list-type Tcl_Obj to simplify memory management and avoid [array names] having to make a copy. Wish: Optional exact/glob/regexp filter like [array names]. ---- **Progress** 20 November 2016 : Began work, implemented Tcl_ArraySize(). 24 November 2016 : Published commits, fixed [[[array size]]] reporting of trace errors, improved Wiki page. <>