\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#227: Interface to Get and Set the Return Options of an Interpreter}
\date{October 30, 2004}
\author{Don Porter}
\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 \#227}&\textbf{Interface to Get and Set the Return Options of an Interpreter}\\\hline
Author&

Don Porter \tipmail{dgp}{users.sf.net}
\\
Created&Saturday, \(\text{30}^{\text{th}}\) October 2004\\
Type&Project\\
Tcl Version&\(8.5\)\\
State&Final\\
Vote&Done\\
Version&\tipversion$Revision: 1.5 $\\
Keywords&Tcl\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP proposes new public C routines to allow the same access to interpreter return options \cite{tip90} as are provided at the script level by the \textbf{catch} and \textbf{return} commands.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Background}

In Tcl 8.5, the \textbf{return} command has aready been extended to accept all option value pairs passed to it as arguments, to permit extensions to augment any custom return code values with whatever additional data values are appropriate. The \textbf{errorInfo} and \textbf{errorCode} values associated with the \textbf{TCL\_ERROR} return code are already converted to this mechanism.

The ability to set custom return options in the interp has been limited to the script level though. For extension commands implemented entirely in C, it is inconvenient and somewhat unreliable to perform a \textit{Tcl\_Eval(``return ...'')} to be able to access this capability.

Likewise, the \textbf{catch} command is able to capture the current set of return options in the interp, but doing so requires both a script level command, and use of a variable. Extension commands implemented in C are better served with a direct interface to fetch the dictionary value.

\section{Proposal}

Two new routines will be added to Tcl's public stub table:

\begin{quote}
int \textbf{Tcl\_SetReturnOptions}(Tcl\_Interp *\textit{interp}, Tcl\_Obj *\textit{options})
\end{quote}

\begin{quote}
Tcl\_Obj *\textbf{Tcl\_GetReturnOptions}(Tcl\_Interp *\textit{interp}, int \textit{result})
\end{quote}

These routines already exist in the HEAD of Tcl's development sources, but as private routines. The Tcl source code itself already makes calls to these routines where appropriate, and their functioning is tested by the test suite. This TIP merely proposes making these routines available as part of the public interface.

The \textit{Tcl\_SetReturnOptions} routine is essentially equivalent to the \textbf{return -options} command. The \textit{int} value returned is the return code that the \textbf{return} command would return given the same options. In fact, a valid implementation for the \textbf{return} command would be:
\begingroup\small\begin{verbatim}
 int Tcl_ReturnObjCmd(ClientData cd, Tcl_Interp *interp,
			int objc, Tcl_Obj *const objv[])
 {
     int explicitResult = (0 == (objc %2));
     int numOptions = objc - 1 - explicitResult;
     if (explicitResult) Tcl_SetObjResult(interp, objv[objc-1]);
     return Tcl_SetReturnOptions(interp, Tcl_NewListObj(numOptions, objv+1));
 }
\end{verbatim}
\endgroup

Note that \textit{Tcl\_SetReturnOptions} is like \textit{Tcl\_SetObjResult} and \textit{Tcl\_SetVar2Ex} in that you can pass it a newly created Tcl\_Obj confident that it will be freed later. No refCount manipulation is required.

The \textit{Tcl\_GetReturnOptions} routine is used by \textbf{catch} to fetch the value to be stored in the \textit{optionsVarName} variable, if any. The \textit{result} argument should be whatever return code was returned by the script evaluation, or other \textit{interp} activity whose return options you wish to retrieve.

The \textit{(Tcl\_Obj *)} returned by \textit{Tcl\_GetReturnOptions} points to a newly created, unshared \textbf{Tcl\_Obj}. It can be written to as returned; no need to implement copy-on-write checks. In particular, new key value pairs can be added to the dictionary, or existing ones changed or removed. As noted above, such a value is also suitable for passing right back to \textit{Tcl\_SetReturnOptions}.

\section{Compatibility}

Some extensions provide commands that offer the ability to evaluate a Tcl script in some other context, and return the complete result of that evaluation. For example, the \textbf{Thread} package provides the \textbf{thread::send} command that evaluates a script in another interp in a different thread. The \textbf{thread::send} command ultimately has a return code and a result that matches those produced by the script evaluation in the other thread. Furthermore, the \textbf{::errorInfo} and \textbf{::errorCode} variables are set according to the script evaluation outcome in the other thread as well. Extensions that accomplish such passing of full evaluation results achieve it now with copies of all portions of the full evaluation results: the return code, the interp result, and when appropriate, the values of \textbf{::errorInfo} and \textbf{::errorCode}. 

Such mechanisms will continue to work unchanged in Tcl 8.5. However, they will no longer represent the \textit{complete} evaluation results of the script. In order to continue to communicate back the full outcome of script evaluation, these extensions will want to call \textit{Tcl\_GetReturnOptions} after the script completes, transport that value back, and call \textit{Tcl\_SetReturnOptions} in the original interp. Note that use of these routines will automatically take care of \textbf{::errorInfo} and \textbf{::errorCode}, so the complete outcome of script evaluation will be able to be communicated by the return code, the interp result, and the dictionary of return options. Because the return options dictionary is itself extensible, this interface will not need to change again.

\section{Reference Implementation}

See Tcl Patch 1060579.

\section{Comments}

Please make any comments here.

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\begin{thebibliography}{TIP \#1}
\addcontentsline{toc}{section}{References}
\bibitem[TIP \#90]{tip90}
Don Porter,
Donal K. Fellows,
\emph{Enable [return -code] in Control Structure Procs},
on-line at \url{http://purl.org/tcl/tip/90.html}
\end{thebibliography}
\end{document}
