/*
* SubstCmd.java
*
* Copyright (c) 1997 Sun Microsystems, Inc.
*
* 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: SubstCmd.java,v 1.3 2003/01/09 02:15:39 mdejong Exp $
*
*/
using System.Text;
namespace tcl.lang
{
/// This class implements the built-in "subst" command in Tcl.
class SubstCmd : Command
{
private static readonly string[] validCmds = new string[] { "-nobackslashes", "-nocommands", "-novariables" };
internal const int OPT_NOBACKSLASHES = 0;
internal const int OPT_NOCOMMANDS = 1;
internal const int OPT_NOVARS = 2;
/// This procedure is invoked to process the "subst" Tcl command.
/// See the user documentation for details on what it does.
///
///
/// the current interpreter.
///
/// command arguments.
///
/// TclException if wrong # of args or invalid argument(s).
///
public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
{
int currentObjIndex, len, i;
int objc = argv.Length - 1;
bool doBackslashes = true;
bool doCmds = true;
bool doVars = true;
StringBuilder result = new StringBuilder();
string s;
char c;
for ( currentObjIndex = 1; currentObjIndex < objc; currentObjIndex++ )
{
if ( !argv[currentObjIndex].ToString().StartsWith( "-" ) )
{
break;
}
int opt = TclIndex.get( interp, argv[currentObjIndex], validCmds, "switch", 0 );
switch ( opt )
{
case OPT_NOBACKSLASHES:
doBackslashes = false;
break;
case OPT_NOCOMMANDS:
doCmds = false;
break;
case OPT_NOVARS:
doVars = false;
break;
default:
throw new TclException( interp, "SubstCmd.cmdProc: bad option " + opt + " index to cmds" );
}
}
if ( currentObjIndex != objc )
{
throw new TclNumArgsException( interp, currentObjIndex, argv, "?-nobackslashes? ?-nocommands? ?-novariables? string" );
}
/*
* Scan through the string one character at a time, performing
* command, variable, and backslash substitutions.
*/
s = argv[currentObjIndex].ToString();
len = s.Length;
i = 0;
while ( i < len )
{
c = s[i];
if ( ( c == '[' ) && doCmds )
{
ParseResult res;
try
{
interp.evalFlags = Parser.TCL_BRACKET_TERM;
interp.eval( s.Substring( i + 1, ( len ) - ( i + 1 ) ) );
TclObject interp_result = interp.getResult();
interp_result.preserve();
res = new ParseResult( interp_result, i + interp.termOffset );
}
catch ( TclException e )
{
i = e.errIndex + 1;
throw;
}
i = res.nextIndex + 2;
result.Append( res.value.ToString() );
res.release();
}
else if ( c == '\r' )
{
/*
* (ToDo) may not be portable on Mac
*/
i++;
}
else if ( ( c == '$' ) && doVars )
{
ParseResult vres = Parser.parseVar( interp, s.Substring( i, ( len ) - ( i ) ) );
i += vres.nextIndex;
result.Append( vres.value.ToString() );
vres.release();
}
else if ( ( c == '\\' ) && doBackslashes )
{
BackSlashResult bs = tcl.lang.Interp.backslash( s, i, len );
i = bs.nextIndex;
if ( bs.isWordSep )
{
break;
}
else
{
result.Append( bs.c );
}
}
else
{
result.Append( c );
i++;
}
}
interp.setResult( result.ToString() );
return TCL.CompletionCode.RETURN;
}
}
}