wasCSharpSQLite – Blame information for rev
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * InterpAliasCmd.java -- |
||
3 | * |
||
4 | * Implements the built-in "interp" Tcl command. |
||
5 | * |
||
6 | * Copyright (c) 2000 Christian Krone. |
||
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: InterpAliasCmd.java,v 1.1 2000/08/20 06:08:42 mo Exp $ |
||
15 | * |
||
16 | */ |
||
17 | using System; |
||
18 | using System.Collections; |
||
19 | |||
20 | namespace tcl.lang |
||
21 | { |
||
22 | |||
23 | /// <summary> This class implements the alias commands, which are created |
||
24 | /// in response to the built-in "interp alias" command in Tcl. |
||
25 | /// |
||
26 | /// </summary> |
||
27 | |||
28 | class InterpAliasCmd : CommandWithDispose |
||
29 | { |
||
30 | |||
31 | // Name of alias command in slave interp. |
||
32 | |||
33 | internal TclObject name; |
||
34 | |||
35 | // Interp in which target command will be invoked. |
||
36 | |||
37 | private Interp targetInterp; |
||
38 | |||
39 | // Tcl list making up the prefix of the target command to be invoked in |
||
40 | // the target interpreter. Additional arguments specified when calling |
||
41 | // the alias in the slave interp will be appended to the prefix before |
||
42 | // the command is invoked. |
||
43 | |||
44 | private TclObject prefix; |
||
45 | |||
46 | // Source command in slave interpreter, bound to command that invokes |
||
47 | // the target command in the target interpreter. |
||
48 | |||
49 | private WrappedCommand slaveCmd; |
||
50 | |||
51 | // Entry for the alias hash table in slave. |
||
52 | // This is used by alias deletion to remove the alias from the slave |
||
53 | // interpreter alias table. |
||
54 | |||
55 | private string aliasEntry; |
||
56 | |||
57 | // Interp in which the command is defined. |
||
58 | // This is the interpreter with the aliasTable in Slave. |
||
59 | |||
60 | private Interp slaveInterp; |
||
61 | public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv ) |
||
62 | { |
||
63 | targetInterp.preserve(); |
||
64 | targetInterp.nestLevel++; |
||
65 | |||
66 | targetInterp.resetResult(); |
||
67 | targetInterp.allowExceptions(); |
||
68 | |||
69 | // Append the arguments to the command prefix and invoke the command |
||
70 | // in the target interp's global namespace. |
||
71 | |||
72 | TclObject[] prefv = TclList.getElements( interp, prefix ); |
||
73 | TclObject cmd = TclList.newInstance(); |
||
74 | cmd.preserve(); |
||
75 | TclList.replace( interp, cmd, 0, 0, prefv, 0, prefv.Length - 1 ); |
||
76 | TclList.replace( interp, cmd, prefv.Length, 0, argv, 1, argv.Length - 1 ); |
||
77 | TclObject[] cmdv = TclList.getElements( interp, cmd ); |
||
78 | |||
79 | TCL.CompletionCode result = targetInterp.invoke( cmdv, Interp.INVOKE_NO_TRACEBACK ); |
||
80 | |||
81 | cmd.release(); |
||
82 | targetInterp.nestLevel--; |
||
83 | |||
84 | // Check if we are at the bottom of the stack for the target interpreter. |
||
85 | // If so, check for special return codes. |
||
86 | |||
87 | if ( targetInterp.nestLevel == 0 ) |
||
88 | { |
||
89 | if ( result == TCL.CompletionCode.RETURN ) |
||
90 | { |
||
91 | result = targetInterp.updateReturnInfo(); |
||
92 | } |
||
93 | if ( result != TCL.CompletionCode.OK && result != TCL.CompletionCode.ERROR ) |
||
94 | { |
||
95 | try |
||
96 | { |
||
97 | targetInterp.processUnexpectedResult( result ); |
||
98 | } |
||
99 | catch ( TclException e ) |
||
100 | { |
||
101 | result = e.getCompletionCode(); |
||
102 | } |
||
103 | } |
||
104 | } |
||
105 | |||
106 | targetInterp.release(); |
||
107 | interp.transferResult( targetInterp, result ); |
||
108 | return TCL.CompletionCode.RETURN; |
||
109 | } |
||
110 | public void disposeCmd() |
||
111 | { |
||
112 | if ( (System.Object)aliasEntry != null ) |
||
113 | { |
||
114 | SupportClass.HashtableRemove( slaveInterp.aliasTable, aliasEntry ); |
||
115 | } |
||
116 | |||
117 | if ( slaveCmd != null ) |
||
118 | { |
||
119 | SupportClass.HashtableRemove( targetInterp.targetTable, slaveCmd ); |
||
120 | } |
||
121 | |||
122 | name.release(); |
||
123 | prefix.release(); |
||
124 | } |
||
125 | internal static void create( Interp interp, Interp slaveInterp, Interp masterInterp, TclObject name, TclObject targetName, int objIx, TclObject[] objv ) |
||
126 | { |
||
127 | |||
128 | string inString = name.ToString(); |
||
129 | |||
130 | InterpAliasCmd alias = new InterpAliasCmd(); |
||
131 | |||
132 | alias.name = name; |
||
133 | name.preserve(); |
||
134 | |||
135 | alias.slaveInterp = slaveInterp; |
||
136 | alias.targetInterp = masterInterp; |
||
137 | |||
138 | alias.prefix = TclList.newInstance(); |
||
139 | alias.prefix.preserve(); |
||
140 | TclList.append( interp, alias.prefix, targetName ); |
||
141 | TclList.insert( interp, alias.prefix, 1, objv, objIx, objv.Length - 1 ); |
||
142 | |||
143 | slaveInterp.createCommand( inString, alias ); |
||
144 | alias.slaveCmd = NamespaceCmd.findCommand( slaveInterp, inString, null, 0 ); |
||
145 | |||
146 | try |
||
147 | { |
||
148 | interp.preventAliasLoop( slaveInterp, alias.slaveCmd ); |
||
149 | } |
||
150 | catch ( TclException e ) |
||
151 | { |
||
152 | // Found an alias loop! The last call to Tcl_CreateObjCommand made |
||
153 | // the alias point to itself. Delete the command and its alias |
||
154 | // record. Be careful to wipe out its client data first, so the |
||
155 | // command doesn't try to delete itself. |
||
156 | |||
157 | slaveInterp.deleteCommandFromToken( alias.slaveCmd ); |
||
158 | throw; |
||
159 | } |
||
160 | |||
161 | // Make an entry in the alias table. If it already exists delete |
||
162 | // the alias command. Then retry. |
||
163 | |||
164 | if ( slaveInterp.aliasTable.ContainsKey( inString ) ) |
||
165 | { |
||
166 | InterpAliasCmd oldAlias = (InterpAliasCmd)slaveInterp.aliasTable[inString]; |
||
167 | slaveInterp.deleteCommandFromToken( oldAlias.slaveCmd ); |
||
168 | } |
||
169 | |||
170 | alias.aliasEntry = inString; |
||
171 | SupportClass.PutElement( slaveInterp.aliasTable, inString, alias ); |
||
172 | |||
173 | // Create the new command. We must do it after deleting any old command, |
||
174 | // because the alias may be pointing at a renamed alias, as in: |
||
175 | // |
||
176 | // interp alias {} foo {} bar # Create an alias "foo" |
||
177 | // rename foo zop # Now rename the alias |
||
178 | // interp alias {} foo {} zop # Now recreate "foo"... |
||
179 | |||
180 | SupportClass.PutElement( masterInterp.targetTable, alias.slaveCmd, slaveInterp ); |
||
181 | |||
182 | interp.setResult( name ); |
||
183 | } |
||
184 | internal static void delete( Interp interp, Interp slaveInterp, TclObject name ) |
||
185 | { |
||
186 | // If the alias has been renamed in the slave, the master can still use |
||
187 | // the original name (with which it was created) to find the alias to |
||
188 | // delete it. |
||
189 | |||
190 | |||
191 | string inString = name.ToString(); |
||
192 | if ( !slaveInterp.aliasTable.ContainsKey( inString ) ) |
||
193 | { |
||
194 | throw new TclException( interp, "alias \"" + inString + "\" not found" ); |
||
195 | } |
||
196 | |||
197 | InterpAliasCmd alias = (InterpAliasCmd)slaveInterp.aliasTable[inString]; |
||
198 | slaveInterp.deleteCommandFromToken( alias.slaveCmd ); |
||
199 | } |
||
200 | internal static void describe( Interp interp, Interp slaveInterp, TclObject name ) |
||
201 | { |
||
202 | // If the alias has been renamed in the slave, the master can still use |
||
203 | // the original name (with which it was created) to find the alias to |
||
204 | // describe it. |
||
205 | |||
206 | |||
207 | string inString = name.ToString(); |
||
208 | if ( slaveInterp.aliasTable.ContainsKey( inString ) ) |
||
209 | { |
||
210 | InterpAliasCmd alias = (InterpAliasCmd)slaveInterp.aliasTable[inString]; |
||
211 | interp.setResult( alias.prefix ); |
||
212 | } |
||
213 | } |
||
214 | internal static void list( Interp interp, Interp slaveInterp ) |
||
215 | { |
||
216 | TclObject result = TclList.newInstance(); |
||
217 | interp.setResult( result ); |
||
218 | |||
219 | IEnumerator aliases = slaveInterp.aliasTable.Values.GetEnumerator(); |
||
220 | while ( aliases.MoveNext() ) |
||
221 | { |
||
222 | InterpAliasCmd alias = (InterpAliasCmd)aliases.Current; |
||
223 | TclList.append( interp, result, alias.name ); |
||
224 | } |
||
225 | } |
||
226 | internal WrappedCommand getTargetCmd( Interp interp ) |
||
227 | { |
||
228 | TclObject[] objv = TclList.getElements( interp, prefix ); |
||
229 | |||
230 | string targetName = objv[0].ToString(); |
||
231 | return NamespaceCmd.findCommand( targetInterp, targetName, null, 0 ); |
||
232 | } |
||
233 | internal static Interp getTargetInterp( Interp slaveInterp, string aliasName ) |
||
234 | { |
||
235 | if ( !slaveInterp.aliasTable.ContainsKey( aliasName ) ) |
||
236 | { |
||
237 | return null; |
||
238 | } |
||
239 | |||
240 | InterpAliasCmd alias = (InterpAliasCmd)slaveInterp.aliasTable[aliasName]; |
||
241 | |||
242 | return alias.targetInterp; |
||
243 | } |
||
244 | } // end InterpAliasCmd |
||
245 | } |