TIP:            235
Title:          Exposing a C API for Ensembles
Version:        $Revision: 1.9 $
Author:         Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
State:          Final
Type:           Project
Vote:           Done
Created:        10-Dec-2004
Post-History:   
Tcl-Version:    8.5

~ Abstract

This TIP exposes a C API for the ensembles of [112].

~ Rationale

As the Tcl core moves to make more use of ensembles, it becomes more
necessary for there to be an API available to allow control over those
ensembles from the C level so that it is not necessary for such
manipulation to be done through the evaluation of Tcl scripts
(e.g. because this interferes with the interpreter's command count and
that may be limited in that particular interpreter). Given such an
API, it should be exposed to code outside the Tcl core if at all
possible.

~ Proposed Change

This TIP proposes exposing the following functions:

 Tcl_CreateEnsemble: Create an ensemble linked to a particular
   namespace and return the command token for the namespace command.
   The ''flags'' argument specifies the initial version of the set of
   flags controllable through Tcl_SetEnsembleFlags (see below).

 > > Tcl_Command '''Tcl_CreateEnsemble'''(Tcl_Interp *''interp'', const char *''name'', Tcl_Namespace *''namespacePtr'', int ''flags'')

 Tcl_FindEnsemble: Return a command token for an ensemble, or NULL if
   the name does not refer to an ensemble. The ''flags'' argument
   controls whether failure to find an ensemble is an error and should
   be either 0 or TCL_LEAVE_ERR_MSG.

 > > Tcl_Command '''Tcl_FindEnsemble'''(Tcl_Interp *''interp'', Tcl_Obj *''cmdNameObj'', int ''flags'')

 Tcl_IsEnsemble: Test whether a command token refers to an ensemble.

 > > int '''Tcl_IsEnsemble'''(Tcl_Command ''command'')

 Tcl_GetEnsembleSubcommandList, Tcl_SetEnsembleSubcommandList: Read
   and write the (fixed) list of subcommands of the ensemble.
   Equivalent to manipulating the '''-subcommands''' option.

 > > int '''Tcl_GetEnsembleSubcommandList'''(Tcl_Interp *''interp'', Tcl_Command ''command'', Tcl_Obj **''subcmdListObjPtr'')

 > > int '''Tcl_SetEnsembleSubcommandList'''(Tcl_Interp *''interp'', Tcl_Command ''command'', Tcl_Obj *''subcmdListObj'')

 Tcl_GetEnsembleMappingDict, Tcl_SetEnsembleMappingDict: Read and
   write the dictionary that maps subcommands to prefixes of
   implementation commands. Equivalent to manipulating the '''-map'''
   option.

 > > int '''Tcl_GetEnsembleMappingDict'''(Tcl_Interp *''interp'', Tcl_Command ''command'', Tcl_Obj **''mapDictObjPtr'')

 > > int '''Tcl_SetEnsembleMappingDict'''(Tcl_Interp *''interp'', Tcl_Command ''command'', Tcl_Obj *''mapDictObj'')

 Tcl_GetEnsembleUnknownHandler, Tcl_SetEnsembleUnknownHandler: Read
   and write the command prefix list that is used to implement the
   unknown-subcommand handler. Equivalent to manipulating the
   '''-unknown''' option.

 > > int '''Tcl_GetEnsembleUnknownHandler'''(Tcl_Interp *''interp'', Tcl_Command ''command'', Tcl_Obj **''handlerListObjPtr'')

 > > int '''Tcl_SetEnsembleUnknownHandler'''(Tcl_Interp *''interp'', Tcl_Command ''command'', Tcl_Obj *''handlerListObj'')

 Tcl_GetEnsembleFlags, Tcl_SetEnsembleFlags: Read and write the flags
   for the ensemble. Currently there is only one settable flag bit,
   TCL_ENSEMBLE_PREFIX, which is present exactly when '''-prefix'''
   option is true.

 > > int '''Tcl_GetEnsembleFlags'''(Tcl_Interp *''interp'', Tcl_Command ''command'', int *''flagsPtr'')

 > > int '''Tcl_SetEnsembleFlags'''(Tcl_Interp *''interp'', Tcl_Command ''command'', int ''flags'')

 Tcl_GetEnsembleNamespace: Reads the namespace associated with the
   ensemble; this value may not be altered.

 > > int '''Tcl_GetEnsembleNamespace'''(Tcl_Interp *''interp'', Tcl_Command ''command'', Tcl_Namespace **''namespacePtrPtr'')

~~ Notes

The handle for an ensemble is a normal Tcl_Command handle, and any
operation valid on such a command (e.g. deleting it or finding its name) 
is valid. Ensembles are just a special subclass of commands. This allows
the ensemble API to be considerably sparser than it would otherwise have
to be.

~ Reference Implementation

The API is already in the core, but with internal naming and not
exposed to anyone. Exposure is just renaming a few functions and
putting them in the stubs table. No new types are exposed. All this
means that a reference implementation is truly trivial.

~ Copyright

This document has been placed in the public domain.
