wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * BgErrorMgr --
3 *
4 * This class manages the background errors for a Tcl interpreter.
5 *
6 * Copyright (c) 1997 Sun Microsystems, Inc.
7 *
8 * See the file "license.terms" for information on usage and
9 * redistribution of this file, and for a DISCLAIMER OF ALL
10 * WARRANTIES.
11 *
12 * Included in SQLite3 port to C# for use in testharness only; 2008 Noah B Hart
13 *
14 * RCS @(#) $Id: BgErrorMgr.java,v 1.6 2002/01/21 06:34:26 mdejong Exp $
15 *
16 */
17 using System;
18 using System.Collections;
19 using System.IO;
20  
21 namespace tcl.lang
22 {
23  
24 /*
25 * This class manages the background errors for a Tcl interpreter. It
26 * stores the error information about the interpreter and use an idle
27 * handler to report the error when the notifier is idle.
28 */
29  
30 class BgErrorMgr : AssocData
31 {
32 private void InitBlock()
33 {
34 errors = new ArrayList( 10 );
35 }
36  
37 /*
38 * We manage the background errors in this interp instance.
39 */
40  
41 internal Interp interp;
42  
43 /*
44 * A TclObject for invoking the "bgerror" command. We use a TclObject
45 * instead of a String so that we don't need to look up the command
46 * every time.
47 */
48  
49 internal TclObject bgerrorCmdObj;
50  
51 /*
52 * A list of the pending background error handlers.
53 */
54  
55 internal ArrayList errors;
56  
57 internal BgErrorMgr( Interp i )
58 {
59 InitBlock();
60 interp = i;
61 bgerrorCmdObj = TclString.newInstance( "bgerror" );
62 bgerrorCmdObj.preserve();
63  
64 errors = new ArrayList( 10 );
65 }
66 internal void addBgError()
67 {
68 BgError bgErr = new BgError( this, interp.getNotifier() );
69  
70 // The addErrorInfo() call below (with an empty string)
71 // ensures that errorInfo gets properly set. It's needed in
72 // cases where the error came from a utility procedure like
73 // Interp.getVar() instead of Interp.eval(); in these cases
74 // errorInfo still won't have been set when this procedure is
75 // called.
76  
77 interp.addErrorInfo( "" );
78  
79 bgErr.errorMsg = interp.getResult();
80 bgErr.errorInfo = null;
81 try
82 {
83 bgErr.errorInfo = interp.getVar( "errorInfo", null, TCL.VarFlag.GLOBAL_ONLY );
84 }
85 catch ( TclException e )
86 {
87 // Do nothing if var does not exist.
88 }
89  
90 bgErr.errorCode = null;
91 try
92 {
93 bgErr.errorCode = interp.getVar( "errorCode", null, TCL.VarFlag.GLOBAL_ONLY );
94 }
95 catch ( TclException e )
96 {
97 // Do nothing if var does not exist.
98 }
99  
100 bgErr.errorMsg.preserve();
101 bgErr.errorInfo.preserve();
102 bgErr.errorCode.preserve();
103  
104 errors.Add( bgErr );
105 }
106 public void disposeAssocData( Interp interp )
107 // The interpreter in which this AssocData
108 // instance is registered in.
109 {
110 for ( int i = errors.Count - 1; i >= 0; i-- )
111 {
112 BgError bgErr = (BgError)errors[i];
113 errors.RemoveAt( i );
114 bgErr.cancel();
115  
116 bgErr.errorMsg.release();
117 bgErr.errorMsg = null;
118 bgErr.errorInfo.release();
119 bgErr.errorInfo = null;
120 bgErr.errorCode.release();
121 bgErr.errorCode = null;
122 }
123  
124 bgerrorCmdObj.release();
125 bgerrorCmdObj = null;
126 }
127 internal class BgError : IdleHandler
128 {
129 private void InitBlock( BgErrorMgr enclosingInstance )
130 {
131 this.enclosingInstance = enclosingInstance;
132 }
133 private BgErrorMgr enclosingInstance;
134 public BgErrorMgr Enclosing_Instance
135 {
136 get
137 {
138 return enclosingInstance;
139 }
140  
141 }
142  
143 /*
144 * The interp's result, errorCode and errorInfo when the bgerror happened.
145 */
146  
147 internal TclObject errorMsg;
148 internal TclObject errorCode;
149 internal TclObject errorInfo;
150  
151 internal BgError( BgErrorMgr enclosingInstance, Notifier n )
152 : base( n )
153 {
154 InitBlock( enclosingInstance );
155 }
156 public override void processIdleEvent()
157 {
158  
159 // During the execution of this method, elements may be removed from
160 // the errors list (because a TCL.CompletionCode.BREAK was returned by the bgerror
161 // command, or because the interp was deleted). We remove this
162 // BgError instance from the list first so that this instance won't
163 // be deleted twice.
164  
165 SupportClass.VectorRemoveElement( Enclosing_Instance.errors, this );
166  
167 // Restore important state variables to what they were at
168 // the time the error occurred.
169  
170 try
171 {
172 Enclosing_Instance.interp.setVar( "errorInfo", null, errorInfo, TCL.VarFlag.GLOBAL_ONLY );
173 }
174 catch ( TclException e )
175 {
176  
177 // Ignore any TclException's, possibly caused by variable traces on
178 // the errorInfo variable. This is compatible with the behavior of
179 // the Tcl C API.
180 }
181  
182 try
183 {
184 Enclosing_Instance.interp.setVar( "errorCode", null, errorCode, TCL.VarFlag.GLOBAL_ONLY );
185 }
186 catch ( TclException e )
187 {
188  
189 // Ignore any TclException's, possibly caused by variable traces on
190 // the errorCode variable. This is compatible with the behavior of
191 // the Tcl C API.
192 }
193  
194 // Make sure, that the interpreter will surive the invocation
195 // of the bgerror command.
196  
197 Enclosing_Instance.interp.preserve();
198  
199 try
200 {
201  
202 // Invoke the bgerror command.
203  
204 TclObject[] argv = new TclObject[2];
205 argv[0] = Enclosing_Instance.bgerrorCmdObj;
206 argv[1] = errorMsg;
207  
208 Parser.evalObjv( Enclosing_Instance.interp, argv, 0, TCL.EVAL_GLOBAL );
209 }
210 catch ( TclException e )
211 {
212 switch ( e.getCompletionCode() )
213 {
214  
215 case TCL.CompletionCode.ERROR:
216 try
217 {
218 Channel chan = TclIO.getStdChannel( StdChannel.STDERR );
219  
220 if ( Enclosing_Instance.interp.getResult().ToString().Equals( "\"bgerror\" is an invalid command name or ambiguous abbreviation" ) )
221 {
222 chan.write( Enclosing_Instance.interp, errorInfo );
223 chan.write( Enclosing_Instance.interp, "\n" );
224 }
225 else
226 {
227 chan.write( Enclosing_Instance.interp, "bgerror failed to handle background error.\n" );
228 chan.write( Enclosing_Instance.interp, " Original error: " );
229 chan.write( Enclosing_Instance.interp, errorMsg );
230 chan.write( Enclosing_Instance.interp, "\n" );
231 chan.write( Enclosing_Instance.interp, " Error in bgerror: " );
232 chan.write( Enclosing_Instance.interp, Enclosing_Instance.interp.getResult() );
233 chan.write( Enclosing_Instance.interp, "\n" );
234 }
235 chan.flush( Enclosing_Instance.interp );
236 }
237 catch ( TclException e1 )
238 {
239  
240 // Ignore.
241 }
242 catch ( IOException e2 )
243 {
244  
245 // Ignore, too.
246 }
247 break;
248  
249  
250 case TCL.CompletionCode.BREAK:
251  
252 for ( int i = Enclosing_Instance.errors.Count - 1; i >= 0; i-- )
253 {
254 BgError bgErr = (BgError)Enclosing_Instance.errors[i];
255 Enclosing_Instance.errors.RemoveAt( i );
256 bgErr.cancel();
257  
258 bgErr.errorMsg.release();
259 bgErr.errorMsg = null;
260 bgErr.errorInfo.release();
261 bgErr.errorInfo = null;
262 bgErr.errorCode.release();
263 bgErr.errorCode = null;
264 }
265 break;
266 }
267 }
268  
269 Enclosing_Instance.interp.release();
270  
271 errorMsg.release();
272 errorMsg = null;
273 errorInfo.release();
274 errorInfo = null;
275 errorCode.release();
276 errorCode = null;
277 }
278 } // end BgErrorMgr.BgError
279 } // end BgErrorMgr
280 }