wasCSharpSQLite – Rev 1
?pathlinks?
/*
* InterpCmd.java --
*
* Implements the built-in "interp" Tcl command.
*
* Copyright (c) 2000 Christian Krone.
*
* See the file "license.terms" for information on usage and
* redistribution of this file, and for a DISCLAIMER OF ALL
* WARRANTIES.
*
* Included in SQLite3 port to C# for use in testharness only; 2008 Noah B Hart
*
* RCS @(#) $Id: InterpCmd.java,v 1.1 2000/08/20 06:08:43 mo Exp $
*
*/
using System;
using System.Collections;
namespace tcl.lang
{
/// <summary> This class implements the built-in "interp" command in Tcl.</summary>
class InterpCmd : Command
{
private static readonly string[] options = new string[] { "alias", "aliases", "create", "delete", "eval", "exists", "expose", "hide", "hidden", "issafe", "invokehidden", "marktrusted", "slaves", "share", "target", "transfer" };
private const int OPT_ALIAS = 0;
private const int OPT_ALIASES = 1;
private const int OPT_CREATE = 2;
private const int OPT_DELETE = 3;
private const int OPT_EVAL = 4;
private const int OPT_EXISTS = 5;
private const int OPT_EXPOSE = 6;
private const int OPT_HIDE = 7;
private const int OPT_HIDDEN = 8;
private const int OPT_ISSAFE = 9;
private const int OPT_INVOKEHIDDEN = 10;
private const int OPT_MARKTRUSTED = 11;
private const int OPT_SLAVES = 12;
private const int OPT_SHARE = 13;
private const int OPT_TARGET = 14;
private const int OPT_TRANSFER = 15;
private static readonly string[] createOptions = new string[] { "-safe", "--" };
private const int OPT_CREATE_SAFE = 0;
private const int OPT_CREATE_LAST = 1;
private static readonly string[] hiddenOptions = new string[] { "-global", "--" };
private const int OPT_HIDDEN_GLOBAL = 0;
private const int OPT_HIDDEN_LAST = 1;
public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv )
{
if ( objv.Length < 2 )
{
throw new TclNumArgsException( interp, 1, objv, "cmd ?arg ...?" );
}
int cmd = TclIndex.get( interp, objv[1], options, "option", 0 );
switch ( cmd )
{
case OPT_ALIAS:
{
if ( objv.Length >= 4 )
{
Interp slaveInterp = getInterp( interp, objv[2] );
if ( objv.Length == 4 )
{
InterpAliasCmd.describe( interp, slaveInterp, objv[3] );
return TCL.CompletionCode.RETURN;
}
if ( ( objv.Length == 5 ) && ( "".Equals( objv[4].ToString() ) ) )
{
InterpAliasCmd.delete( interp, slaveInterp, objv[3] );
return TCL.CompletionCode.RETURN;
}
if ( objv.Length > 5 )
{
Interp masterInterp = getInterp( interp, objv[4] );
if ( "".Equals( objv[5].ToString() ) )
{
if ( objv.Length == 6 )
{
InterpAliasCmd.delete( interp, slaveInterp, objv[3] );
return TCL.CompletionCode.RETURN;
}
}
else
{
InterpAliasCmd.create( interp, slaveInterp, masterInterp, objv[3], objv[5], 6, objv );
return TCL.CompletionCode.RETURN;
}
}
}
throw new TclNumArgsException( interp, 2, objv, "slavePath slaveCmd ?masterPath masterCmd? ?args ..?" );
}
case OPT_ALIASES:
{
Interp slaveInterp = getInterp( interp, objv );
InterpAliasCmd.list( interp, slaveInterp );
break;
}
case OPT_CREATE:
{
// Weird historical rules: "-safe" is accepted at the end, too.
bool safe = interp.isSafe;
TclObject slaveNameObj = null;
bool last = false;
for ( int i = 2; i < objv.Length; i++ )
{
if ( ( !last ) && ( objv[i].ToString()[0] == '-' ) )
{
int index = TclIndex.get( interp, objv[i], createOptions, "option", 0 );
if ( index == OPT_CREATE_SAFE )
{
safe = true;
continue;
}
i++;
last = true;
}
if ( slaveNameObj != null )
{
throw new TclNumArgsException( interp, 2, objv, "?-safe? ?--? ?path?" );
}
slaveNameObj = objv[i];
}
if ( slaveNameObj == null )
{
// Create an anonymous interpreter -- we choose its name and
// the name of the command. We check that the command name
// that we use for the interpreter does not collide with an
// existing command in the master interpreter.
int i = 0;
while ( interp.getCommand( "interp" + i ) != null )
{
i++;
}
slaveNameObj = TclString.newInstance( "interp" + i );
}
InterpSlaveCmd.create( interp, slaveNameObj, safe );
interp.setResult( slaveNameObj );
break;
}
case OPT_DELETE:
{
for ( int i = 2; i < objv.Length; i++ )
{
Interp slaveInterp = getInterp( interp, objv[i] );
if ( slaveInterp == interp )
{
throw new TclException( interp, "cannot delete the current interpreter" );
}
InterpSlaveCmd slave = slaveInterp.slave;
slave.masterInterp.deleteCommandFromToken( slave.interpCmd );
}
break;
}
case OPT_EVAL:
{
if ( objv.Length < 4 )
{
throw new TclNumArgsException( interp, 2, objv, "path arg ?arg ...?" );
}
Interp slaveInterp = getInterp( interp, objv[2] );
InterpSlaveCmd.eval( interp, slaveInterp, 3, objv );
break;
}
case OPT_EXISTS:
{
bool exists = true;
try
{
getInterp( interp, objv );
}
catch ( TclException e )
{
if ( objv.Length > 3 )
{
throw;
}
exists = false;
}
interp.setResult( exists );
break;
}
case OPT_EXPOSE:
{
if ( objv.Length < 4 || objv.Length > 5 )
{
throw new TclNumArgsException( interp, 2, objv, "path hiddenCmdName ?cmdName?" );
}
Interp slaveInterp = getInterp( interp, objv[2] );
InterpSlaveCmd.expose( interp, slaveInterp, 3, objv );
break;
}
case OPT_HIDE:
{
if ( objv.Length < 4 || objv.Length > 5 )
{
throw new TclNumArgsException( interp, 2, objv, "path cmdName ?hiddenCmdName?" );
}
Interp slaveInterp = getInterp( interp, objv[2] );
InterpSlaveCmd.hide( interp, slaveInterp, 3, objv );
break;
}
case OPT_HIDDEN:
{
Interp slaveInterp = getInterp( interp, objv );
InterpSlaveCmd.hidden( interp, slaveInterp );
break;
}
case OPT_ISSAFE:
{
Interp slaveInterp = getInterp( interp, objv );
interp.setResult( slaveInterp.isSafe );
break;
}
case OPT_INVOKEHIDDEN:
{
bool global = false;
int i;
for ( i = 3; i < objv.Length; i++ )
{
if ( objv[i].ToString()[0] != '-' )
{
break;
}
int index = TclIndex.get( interp, objv[i], hiddenOptions, "option", 0 );
if ( index == OPT_HIDDEN_GLOBAL )
{
global = true;
}
else
{
i++;
break;
}
}
if ( objv.Length - i < 1 )
{
throw new TclNumArgsException( interp, 2, objv, "path ?-global? ?--? cmd ?arg ..?" );
}
Interp slaveInterp = getInterp( interp, objv[2] );
InterpSlaveCmd.invokeHidden( interp, slaveInterp, global, i, objv );
break;
}
case OPT_MARKTRUSTED:
{
if ( objv.Length != 3 )
{
throw new TclNumArgsException( interp, 2, objv, "path" );
}
Interp slaveInterp = getInterp( interp, objv[2] );
InterpSlaveCmd.markTrusted( interp, slaveInterp );
break;
}
case OPT_SLAVES:
{
Interp slaveInterp = getInterp( interp, objv );
TclObject result = TclList.newInstance();
interp.setResult( result );
IEnumerator keys = slaveInterp.slaveTable.Keys.GetEnumerator();
while ( keys.MoveNext() )
{
string inString = (string)keys.Current;
TclList.append( interp, result, TclString.newInstance( inString ) );
}
break;
}
case OPT_SHARE:
{
if ( objv.Length != 5 )
{
throw new TclNumArgsException( interp, 2, objv, "srcPath channelId destPath" );
}
Interp masterInterp = getInterp( interp, objv[2] );
Channel chan = TclIO.getChannel( masterInterp, objv[3].ToString() );
if ( chan == null )
{
throw new TclException( interp, "can not find channel named \"" + objv[3].ToString() + "\"" );
}
Interp slaveInterp = getInterp( interp, objv[4] );
TclIO.registerChannel( slaveInterp, chan );
break;
}
case OPT_TARGET:
{
if ( objv.Length != 4 )
{
throw new TclNumArgsException( interp, 2, objv, "path alias" );
}
Interp slaveInterp = getInterp( interp, objv[2] );
string aliasName = objv[3].ToString();
Interp targetInterp = InterpAliasCmd.getTargetInterp( slaveInterp, aliasName );
if ( targetInterp == null )
{
throw new TclException( interp, "alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" not found" );
}
if ( !getInterpPath( interp, targetInterp ) )
{
throw new TclException( interp, "target interpreter for alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" is not my descendant" );
}
break;
}
case OPT_TRANSFER:
{
if ( objv.Length != 5 )
{
throw new TclNumArgsException( interp, 2, objv, "srcPath channelId destPath" );
}
Interp masterInterp = getInterp( interp, objv[2] );
Channel chan = TclIO.getChannel( masterInterp, objv[3].ToString() );
if ( chan == null )
{
throw new TclException( interp, "can not find channel named \"" + objv[3].ToString() + "\"" );
}
Interp slaveInterp = getInterp( interp, objv[4] );
TclIO.registerChannel( slaveInterp, chan );
TclIO.unregisterChannel( masterInterp, chan );
break;
}
}
return TCL.CompletionCode.RETURN;
}
private static Interp getInterp( Interp interp, TclObject[] objv )
{
if ( objv.Length == 2 )
{
return interp;
}
else if ( objv.Length == 3 )
{
return getInterp( interp, objv[2] );
}
else
{
throw new TclNumArgsException( interp, 2, objv, "?path?" );
}
}
private static bool getInterpPath( Interp askingInterp, Interp targetInterp )
{
if ( targetInterp == askingInterp )
{
return true;
}
if ( targetInterp == null || targetInterp.slave == null )
{
return false;
}
if ( !getInterpPath( askingInterp, targetInterp.slave.masterInterp ) )
{
return false;
}
askingInterp.appendElement( targetInterp.slave.path );
return true;
}
internal static Interp getInterp( Interp interp, TclObject path )
{
TclObject[] objv = TclList.getElements( interp, path );
Interp searchInterp = interp; //Interim storage for interp. to find.
for ( int i = 0; i < objv.Length; i++ )
{
string name = objv[i].ToString();
if ( !searchInterp.slaveTable.ContainsKey( name ) )
{
searchInterp = null;
break;
}
InterpSlaveCmd slave = (InterpSlaveCmd)searchInterp.slaveTable[name];
searchInterp = slave.slaveInterp;
if ( searchInterp == null )
{
break;
}
}
if ( searchInterp == null )
{
throw new TclException( interp, "could not find interpreter \"" + path.ToString() + "\"" );
}
return searchInterp;
}
} // end InterpCmd
}