Tcl_AddInterpResolvers(3)

NAME
Tcl_AddInterpResolvers, Tcl_GetInterpResolvers, Tcl_RemoveInterpResolvers, Tcl_SetNamespaceResolvers, Tcl_GetNamespaceResolvers - change the name resolution rules for commands/variables

SYNOPSIS
#include <tcl.h>

void
Tcl_AddInterpResolvers(interp, name, cmdProc, varProc, compiledVarProc)

int
Tcl_GetInterpResolvers(interp, name, resInfoPtr)

int
Tcl_RemoveInterpResolvers(interp, name)

void
Tcl_SetNamespaceResolvers(namespacePtr, cmdProc, varProc, compiledVarProc)

int
Tcl_GetNamespaceResolvers(namespacePtr, resInfoPtr)

ARGUMENTS
Interpreter whose name resolution rules are being queried or modified. Name for a group of name resolution procedures. Procedure which will be used to resolve command names. Procedure which will be used to resolve variable names at run time. Procedure which will be used to resolve variable names at compile time. Returns the resolution procedures that are currently in effect for a particular namespace or for a particular name resolution scheme in the interpreter. Namespace whose name resolution rules are being queried or modified.

DESCRIPTION

These procedures make it possible to change the way that Tcl resolves command/variable names. The name resolution rules are changed by supplying three procedures: cmdProc, varProc, and compiledVarProc. See the section HOW NAME RESOLUTION PROCEDURES WORK for details about these procedures.

The name resolution rules can be changed for a particular namespace, for an entire interpreter, or both. When a name needs to be resolved, Tcl handles it as follows. The name resolution scheme for the current namespace is consulted first. Each of the name resolution schemes for the interpreter are consulted next. Finally, Tcl uses the default rules for name resolution as described for the namespace command.

Tcl_AddInterpResolver adds a set of name resolution procedures to an interpreter. The procedures are identified by a string name, so they can be queried or deleted later on. All of the name resolution schemes for the interpreter are kept on a list, and they are consulted in order from most- to least-recently added. For example, suppose one extension adds a name resolution scheme called "fred", and another extension adds another scheme called "barney". When a name is resolved, the "barney" scheme will be consulted first, followed by the "fred" scheme, if necessary.

Tcl_GetInterpResolver looks for a particular name resolution scheme in an interpreter. If the name is recognized, this procedure returns a non-zero value along with pointers to the name resolution procedures in the resInfoPtr structure. Otherwise, the procedure returns 0.

Tcl_RemoveInterpResolver looks for a particular name resolution scheme in an interpreter. If the name is recognized, this procedure deletes the scheme and returns a non-zero value. Otherwise, it returns 0.

Tcl_SetNamespaceResolver sets the name resolution procedures for a particular namespace. Unlike an interpreter, a namespace can have only one name resolution scheme in effect at any given time.

Tcl_GetNamespaceResolver returns the name resolution procedures for a particular namespace. If the namespace has a special name resolution scheme, this procedure returns a non-zero value along with pointers to the name resolution procedures in the resInfoPtr structure. Otherwise, the procedure returns 0.

HOW NAME RESOLUTION PROCEDURES WORK
A name resolution scheme is enforced by three name resolution procedures. The cmdProc procedure is used to resolve command names. It must conform to the following type: typedef int Tcl_ResolveCmdProc(Tcl_Interp* interp,
        char* name, Tcl_Namespace* context, int flags,
        Tcl_Command* rPtr); The interp argument is the interpreter performing the resolution; name is the command name being resolved; context is the namespace context containing the command reference; and flags may contain TCL_LEAVE_ERR_MSG.

If this procedure recognizes the command name, it should store the Tcl_Command token for that command in the rPtr argument and return TCL_OK. If this procedure doesn't recognize the command name, it should return TCL_CONTINUE, and the name resolution will continue with another procedure or with the default Tcl resolution scheme. If this procedure recognizes the command name, but for some reason the command is invalid, the procedure should return TCL_ERROR. If the flags argument contains TCL_LEAVE_ERR_MSG, the procedure should leave an error message in the interpreter, explaining why the command is invalid.

The varProc procedure is similar to cmdProc, but it is used to resolve variable names encountered at run time. It must conform to the following type: typedef int Tcl_ResolveVarProc(Tcl_Interp* interp,
        char* name, Tcl_Namespace* context, int flags,
        Tcl_Var* rPtr); The interp argument is the interpreter performing the resolution; name is the variable name being resolved; context is the namespace context containing the variable reference; and flags may contain TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, or TCL_LEAVE_ERR_MSG.

If this procedure recognizes the variable name, it should store the Tcl_Var token for that variable in the rPtr argument and return TCL_OK. If this procedure doesn't recognize the variable name, it should return TCL_CONTINUE, and the name resolution will continue with another procedure or with the default Tcl resolution scheme. If this procedure recognizes the variable name, but for some reason the variable is not accessible, the procedure should return TCL_ERROR. If the flags argument contains TCL_LEAVE_ERR_MSG, the procedure should leave an error message in the interpreter, explaining why the variable reference is invalid.

Note that this procedure should look for the TCL_GLOBAL_ONLY and TCL_NAMESPACE_ONLY flags. It should handle them appropriately, or return TCL_CONTINUE and let Tcl handle the reference. But it should not ignore the flags.

Tcl also resolves variables when a body of code is compiled; the compiledVarProc procedure handles that case. It must conform to the following type: typedef int Tcl_ResolveCompiledVarProc(Tcl_Interp* interp,
        char* name, int length, Tcl_Namespace* context,
        Tcl_ResolvedVarInfo* rPtr); The interp argument is the interpreter performing the resolution; name is the variable name being resolved; length is the number of bytes in name, which is not a null-terminated string; and context is the namespace context containing the variable reference.

If this procedure recognizes the variable name, it should return some information characterizing the variable in the rPtr structure. This structure is defined as follows: typedef struct Tcl_ResolvedVarInfo {
    ClientData identity;
    Tcl_ResolveRuntimeVarProc *fetchProc;
    Tcl_ResolveVarDeleteProc *deleteProc; } Tcl_ResolvedVarInfo; The identity field is an arbitrary value that characterizes the variable. Each variable should have a unique identity. Each time the compiled code is executed, Tcl will call the fetchProc procedure to get the actual variable for a particular identity value. This callback procedure must conform to the following type: typedef Tcl_Var Tcl_ResolveRuntimeVarProc(Tcl_Interp* interp,
    ClientData identity); The fetchProc procedure takes the interp interpreter and the identity from compile time and returns a Tcl_Var token representing the variable. If for some reason the variable can't be found, this procedure should return NULL, and Tcl will create a local variable within the call frame of the procedure being executed.

When the compiled code is discarded, Tcl calls the deleteProc procedure to release the identity data. The delete procedure must conform to the following type: typedef void Tcl_ResolveVarDeleteProc(ClientData identity);

In general, the varProc and compiledVarProc procedures should both be defined. If the compiledVarProc is not defined, then Tcl will create local variables for any variable names that are not recognized within a procedure. If the varProc is not defined, then Tcl will not recognize variables that are encountered at runtime. For example, consider the following procedure: proc foo {args} {
    set anotherRef "1"
    set name "another"
    set ${name}Ref "2" } Suppose that the compiledVarProc resolves the name anotherRef at compile time. The name ${name}Ref can't be resolved at compile time, so the resolution of that name is deferred to run time. If the varProc procedure must intercept the name anotherRef at run time and supply the appropriate variable.

KEYWORDS
interpreter, namespace, resolution