Author: Kevin Kenny <kennykb@acm.org>
State: Final
Type: Project
Vote: Done
Created: 03-Jan-2002
Post-History:
Discussions-To: news:comp.lang.tcl
Keywords: trace,Tcl_Obj
Tcl-Version: 8.4
Abstract
This document is a correction to the Tcl_CreateObjTrace API from [32]. It addresses a deficiency that the API provides no deletion callback for its client data.
Rationale
In developing a reference implementation for the changes described in [32], the author of this TIP discovered an anomaly in the proposed API for Tcl_CreateObjTrace. While the function accepts a ClientData parameter, it provides no deletion callback for the client data, making it difficult to clean up the client data if Tcl_DeleteTrace is called from a point in the code where the client data is not readily available. (The usual pattern in the Tcl library is to provide a deletion callback wherever client data is passed to the Tcl interpreter; Tcl_CreateObjCommand is an example.
Specification
The Tcl_CreateObjTrace function proposed in [32] shall be changed to the following:
Tcl_Trace Tcl_CreateObjTrace ( Tcl_Interp* interp,
int level,
int flags,
Tcl_CmdObjTraceProc* objProc,
ClientData clientData,
Tcl_CmdObjTraceDeleteProc* deleteProc );
The Tcl_CreateObjTrace function adds a trace to the Tcl evaluator. The interp argument is the Tcl interpreter for which tracing is being requested. The level argument is the maximum depth of recursive calls; when the execution depth of the interpreter exceeds this number, the trace callback does not execute. The objProc argument is the callback procedure to execute each time a Tcl command is evaluated; it is expected to have arguments and result type that match Tcl_CmdObjTraceProc below. The clientData argument is client data to pass to the objProc callback. The deleteProc argument specifies a function to call when the trace is removed by a call to Tcl_DeleteTrace. This parameter may be a null pointer if no deletion callback is desired. Finally, the flags argument gives flags that control the tracing. Initially, the only flag supported will be TCL_ALLOW_INLINE_COMPILE. If this flag is set, the bytecode compiler is permitted to compile in-line code for the Tcl built-in commands; any command that has been compiled in-line will not be traced.
The trace token returned from Tcl_CreateObjTrace may be passed as a parameter to Tcl_DeleteTrace, which arranges to cancel the tracing. If a non-empty deleteProc argument was supplied to Tcl_CreateObjTrace, it is called at this time. After Tcl_DeleteTrace returns, no further calls to the trace procedure will be made, and the trace token must not be used further in the calling program.
The Tcl_CmdObjTraceProc will have the following type signature.
typedef int Tcl_CmdObjTraceProc( ClientData clientData,
Tcl_Interp* interp,
int level,
CONST char* command,
Tcl_Command commandInfo,
int objc,
Tcl_Obj *CONST objv[] );
The clientData parameter is the client data that was passed to Tcl_CreateObjTrace. The interp parameter designates a Tcl interpreter. The level parameter specifies the execution level. The command parameter gives the raw UTF-8 text of the command being evaluated, before any substitutions have been performed. The commandInfo parameter is an opaque Tcl_Command object that gives information about the command. The objc and objv parameters are the command name and parameter vector after substitution.
The trace procedure is expected to return a standard Tcl status return. If it returns TCL_OK, the command is evaluated normally. If it returns TCL_ERROR, evaluation of the command does not take place. The interpreter result is expected to contain an error message. If it returns any other status, such as TCL_BREAK, TCL_CONTINUE or TCL_RETURN, it is treated as if the command had done so.
The Tcl_CmdObjTraceDeleteProc will have the following type signature.
typedef void Tcl_CmdObjTraceDeleteProc( ClientData clientData );
The clientData parameter is the client data that was originally passed into Tcl_CreateObjTrace.
Copyright
Copyright © 2002 by Kevin B. Kenny. Distribution in whole or part, with or without annotations, is unlimited.