/*
* ForeachCmd.java
*
* Copyright (c) 1997 Cornell University.
* 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: ForeachCmd.java,v 1.4 1999/08/07 06:44:04 mo Exp $
*
*/
using System;
namespace tcl.lang
{
/// This class implements the built-in "Foreach" command in Tcl.
class ForeachCmd : Command
{
/// Tcl_ForeachObjCmd -> ForeachCmd.cmdProc
///
/// This procedure is invoked to process the "foreach" Tcl command.
/// See the user documentation for details on what it does.
///
///
/// the current interpreter.
///
/// command arguments.
///
/// TclException if script causes error.
///
public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv )
{
if ( objv.Length < 4 || ( objv.Length % 2 ) != 0 )
{
throw new TclNumArgsException( interp, 1, objv, "varList list ?varList list ...? command" );
}
// foreach {n1 n2} {1 2 3 4} {n3} {1 2} {puts $n1-$n2-$n3}
// name[0] = {n1 n2} value[0] = {1 2 3 4}
// name[1] = {n3} value[0] = {1 2}
TclObject[] name = new TclObject[( objv.Length - 2 ) / 2];
TclObject[] value = new TclObject[( objv.Length - 2 ) / 2];
int c, i, j, base_;
int maxIter = 0;
TclObject command = objv[objv.Length - 1];
bool done = false;
for ( i = 0; i < objv.Length - 2; i += 2 )
{
int x = i / 2;
name[x] = objv[i + 1];
value[x] = objv[i + 2];
int nSize = TclList.getLength( interp, name[x] );
int vSize = TclList.getLength( interp, value[x] );
if ( nSize == 0 )
{
throw new TclException( interp, "foreach varlist is empty" );
}
int iter = ( vSize + nSize - 1 ) / nSize;
if ( maxIter < iter )
{
maxIter = iter;
}
}
for ( c = 0; !done && c < maxIter; c++ )
{
// Set up the variables
for ( i = 0; i < objv.Length - 2; i += 2 )
{
int x = i / 2;
int nSize = TclList.getLength( interp, name[x] );
base_ = nSize * c;
for ( j = 0; j < nSize; j++ )
{
// Test and see if the name variable is an array.
Var[] result = Var.lookupVar( interp, name[x].ToString(), null, 0, null, false, false );
Var var = null;
if ( result != null )
{
if ( result[1] != null )
{
var = result[1];
}
else
{
var = result[0];
}
}
try
{
if ( base_ + j >= TclList.getLength( interp, value[x] ) )
{
interp.setVar( TclList.index( interp, name[x], j ), TclString.newInstance( "" ), 0 );
}
else
{
interp.setVar( TclList.index( interp, name[x], j ), TclList.index( interp, value[x], base_ + j ), 0 );
}
}
catch ( TclException e )
{
throw new TclException( interp, "couldn't set loop variable: \"" + TclList.index( interp, name[x], j ) + "\"" );
}
}
}
// Execute the script
try
{
interp.eval( command, 0 );
}
catch ( TclException e )
{
switch ( e.getCompletionCode() )
{
case TCL.CompletionCode.BREAK:
done = true;
break;
case TCL.CompletionCode.CONTINUE:
continue;
case TCL.CompletionCode.ERROR:
interp.addErrorInfo( "\n (\"foreach\" body line " + interp.errorLine + ")" );
throw;
default:
throw;
}
}
}
interp.resetResult();
return TCL.CompletionCode.RETURN;
}
}
}