wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * TraceCmd.java --
3 *
4 * This file implements the Tcl "trace" command.
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: TraceCmd.java,v 1.6 1999/08/15 19:38:36 mo Exp $
15 *
16 */
17 using System.Collections;
18 using System.Text;
19  
20 namespace tcl.lang
21 {
22  
23 /// <summary> The TraceCmd class implements the Command interface for specifying
24 /// a new Tcl command. The method cmdProc implements the built-in Tcl
25 /// command "trace" which is used to manupilate variable traces. See
26 /// user documentation for more details.
27 /// </summary>
28  
29 class TraceCmd : Command
30 {
31  
32 // Valid sub-commands for the trace command.
33  
34 private static readonly string[] validCmds = new string[] { "variable", "vdelete", "vinfo" };
35  
36 private const int OPT_VARIABLE = 0;
37 private const int OPT_VDELETE = 1;
38 private const int OPT_VINFO = 2;
39  
40 // An array for quickly generating the Tcl strings corresponding to
41 // the TCL.VarFlag.TRACE_READS, TCL.VarFlag.TRACE_WRITES and TCL.VarFlag.TRACE_UNSETS flags.
42  
43 private static TclObject[] opStr;
44  
45 /*
46 *----------------------------------------------------------------------
47 *
48 * initOptStr --
49 *
50 * This static method is called when the TraceCmd class is loaded
51 * into the VM. It initializes the opStr array.
52 *
53 * Results:
54 * Initial value for opStr.
55 *
56 * Side effects:
57 * The TclObjects stored in opStr are preserve()'ed.
58 *
59 *----------------------------------------------------------------------
60 */
61  
62 private static TclObject[] initOptStr()
63 {
64 TclObject[] strings = new TclObject[8];
65 strings[0] = TclString.newInstance( "error" );
66 strings[1] = TclString.newInstance( "r" );
67 strings[2] = TclString.newInstance( "w" );
68 strings[3] = TclString.newInstance( "rw" );
69 strings[4] = TclString.newInstance( "u" );
70 strings[5] = TclString.newInstance( "ru" );
71 strings[6] = TclString.newInstance( "wu" );
72 strings[7] = TclString.newInstance( "rwu" );
73  
74 for ( int i = 0; i < 8; i++ )
75 {
76 strings[i].preserve();
77 }
78  
79 return strings;
80 }
81 public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv )
82 {
83 int len;
84  
85 if ( objv.Length < 2 )
86 {
87 throw new TclNumArgsException( interp, 1, objv, "option [arg arg ...]" );
88 }
89 int opt = TclIndex.get( interp, objv[1], validCmds, "option", 0 );
90  
91 switch ( opt )
92 {
93  
94 case OPT_VARIABLE:
95 case OPT_VDELETE:
96 if ( objv.Length != 5 )
97 {
98 if ( opt == OPT_VARIABLE )
99 {
100 throw new TclNumArgsException( interp, 1, objv, "variable name ops command" );
101 }
102 else
103 {
104 throw new TclNumArgsException( interp, 1, objv, "vdelete name ops command" );
105 }
106 }
107  
108 TCL.VarFlag flags = 0;
109  
110 string ops = objv[3].ToString();
111 len = ops.Length;
112 {
113 for ( int i = 0; i < len; i++ )
114 {
115 switch ( ops[i] )
116 {
117  
118 case 'r':
119 flags |= TCL.VarFlag.TRACE_READS;
120 break;
121  
122 case 'w':
123 flags |= TCL.VarFlag.TRACE_WRITES;
124 break;
125  
126 case 'u':
127 flags |= TCL.VarFlag.TRACE_UNSETS;
128 break;
129  
130 default:
131 flags = 0;
132 goto check_ops_brk;
133  
134 }
135 }
136 }
137  
138 check_ops_brk:
139 ;
140  
141  
142 if ( flags == 0 )
143 {
144  
145 throw new TclException( interp, "bad operations \"" + objv[3] + "\": should be one or more of rwu" );
146 }
147  
148 if ( opt == OPT_VARIABLE )
149 {
150  
151 CmdTraceProc trace = new CmdTraceProc( objv[4].ToString(), flags );
152 Var.traceVar( interp, objv[2], flags, trace );
153 }
154 else
155 {
156 // Search through all of our traces on this variable to
157 // see if there's one with the given command. If so, then
158 // delete the first one that matches.
159  
160  
161 ArrayList traces = Var.getTraces( interp, objv[2].ToString(), 0 );
162 if ( traces != null )
163 {
164 len = traces.Count;
165 for ( int i = 0; i < len; i++ )
166 {
167 TraceRecord rec = (TraceRecord)traces[i];
168  
169 if ( rec.trace is CmdTraceProc )
170 {
171 CmdTraceProc proc = (CmdTraceProc)rec.trace;
172  
173 if ( proc.flags == flags && proc.command.ToString().Equals( objv[4].ToString() ) )
174 {
175 Var.untraceVar( interp, objv[2], flags, proc );
176 break;
177 }
178 }
179 }
180 }
181 }
182 break;
183  
184  
185 case OPT_VINFO:
186 if ( objv.Length != 3 )
187 {
188 throw new TclNumArgsException( interp, 2, objv, "name" );
189 }
190  
191 ArrayList traces2 = Var.getTraces( interp, objv[2].ToString(), 0 );
192 if ( traces2 != null )
193 {
194 len = traces2.Count;
195 TclObject list = TclList.newInstance();
196 TclObject cmd = null;
197 list.preserve();
198  
199 try
200 {
201 for ( int i = 0; i < len; i++ )
202 {
203 TraceRecord rec = (TraceRecord)traces2[i];
204  
205 if ( rec.trace is CmdTraceProc )
206 {
207 CmdTraceProc proc = (CmdTraceProc)rec.trace;
208 TCL.VarFlag mode = proc.flags;
209 mode &= ( TCL.VarFlag.TRACE_READS | TCL.VarFlag.TRACE_WRITES | TCL.VarFlag.TRACE_UNSETS );
210 int modeInt = (int)mode;
211 modeInt /= ( (int)TCL.VarFlag.TRACE_READS );
212  
213 cmd = TclList.newInstance();
214 TclList.append( interp, cmd, opStr[modeInt] );
215 TclList.append( interp, cmd, TclString.newInstance( proc.command ) );
216 TclList.append( interp, list, cmd );
217 }
218 }
219 interp.setResult( list );
220 }
221 finally
222 {
223 list.release();
224 }
225 }
226 break;
227 }
228 return TCL.CompletionCode.RETURN;
229 }
230 static TraceCmd()
231 {
232 opStr = initOptStr();
233 }
234 } // TraceCmd
235 class CmdTraceProc : VarTrace
236 {
237  
238 // The command holds the Tcl script that will execute. The flags
239 // hold the mode flags that define what conditions to fire under.
240  
241 internal string command;
242 internal TCL.VarFlag flags;
243  
244 internal CmdTraceProc( string cmd, TCL.VarFlag newFlags )
245 {
246 flags = newFlags;
247 command = cmd;
248 }
249 public void traceProc( Interp interp, string part1, string part2, TCL.VarFlag flags )
250 {
251 if ( ( ( this.flags & flags ) != 0 ) && ( ( flags & TCL.VarFlag.INTERP_DESTROYED ) == 0 ) )
252 {
253 StringBuilder sbuf = new StringBuilder( command );
254  
255 try
256 {
257 Util.appendElement( interp, sbuf, part1 );
258 if ( (System.Object)part2 != null )
259 {
260 Util.appendElement( interp, sbuf, part2 );
261 }
262 else
263 {
264 Util.appendElement( interp, sbuf, "" );
265 }
266  
267 if ( ( flags & TCL.VarFlag.TRACE_READS ) != 0 )
268 {
269 Util.appendElement( interp, sbuf, "r" );
270 }
271 else if ( ( flags & TCL.VarFlag.TRACE_WRITES ) != 0 )
272 {
273 Util.appendElement( interp, sbuf, "w" );
274 }
275 else if ( ( flags & TCL.VarFlag.TRACE_UNSETS ) != 0 )
276 {
277 Util.appendElement( interp, sbuf, "u" );
278 }
279 }
280 catch ( TclException e )
281 {
282 throw new TclRuntimeError( "unexpected TclException: " + e.Message, e );
283 }
284  
285 // Execute the command.
286  
287 interp.eval( sbuf.ToString(), 0 );
288 }
289 }
290 } // CmdTraceProc
291 }