1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
/*
* tclResult.c --
*
* This file contains code to manage the interpreter result.
*
* Copyright (c) 1997 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclResult.c,v 1.16 2004/10/17 14:22:08 msofer Exp $
*/
#include "tclInt.h"
/*
* Function prototypes for local procedures in this file:
*/
static void ResetObjResult _ANSI_ARGS_((Interp *iPtr));
static void SetupAppendBuffer _ANSI_ARGS_((Interp *iPtr,
int newSpace));
/*
*----------------------------------------------------------------------
*
* Tcl_SaveResult --
*
* Takes a snapshot of the current result state of the interpreter.
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
/*
* tclResult.c --
*
* This file contains code to manage the interpreter result.
*
* Copyright (c) 1997 by Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclResult.c,v 1.17 2004/10/19 21:54:07 dgp Exp $
*/
#include "tclInt.h"
/*
* Function prototypes for local procedures in this file:
*/
static void ResetObjResult _ANSI_ARGS_((Interp *iPtr));
static void SetupAppendBuffer _ANSI_ARGS_((Interp *iPtr,
int newSpace));
/*
* This structure is used to take a snapshot of the interpreter
* state in TclSaveInterpState. You can snapshot the state,
* execute a command, and then back up to the result or the
* error that was previously in progress.
*/
typedef struct InterpState {
int status; /* return code status */
int flags; /* Each remaining field saves */
int returnLevel; /* the corresponding field of */
int returnCode; /* the Interp struct. These */
Tcl_Obj *errorInfo; /* fields take together are the */
Tcl_Obj *errorCode; /* "state" of the interp. */
Tcl_Obj *returnOpts;
Tcl_Obj *objResult;
} InterpState;
/*
*----------------------------------------------------------------------
*
* TclSaveInterpState --
*
* Fills a token with a snapshot of the current state of the
* interpreter. The snapshot can be restored at any point by
* TclRestoreInterpState.
*
* The token returned must be eventally passed to one of the
* routines TclRestoreInterpState or TclDiscardInterpState,
* or there will be a memory leak.
*
* Results:
* Returns a token representing the interp state.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
TclInterpState
TclSaveInterpState(interp, status)
Tcl_Interp* interp; /* Interpreter's state to be saved */
int status; /* status code for current operation */
{
Interp *iPtr = (Interp *)interp;
InterpState *statePtr = (InterpState *)ckalloc(sizeof(InterpState));
statePtr->status = status;
statePtr->flags = iPtr->flags & ERR_ALREADY_LOGGED;
statePtr->returnLevel = iPtr->returnLevel;
statePtr->returnCode = iPtr->returnCode;
statePtr->errorInfo = iPtr->errorInfo;
if (statePtr->errorInfo) {
Tcl_IncrRefCount(statePtr->errorInfo);
}
statePtr->errorCode = iPtr->errorCode;
if (statePtr->errorCode) {
Tcl_IncrRefCount(statePtr->errorCode);
}
statePtr->returnOpts = iPtr->returnOpts;
if (statePtr->returnOpts) {
Tcl_IncrRefCount(statePtr->returnOpts);
}
statePtr->objResult = Tcl_GetObjResult(interp);
Tcl_IncrRefCount(statePtr->objResult);
return (TclInterpState) statePtr;
}
/*
*----------------------------------------------------------------------
*
* TclRestoreInterpState --
*
* Accepts an interp and a token previously returned by
* TclSaveInterpState. Restore the state of the interp
* to what it was at the time of the TclSaveInterpState call.
*
* Results:
* Returns the status value originally passed in to TclSaveInterpState.
*
* Side effects:
* Restores the interp state and frees memory held by token.
*
*----------------------------------------------------------------------
*/
int
TclRestoreInterpState(interp, state)
Tcl_Interp* interp; /* Interpreter's state to be restored*/
TclInterpState state; /* saved interpreter state */
{
Interp *iPtr = (Interp *)interp;
InterpState *statePtr = (InterpState *)state;
int status = statePtr->status;
iPtr->flags &= ~ERR_ALREADY_LOGGED;
iPtr->flags |= (statePtr->flags & ERR_ALREADY_LOGGED);
iPtr->returnLevel = statePtr->returnLevel;
iPtr->returnCode = statePtr->returnCode;
iPtr->errorInfo = statePtr->errorInfo;
if (iPtr->errorInfo) {
Tcl_IncrRefCount(iPtr->errorInfo);
}
iPtr->errorCode = statePtr->errorCode;
if (iPtr->errorCode) {
Tcl_IncrRefCount(iPtr->errorCode);
}
iPtr->returnOpts = statePtr->returnOpts;
if (iPtr->returnOpts) {
Tcl_IncrRefCount(iPtr->returnOpts);
}
Tcl_SetObjResult(interp, statePtr->objResult);
TclDiscardInterpState(state);
return status;
}
/*
*----------------------------------------------------------------------
*
* TclDiscardInterpState --
*
* Accepts a token previously returned by TclSaveInterpState.
* Frees the memory it uses.
*
* Results:
* None.
*
* Side effects:
* Frees memory.
*
*----------------------------------------------------------------------
*/
void
TclDiscardInterpState(state)
TclInterpState state; /* saved interpreter state */
{
InterpState *statePtr = (InterpState *)state;
if (statePtr->errorInfo) {
Tcl_DecrRefCount(statePtr->errorInfo);
}
if (statePtr->errorCode) {
Tcl_DecrRefCount(statePtr->errorCode);
}
if (statePtr->returnOpts) {
Tcl_DecrRefCount(statePtr->returnOpts);
}
Tcl_DecrRefCount(statePtr->objResult);
ckfree((char*) statePtr);
}
/*
*----------------------------------------------------------------------
*
* Tcl_SaveResult --
*
* Takes a snapshot of the current result state of the interpreter.
|
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
|
/* Legacy support */
Tcl_ObjSetVar2(interp, iPtr->ecVar, NULL,
iPtr->errorCode, TCL_GLOBAL_ONLY);
Tcl_DecrRefCount(iPtr->errorCode);
iPtr->errorCode = NULL;
}
if (iPtr->errorInfo) {
/* Legacy support*/
Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL,
iPtr->errorInfo, TCL_GLOBAL_ONLY);
Tcl_DecrRefCount(iPtr->errorInfo);
iPtr->errorInfo = NULL;
}
iPtr->flags &= ~ERR_ALREADY_LOGGED;
}
|
|
|
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
|
/* Legacy support */
Tcl_ObjSetVar2(interp, iPtr->ecVar, NULL,
iPtr->errorCode, TCL_GLOBAL_ONLY);
Tcl_DecrRefCount(iPtr->errorCode);
iPtr->errorCode = NULL;
}
if (iPtr->errorInfo) {
/* Legacy support */
Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL,
iPtr->errorInfo, TCL_GLOBAL_ONLY);
Tcl_DecrRefCount(iPtr->errorInfo);
iPtr->errorInfo = NULL;
}
iPtr->flags &= ~ERR_ALREADY_LOGGED;
}
|