os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclResult.c
First public contribution.
4 * This file contains code to manage the interpreter result.
6 * Copyright (c) 1997 by Sun Microsystems, Inc.
7 * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.
9 * See the file "license.terms" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 * RCS: @(#) $Id: tclResult.c,v 1.5.2.2 2004/09/30 22:45:15 dgp Exp $
18 * Function prototypes for local procedures in this file:
21 static void ResetObjResult _ANSI_ARGS_((Interp *iPtr));
22 static void SetupAppendBuffer _ANSI_ARGS_((Interp *iPtr,
27 *----------------------------------------------------------------------
31 * Takes a snapshot of the current result state of the interpreter.
32 * The snapshot can be restored at any point by
33 * Tcl_RestoreResult. Note that this routine does not
34 * preserve the errorCode, errorInfo, or flags fields so it
35 * should not be used if an error is in progress.
37 * Once a snapshot is saved, it must be restored by calling
38 * Tcl_RestoreResult, or discarded by calling
45 * Resets the interpreter result.
47 *----------------------------------------------------------------------
51 Tcl_SaveResult(interp, statePtr)
52 Tcl_Interp *interp; /* Interpreter to save. */
53 Tcl_SavedResult *statePtr; /* Pointer to state structure. */
55 Interp *iPtr = (Interp *) interp;
58 * Move the result object into the save state. Note that we don't need
59 * to change its refcount because we're moving it, not adding a new
60 * reference. Put an empty object into the interpreter.
63 statePtr->objResultPtr = iPtr->objResultPtr;
64 iPtr->objResultPtr = Tcl_NewObj();
65 Tcl_IncrRefCount(iPtr->objResultPtr);
68 * Save the string result.
71 statePtr->freeProc = iPtr->freeProc;
72 if (iPtr->result == iPtr->resultSpace) {
74 * Copy the static string data out of the interp buffer.
77 statePtr->result = statePtr->resultSpace;
78 strcpy(statePtr->result, iPtr->result);
79 statePtr->appendResult = NULL;
80 } else if (iPtr->result == iPtr->appendResult) {
82 * Move the append buffer out of the interp.
85 statePtr->appendResult = iPtr->appendResult;
86 statePtr->appendAvl = iPtr->appendAvl;
87 statePtr->appendUsed = iPtr->appendUsed;
88 statePtr->result = statePtr->appendResult;
89 iPtr->appendResult = NULL;
94 * Move the dynamic or static string out of the interpreter.
97 statePtr->result = iPtr->result;
98 statePtr->appendResult = NULL;
101 iPtr->result = iPtr->resultSpace;
102 iPtr->resultSpace[0] = 0;
107 *----------------------------------------------------------------------
109 * Tcl_RestoreResult --
111 * Restores the state of the interpreter to a snapshot taken
112 * by Tcl_SaveResult. After this call, the token for
113 * the interpreter state is no longer valid.
119 * Restores the interpreter result.
121 *----------------------------------------------------------------------
125 Tcl_RestoreResult(interp, statePtr)
126 Tcl_Interp* interp; /* Interpreter being restored. */
127 Tcl_SavedResult *statePtr; /* State returned by Tcl_SaveResult. */
129 Interp *iPtr = (Interp *) interp;
131 Tcl_ResetResult(interp);
134 * Restore the string result.
137 iPtr->freeProc = statePtr->freeProc;
138 if (statePtr->result == statePtr->resultSpace) {
140 * Copy the static string data into the interp buffer.
143 iPtr->result = iPtr->resultSpace;
144 strcpy(iPtr->result, statePtr->result);
145 } else if (statePtr->result == statePtr->appendResult) {
147 * Move the append buffer back into the interp.
150 if (iPtr->appendResult != NULL) {
151 ckfree((char *)iPtr->appendResult);
154 iPtr->appendResult = statePtr->appendResult;
155 iPtr->appendAvl = statePtr->appendAvl;
156 iPtr->appendUsed = statePtr->appendUsed;
157 iPtr->result = iPtr->appendResult;
160 * Move the dynamic or static string back into the interpreter.
163 iPtr->result = statePtr->result;
167 * Restore the object result.
170 Tcl_DecrRefCount(iPtr->objResultPtr);
171 iPtr->objResultPtr = statePtr->objResultPtr;
175 *----------------------------------------------------------------------
177 * Tcl_DiscardResult --
179 * Frees the memory associated with an interpreter snapshot
180 * taken by Tcl_SaveResult. If the snapshot is not
181 * restored, this procedure must be called to discard it,
182 * or the memory will be lost.
190 *----------------------------------------------------------------------
194 Tcl_DiscardResult(statePtr)
195 Tcl_SavedResult *statePtr; /* State returned by Tcl_SaveResult. */
197 TclDecrRefCount(statePtr->objResultPtr);
199 if (statePtr->result == statePtr->appendResult) {
200 ckfree(statePtr->appendResult);
201 } else if (statePtr->freeProc) {
202 if (statePtr->freeProc == TCL_DYNAMIC) {
203 ckfree(statePtr->result);
205 (*statePtr->freeProc)(statePtr->result);
211 *----------------------------------------------------------------------
215 * Arrange for "string" to be the Tcl return value.
221 * interp->result is left pointing either to "string" (if "copy" is 0)
222 * or to a copy of string. Also, the object result is reset.
224 *----------------------------------------------------------------------
228 Tcl_SetResult(interp, string, freeProc)
229 Tcl_Interp *interp; /* Interpreter with which to associate the
231 register char *string; /* Value to be returned. If NULL, the
232 * result is set to an empty string. */
233 Tcl_FreeProc *freeProc; /* Gives information about the string:
234 * TCL_STATIC, TCL_VOLATILE, or the address
235 * of a Tcl_FreeProc such as free. */
237 Interp *iPtr = (Interp *) interp;
239 register Tcl_FreeProc *oldFreeProc = iPtr->freeProc;
240 char *oldResult = iPtr->result;
242 if (string == NULL) {
243 iPtr->resultSpace[0] = 0;
244 iPtr->result = iPtr->resultSpace;
246 } else if (freeProc == TCL_VOLATILE) {
247 length = strlen(string);
248 if (length > TCL_RESULT_SIZE) {
249 iPtr->result = (char *) ckalloc((unsigned) length+1);
250 iPtr->freeProc = TCL_DYNAMIC;
252 iPtr->result = iPtr->resultSpace;
255 strcpy(iPtr->result, string);
257 iPtr->result = string;
258 iPtr->freeProc = freeProc;
262 * If the old result was dynamically-allocated, free it up. Do it
263 * here, rather than at the beginning, in case the new result value
264 * was part of the old result value.
267 if (oldFreeProc != 0) {
268 if (oldFreeProc == TCL_DYNAMIC) {
271 (*oldFreeProc)(oldResult);
276 * Reset the object result since we just set the string result.
279 ResetObjResult(iPtr);
283 *----------------------------------------------------------------------
285 * Tcl_GetStringResult --
287 * Returns an interpreter's result value as a string.
290 * The interpreter's result as a string.
293 * If the string result is empty, the object result is moved to the
294 * string result, then the object result is reset.
296 *----------------------------------------------------------------------
299 EXPORT_C CONST char *
300 Tcl_GetStringResult(interp)
301 register Tcl_Interp *interp; /* Interpreter whose result to return. */
304 * If the string result is empty, move the object result to the
305 * string result, then reset the object result.
308 if (*(interp->result) == 0) {
309 Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
312 return interp->result;
316 *----------------------------------------------------------------------
318 * Tcl_SetObjResult --
320 * Arrange for objPtr to be an interpreter's result value.
326 * interp->objResultPtr is left pointing to the object referenced
327 * by objPtr. The object's reference count is incremented since
328 * there is now a new reference to it. The reference count for any
329 * old objResultPtr value is decremented. Also, the string result
332 *----------------------------------------------------------------------
336 Tcl_SetObjResult(interp, objPtr)
337 Tcl_Interp *interp; /* Interpreter with which to associate the
338 * return object value. */
339 register Tcl_Obj *objPtr; /* Tcl object to be returned. If NULL, the
340 * obj result is made an empty string
343 register Interp *iPtr = (Interp *) interp;
344 register Tcl_Obj *oldObjResult = iPtr->objResultPtr;
346 iPtr->objResultPtr = objPtr;
347 Tcl_IncrRefCount(objPtr); /* since interp result is a reference */
350 * We wait until the end to release the old object result, in case
351 * we are setting the result to itself.
354 TclDecrRefCount(oldObjResult);
357 * Reset the string result since we just set the result object.
360 if (iPtr->freeProc != NULL) {
361 if (iPtr->freeProc == TCL_DYNAMIC) {
362 ckfree(iPtr->result);
364 (*iPtr->freeProc)(iPtr->result);
368 iPtr->result = iPtr->resultSpace;
369 iPtr->resultSpace[0] = 0;
373 *----------------------------------------------------------------------
375 * Tcl_GetObjResult --
377 * Returns an interpreter's result value as a Tcl object. The object's
378 * reference count is not modified; the caller must do that if it
379 * needs to hold on to a long-term reference to it.
382 * The interpreter's result as an object.
385 * If the interpreter has a non-empty string result, the result object
386 * is either empty or stale because some procedure set interp->result
387 * directly. If so, the string result is moved to the result object
388 * then the string result is reset.
390 *----------------------------------------------------------------------
394 Tcl_GetObjResult(interp)
395 Tcl_Interp *interp; /* Interpreter whose result to return. */
397 register Interp *iPtr = (Interp *) interp;
398 Tcl_Obj *objResultPtr;
402 * If the string result is non-empty, move the string result to the
403 * object result, then reset the string result.
406 if (*(iPtr->result) != 0) {
407 ResetObjResult(iPtr);
409 objResultPtr = iPtr->objResultPtr;
410 length = strlen(iPtr->result);
411 TclInitStringRep(objResultPtr, iPtr->result, length);
413 if (iPtr->freeProc != NULL) {
414 if (iPtr->freeProc == TCL_DYNAMIC) {
415 ckfree(iPtr->result);
417 (*iPtr->freeProc)(iPtr->result);
421 iPtr->result = iPtr->resultSpace;
422 iPtr->resultSpace[0] = 0;
424 return iPtr->objResultPtr;
428 *----------------------------------------------------------------------
430 * Tcl_AppendResultVA --
432 * Append a variable number of strings onto the interpreter's string
439 * The result of the interpreter given by the first argument is
440 * extended by the strings in the va_list (up to a terminating NULL
443 * If the string result is empty, the object result is moved to the
444 * string result, then the object result is reset.
446 *----------------------------------------------------------------------
450 Tcl_AppendResultVA (interp, argList)
451 Tcl_Interp *interp; /* Interpreter with which to associate the
453 va_list argList; /* Variable argument list. */
455 #define STATIC_LIST_SIZE 16
456 Interp *iPtr = (Interp *) interp;
457 char *string, *static_list[STATIC_LIST_SIZE];
458 char **args = static_list;
459 int nargs_space = STATIC_LIST_SIZE;
460 int nargs, newSpace, i;
463 * If the string result is empty, move the object result to the
464 * string result, then reset the object result.
467 if (*(iPtr->result) == 0) {
468 Tcl_SetResult((Tcl_Interp *) iPtr,
469 TclGetString(Tcl_GetObjResult((Tcl_Interp *) iPtr)),
474 * Scan through all the arguments to see how much space is needed
475 * and save pointers to the arguments in the args array,
476 * reallocating as necessary.
482 string = va_arg(argList, char *);
483 if (string == NULL) {
486 if (nargs >= nargs_space) {
488 * Expand the args buffer
490 nargs_space += STATIC_LIST_SIZE;
491 if (args == static_list) {
492 args = (void *)ckalloc(nargs_space * sizeof(char *));
493 for (i = 0; i < nargs; ++i) {
494 args[i] = static_list[i];
497 args = (void *)ckrealloc((void *)args,
498 nargs_space * sizeof(char *));
501 newSpace += strlen(string);
502 args[nargs++] = string;
506 * If the append buffer isn't already setup and large enough to hold
507 * the new data, set it up.
510 if ((iPtr->result != iPtr->appendResult)
511 || (iPtr->appendResult[iPtr->appendUsed] != 0)
512 || ((newSpace + iPtr->appendUsed) >= iPtr->appendAvl)) {
513 SetupAppendBuffer(iPtr, newSpace);
517 * Now go through all the argument strings again, copying them into the
521 for (i = 0; i < nargs; ++i) {
523 strcpy(iPtr->appendResult + iPtr->appendUsed, string);
524 iPtr->appendUsed += strlen(string);
528 * If we had to allocate a buffer from the heap,
532 if (args != static_list) {
533 ckfree((void *)args);
535 #undef STATIC_LIST_SIZE
539 *----------------------------------------------------------------------
541 * Tcl_AppendResult --
543 * Append a variable number of strings onto the interpreter's string
550 * The result of the interpreter given by the first argument is
551 * extended by the strings given by the second and following arguments
552 * (up to a terminating NULL argument).
554 * If the string result is empty, the object result is moved to the
555 * string result, then the object result is reset.
557 *----------------------------------------------------------------------
561 Tcl_AppendResult TCL_VARARGS_DEF(Tcl_Interp *,arg1)
566 interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
567 Tcl_AppendResultVA(interp, argList);
572 *----------------------------------------------------------------------
574 * Tcl_AppendElement --
576 * Convert a string to a valid Tcl list element and append it to the
577 * result (which is ostensibly a list).
583 * The result in the interpreter given by the first argument is
584 * extended with a list element converted from string. A separator
585 * space is added before the converted list element unless the current
586 * result is empty, contains the single character "{", or ends in " {".
588 * If the string result is empty, the object result is moved to the
589 * string result, then the object result is reset.
591 *----------------------------------------------------------------------
595 Tcl_AppendElement(interp, string)
596 Tcl_Interp *interp; /* Interpreter whose result is to be
598 CONST char *string; /* String to convert to list element and
601 Interp *iPtr = (Interp *) interp;
607 * If the string result is empty, move the object result to the
608 * string result, then reset the object result.
611 if (*(iPtr->result) == 0) {
612 Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
617 * See how much space is needed, and grow the append buffer if
618 * needed to accommodate the list element.
621 size = Tcl_ScanElement(string, &flags) + 1;
622 if ((iPtr->result != iPtr->appendResult)
623 || (iPtr->appendResult[iPtr->appendUsed] != 0)
624 || ((size + iPtr->appendUsed) >= iPtr->appendAvl)) {
625 SetupAppendBuffer(iPtr, size+iPtr->appendUsed);
629 * Convert the string into a list element and copy it to the
630 * buffer that's forming, with a space separator if needed.
633 dst = iPtr->appendResult + iPtr->appendUsed;
634 if (TclNeedSpace(iPtr->appendResult, dst)) {
639 iPtr->appendUsed += Tcl_ConvertElement(string, dst, flags);
643 *----------------------------------------------------------------------
645 * SetupAppendBuffer --
647 * This procedure makes sure that there is an append buffer properly
648 * initialized, if necessary, from the interpreter's result, and
649 * that it has at least enough room to accommodate newSpace new
650 * bytes of information.
658 *----------------------------------------------------------------------
662 SetupAppendBuffer(iPtr, newSpace)
663 Interp *iPtr; /* Interpreter whose result is being set up. */
664 int newSpace; /* Make sure that at least this many bytes
665 * of new information may be added. */
670 * Make the append buffer larger, if that's necessary, then copy the
671 * result into the append buffer and make the append buffer the official
675 if (iPtr->result != iPtr->appendResult) {
677 * If an oversized buffer was used recently, then free it up
678 * so we go back to a smaller buffer. This avoids tying up
679 * memory forever after a large operation.
682 if (iPtr->appendAvl > 500) {
683 ckfree(iPtr->appendResult);
684 iPtr->appendResult = NULL;
687 iPtr->appendUsed = strlen(iPtr->result);
688 } else if (iPtr->result[iPtr->appendUsed] != 0) {
690 * Most likely someone has modified a result created by
691 * Tcl_AppendResult et al. so that it has a different size.
692 * Just recompute the size.
695 iPtr->appendUsed = strlen(iPtr->result);
698 totalSpace = newSpace + iPtr->appendUsed;
699 if (totalSpace >= iPtr->appendAvl) {
702 if (totalSpace < 100) {
707 new = (char *) ckalloc((unsigned) totalSpace);
708 strcpy(new, iPtr->result);
709 if (iPtr->appendResult != NULL) {
710 ckfree(iPtr->appendResult);
712 iPtr->appendResult = new;
713 iPtr->appendAvl = totalSpace;
714 } else if (iPtr->result != iPtr->appendResult) {
715 strcpy(iPtr->appendResult, iPtr->result);
718 Tcl_FreeResult((Tcl_Interp *) iPtr);
719 iPtr->result = iPtr->appendResult;
723 *----------------------------------------------------------------------
727 * This procedure frees up the memory associated with an interpreter's
728 * string result. It also resets the interpreter's result object.
729 * Tcl_FreeResult is most commonly used when a procedure is about to
730 * replace one result value with another.
736 * Frees the memory associated with interp's string result and sets
737 * interp->freeProc to zero, but does not change interp->result or
738 * clear error state. Resets interp's result object to an unshared
741 *----------------------------------------------------------------------
745 Tcl_FreeResult(interp)
746 register Tcl_Interp *interp; /* Interpreter for which to free result. */
748 register Interp *iPtr = (Interp *) interp;
750 if (iPtr->freeProc != NULL) {
751 if (iPtr->freeProc == TCL_DYNAMIC) {
752 ckfree(iPtr->result);
754 (*iPtr->freeProc)(iPtr->result);
759 ResetObjResult(iPtr);
763 *----------------------------------------------------------------------
767 * This procedure resets both the interpreter's string and object
774 * It resets the result object to an unshared empty object. It
775 * then restores the interpreter's string result area to its default
776 * initialized state, freeing up any memory that may have been
777 * allocated. It also clears any error information for the interpreter.
779 *----------------------------------------------------------------------
783 Tcl_ResetResult(interp)
784 register Tcl_Interp *interp; /* Interpreter for which to clear result. */
786 register Interp *iPtr = (Interp *) interp;
788 ResetObjResult(iPtr);
789 if (iPtr->freeProc != NULL) {
790 if (iPtr->freeProc == TCL_DYNAMIC) {
791 ckfree(iPtr->result);
793 (*iPtr->freeProc)(iPtr->result);
797 iPtr->result = iPtr->resultSpace;
798 iPtr->resultSpace[0] = 0;
799 iPtr->flags &= ~(ERR_ALREADY_LOGGED | ERR_IN_PROGRESS | ERROR_CODE_SET);
803 *----------------------------------------------------------------------
807 * Procedure used to reset an interpreter's Tcl result object.
813 * Resets the interpreter's result object to an unshared empty string
814 * object with ref count one. It does not clear any error information
815 * in the interpreter.
817 *----------------------------------------------------------------------
822 register Interp *iPtr; /* Points to the interpreter whose result
823 * object should be reset. */
825 register Tcl_Obj *objResultPtr = iPtr->objResultPtr;
827 if (Tcl_IsShared(objResultPtr)) {
828 TclDecrRefCount(objResultPtr);
829 TclNewObj(objResultPtr);
830 Tcl_IncrRefCount(objResultPtr);
831 iPtr->objResultPtr = objResultPtr;
833 if ((objResultPtr->bytes != NULL)
834 && (objResultPtr->bytes != tclEmptyStringRep)) {
835 ckfree((char *) objResultPtr->bytes);
837 objResultPtr->bytes = tclEmptyStringRep;
838 objResultPtr->length = 0;
839 if ((objResultPtr->typePtr != NULL)
840 && (objResultPtr->typePtr->freeIntRepProc != NULL)) {
841 objResultPtr->typePtr->freeIntRepProc(objResultPtr);
843 objResultPtr->typePtr = (Tcl_ObjType *) NULL;
848 *----------------------------------------------------------------------
850 * Tcl_SetErrorCodeVA --
852 * This procedure is called to record machine-readable information
853 * about an error that is about to be returned.
859 * The errorCode global variable is modified to hold all of the
860 * arguments to this procedure, in a list form with each argument
861 * becoming one element of the list. A flag is set internally
862 * to remember that errorCode has been set, so the variable doesn't
863 * get set automatically when the error is returned.
865 *----------------------------------------------------------------------
869 Tcl_SetErrorCodeVA (interp, argList)
870 Tcl_Interp *interp; /* Interpreter in which to access the errorCode
872 va_list argList; /* Variable argument list. */
876 Interp *iPtr = (Interp *) interp;
879 * Scan through the arguments one at a time, appending them to
880 * $errorCode as list elements.
883 flags = TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT;
885 string = va_arg(argList, char *);
886 if (string == NULL) {
889 (void) Tcl_SetVar2((Tcl_Interp *) iPtr, "errorCode",
890 (char *) NULL, string, flags);
891 flags |= TCL_APPEND_VALUE;
893 iPtr->flags |= ERROR_CODE_SET;
897 *----------------------------------------------------------------------
899 * Tcl_SetErrorCode --
901 * This procedure is called to record machine-readable information
902 * about an error that is about to be returned.
908 * The errorCode global variable is modified to hold all of the
909 * arguments to this procedure, in a list form with each argument
910 * becoming one element of the list. A flag is set internally
911 * to remember that errorCode has been set, so the variable doesn't
912 * get set automatically when the error is returned.
914 *----------------------------------------------------------------------
918 Tcl_SetErrorCode TCL_VARARGS_DEF(Tcl_Interp *,arg1)
924 * Scan through the arguments one at a time, appending them to
925 * $errorCode as list elements.
928 interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
929 Tcl_SetErrorCodeVA(interp, argList);
934 *----------------------------------------------------------------------
936 * Tcl_SetObjErrorCode --
938 * This procedure is called to record machine-readable information
939 * about an error that is about to be returned. The caller should
940 * build a list object up and pass it to this routine.
946 * The errorCode global variable is modified to be the new value.
947 * A flag is set internally to remember that errorCode has been
948 * set, so the variable doesn't get set automatically when the
951 *----------------------------------------------------------------------
955 Tcl_SetObjErrorCode(interp, errorObjPtr)
957 Tcl_Obj *errorObjPtr;
961 iPtr = (Interp *) interp;
962 Tcl_SetVar2Ex(interp, "errorCode", NULL, errorObjPtr, TCL_GLOBAL_ONLY);
963 iPtr->flags |= ERROR_CODE_SET;
967 *-------------------------------------------------------------------------
969 * TclTransferResult --
971 * Copy the result (and error information) from one interp to
972 * another. Used when one interp has caused another interp to
973 * evaluate a script and then wants to transfer the results back
976 * This routine copies the string reps of the result and error
977 * information. It does not simply increment the refcounts of the
978 * result and error information objects themselves.
979 * It is not legal to exchange objects between interps, because an
980 * object may be kept alive by one interp, but have an internal rep
981 * that is only valid while some other interp is alive.
984 * The target interp's result is set to a copy of the source interp's
985 * result. The source's error information "$errorInfo" may be
986 * appended to the target's error information and the source's error
987 * code "$errorCode" may be stored in the target's error code.
992 *-------------------------------------------------------------------------
996 TclTransferResult(sourceInterp, result, targetInterp)
997 Tcl_Interp *sourceInterp; /* Interp whose result and error information
998 * should be moved to the target interp.
999 * After moving result, this interp's result
1001 int result; /* TCL_OK if just the result should be copied,
1002 * TCL_ERROR if both the result and error
1003 * information should be copied. */
1004 Tcl_Interp *targetInterp; /* Interp where result and error information
1005 * should be stored. If source and target
1006 * are the same, nothing is done. */
1011 if (sourceInterp == targetInterp) {
1015 if (result == TCL_ERROR) {
1017 * An error occurred, so transfer error information from the source
1018 * interpreter to the target interpreter. Setting the flags tells
1019 * the target interp that it has inherited a partial traceback
1020 * chain, not just a simple error message.
1023 iPtr = (Interp *) sourceInterp;
1024 if ((iPtr->flags & ERR_ALREADY_LOGGED) == 0) {
1025 Tcl_AddErrorInfo(sourceInterp, "");
1027 iPtr->flags &= ~(ERR_ALREADY_LOGGED);
1029 Tcl_ResetResult(targetInterp);
1031 objPtr = Tcl_GetVar2Ex(sourceInterp, "errorInfo", NULL,
1034 Tcl_SetVar2Ex(targetInterp, "errorInfo", NULL, objPtr,
1036 ((Interp *) targetInterp)->flags |= ERR_IN_PROGRESS;
1039 objPtr = Tcl_GetVar2Ex(sourceInterp, "errorCode", NULL,
1042 Tcl_SetObjErrorCode(targetInterp, objPtr);
1047 ((Interp *) targetInterp)->returnCode = ((Interp *) sourceInterp)->returnCode;
1048 Tcl_SetObjResult(targetInterp, Tcl_GetObjResult(sourceInterp));
1049 Tcl_ResetResult(sourceInterp);