\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#79: Add Deletion Callback to Tcl\_CreateObjTrace}
\date{January 03, 2002}
\author{Kevin Kenny}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#79}&\textbf{Add Deletion Callback to Tcl\_CreateObjTrace}\\\hline
Author&

Kevin Kenny \tipmail{kennykb}{acm.org}
\\
Created&Thursday, \(\text{3}^{\text{rd}}\) January 2002\\
Type&Project\\
Tcl Version&\(8.4\)\\
State&Final\\
Vote&Done\\
Version&\tipversion$Revision: 1.7 $\\
Keywords&trace, Tcl\_Obj\\
Post History&\\
Discussions To&news:comp.lang.tcl\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This document is a correction to the \textit{Tcl\_CreateObjTrace} API from \cite{tip32}. It addresses a deficiency that the API provides no deletion callback for its client data.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

In developing a reference implementation for the changes described in \cite{tip32}, the author of this TIP discovered an anomaly in the proposed API for \textit{Tcl\_CreateObjTrace.} While the function accepts a \textit{ClientData} parameter, it provides no deletion callback for the client data, making it difficult to clean up the client data if \textit{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; \textit{Tcl\_CreateObjCommand} is an example.

\section{Specification}

The \textit{Tcl\_CreateObjTrace} function proposed in \cite{tip32} shall be changed to the following:
\begingroup\small\begin{verbatim}
 Tcl_Trace Tcl_CreateObjTrace ( Tcl_Interp*                interp,
                                int                        level, 
                                int                        flags,
                                Tcl_CmdObjTraceProc*       objProc,
                                ClientData                 clientData,
                                Tcl_CmdObjTraceDeleteProc* deleteProc );
\end{verbatim}
\endgroup

The \textit{Tcl\_CreateObjTrace} function adds a trace to the Tcl evaluator. The \textit{interp} argument is the Tcl interpreter for which tracing is being requested. The \textit{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 \textit{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 \textit{Tcl\_CmdObjTraceProc} below. The \textit{clientData} argument is client data to pass to the \textit{objProc} callback. The \textit{deleteProc} argument specifies a function to call when the trace is removed by a call to \textit{Tcl\_DeleteTrace.} This parameter may be a null pointer if no deletion callback is desired. Finally, the \textit{flags} argument gives flags that control the tracing. Initially, the only flag supported will be \textit{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 \textit{Tcl\_CreateObjTrace} may be passed as a parameter to \textit{Tcl\_DeleteTrace}, which arranges to cancel the tracing. If a non-empty \textit{deleteProc} argument was supplied to \textit{Tcl\_CreateObjTrace}, it is called at this time. After \textit{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 \textit{Tcl\_CmdObjTraceProc} will have the following type signature.
\begingroup\small\begin{verbatim}
    typedef int Tcl_CmdObjTraceProc( ClientData     clientData,
                                     Tcl_Interp*    interp,
                                     int            level,
                                     CONST char*    command,
                                     Tcl_Command    commandInfo,
                                     int            objc,
                                     Tcl_Obj *CONST objv[] );
\end{verbatim}
\endgroup

The \textit{clientData} parameter is the client data that was passed to \textit{Tcl\_CreateObjTrace}. The \textit{interp} parameter designates a Tcl interpreter. The \textit{level} parameter specifies the execution level. The \textit{command} parameter gives the raw UTF-8 text of the command being evaluated, before any substitutions have been performed. The \textit{commandInfo} parameter is an opaque \textit{Tcl\_Command} object that gives information about the command. The \textit{objc} and \textit{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 \textit{TCL\_OK}, the command is evaluated normally. If it returns \textit{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 \textit{TCL\_BREAK}, \textit{TCL\_CONTINUE} or \textit{TCL\_RETURN}, it is treated as if the command had done so.

The \textit{Tcl\_CmdObjTraceDeleteProc} will have the following type signature.
\begingroup\small\begin{verbatim}
    typedef void Tcl_CmdObjTraceDeleteProc( ClientData clientData );
\end{verbatim}
\endgroup

The \textit{clientData} parameter is the client data that was originally passed into \textit{Tcl\_CreateObjTrace}.

\section{Copyright}

Copyright (c) 2002 by Kevin B. Kenny. Distribution in whole or part, with or without annotations, is unlimited.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\begin{thebibliography}{TIP \#1}
\addcontentsline{toc}{section}{References}
\bibitem[TIP \#32]{tip32}
David Cuthbert,
Kevin Kenny,
\emph{Add Tcl\_Obj-enabled counterpart to Tcl\_CreateTrace},
on-line at \url{http://purl.org/tcl/tip/32.html}
\end{thebibliography}
\end{document}
