/* * 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; } } }