public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv ) { int i; Notifier notifier = (Notifier)interp.getNotifier(); Object info; if ( assocData == null ) { /* * Create the "after" information associated for this * interpreter, if it doesn't already exist. */ assocData = (AfterAssocData)interp.getAssocData( "tclAfter" ); if ( assocData == null ) { assocData = new AfterAssocData( this ); interp.setAssocData( "tclAfter", assocData ); } } if ( argv.Length < 2 ) { throw new TclNumArgsException( interp, 1, argv, "option ?arg arg ...?" ); } /* * First lets see if the command was passed a number as the first argument. */ bool isNumber = false; int ms = 0; if ( argv[1].InternalRep is TclInteger ) { ms = TclInteger.get( interp, argv[1] ); isNumber = true; } else { string s = argv[1].ToString(); if ( ( s.Length > 0 ) && ( System.Char.IsDigit( s[0] ) ) ) { ms = TclInteger.get( interp, argv[1] ); isNumber = true; } } if ( isNumber ) { if ( ms < 0 ) { ms = 0; } if ( argv.Length == 2 ) { /* * Sleep for at least the given milliseconds and return. */ long endTime = System.DateTime.Now.Ticks / 10000 + ms; while ( true ) { try { System.Threading.Thread.Sleep( ms ); return TCL.CompletionCode.RETURN; } catch ( System.Threading.ThreadInterruptedException e ) { /* * We got interrupted. Sleep again if we havn't slept * long enough yet. */ long sysTime = System.DateTime.Now.Ticks / 10000; if ( sysTime >= endTime ) { return TCL.CompletionCode.RETURN; } ms = (int)( endTime - sysTime ); continue; } } } TclObject cmd = getCmdObject( argv ); cmd.preserve(); assocData.lastAfterId++; TimerInfo timerInfo = new TimerInfo( this, notifier, ms ); timerInfo.interp = interp; timerInfo.command = cmd; timerInfo.id = assocData.lastAfterId; assocData.handlers.Add( timerInfo ); interp.setResult( "after#" + timerInfo.id ); return TCL.CompletionCode.RETURN; } /* * If it's not a number it must be a subcommand. */ int index; try { index = TclIndex.get( interp, argv[1], validOpts, "option", 0 ); } catch ( TclException e ) { throw new TclException( interp, "bad argument \"" + argv[1] + "\": must be cancel, idle, info, or a number" ); } switch ( index ) { case OPT_CANCEL: if ( argv.Length < 3 ) { throw new TclNumArgsException( interp, 2, argv, "id|command" ); } TclObject arg = getCmdObject( argv ); arg.preserve(); /* * Search the timer/idle handler by id or by command. */ info = null; for ( i = 0; i < assocData.handlers.Count; i++ ) { Object obj = assocData.handlers[i]; if ( obj is TimerInfo ) { TclObject cmd = ( (TimerInfo)obj ).command; if ( ( cmd == arg ) || cmd.ToString().Equals( arg.ToString() ) ) { info = obj; break; } } else { TclObject cmd = ( (IdleInfo)obj ).command; if ( ( cmd == arg ) || cmd.ToString().Equals( arg.ToString() ) ) { info = obj; break; } } } if ( info == null ) { info = getAfterEvent( arg.ToString() ); } arg.release(); /* * Cancel the handler. */ if ( info != null ) { if ( info is TimerInfo ) { ( (TimerInfo)info ).cancel(); ( (TimerInfo)info ).command.release(); } else { ( (IdleInfo)info ).cancel(); ( (IdleInfo)info ).command.release(); } SupportClass.VectorRemoveElement( assocData.handlers, info ); } break; case OPT_IDLE: if ( argv.Length < 3 ) { throw new TclNumArgsException( interp, 2, argv, "script script ..." ); } TclObject cmd2 = getCmdObject( argv ); cmd2.preserve(); assocData.lastAfterId++; IdleInfo idleInfo = new IdleInfo( this, notifier ); idleInfo.interp = interp; idleInfo.command = cmd2; idleInfo.id = assocData.lastAfterId; assocData.handlers.Add( idleInfo ); interp.setResult( "after#" + idleInfo.id ); break; case OPT_INFO: if ( argv.Length == 2 ) { /* * No id is given. Return a list of current after id's. */ TclObject list = TclList.newInstance(); for ( i = 0; i < assocData.handlers.Count; i++ ) { int id; Object obj = assocData.handlers[i]; if ( obj is TimerInfo ) { id = ( (TimerInfo)obj ).id; } else { id = ( (IdleInfo)obj ).id; } TclList.append( interp, list, TclString.newInstance( "after#" + id ) ); } interp.resetResult(); interp.setResult( list ); return TCL.CompletionCode.RETURN; } if ( argv.Length != 3 ) { throw new TclNumArgsException( interp, 2, argv, "?id?" ); } /* * Return command and type of the given after id. */ info = getAfterEvent( argv[2].ToString() ); if ( info == null ) { throw new TclException( interp, "event \"" + argv[2] + "\" doesn't exist" ); } TclObject list2 = TclList.newInstance(); TclList.append( interp, list2, ( ( info is TimerInfo ) ? ( (TimerInfo)info ).command : ( (IdleInfo)info ).command ) ); TclList.append( interp, list2, TclString.newInstance( ( info is TimerInfo ) ? "timer" : "idle" ) ); interp.resetResult(); interp.setResult( list2 ); break; } return TCL.CompletionCode.RETURN; }
internal static Interp create( Interp interp, TclObject path, bool safe ) { Interp masterInterp; string pathString; TclObject[] objv = TclList.getElements( interp, path ); if ( objv.Length < 2 ) { masterInterp = interp; pathString = path.ToString(); } else { TclObject obj = TclList.newInstance(); TclList.insert( interp, obj, 0, objv, 0, objv.Length - 2 ); masterInterp = InterpCmd.getInterp( interp, obj ); pathString = objv[objv.Length - 1].ToString(); } if ( !safe ) { safe = masterInterp.isSafe; } if ( masterInterp.slaveTable.ContainsKey( pathString ) ) { throw new TclException( interp, "interpreter named \"" + pathString + "\" already exists, cannot create" ); } Interp slaveInterp = new Interp(); InterpSlaveCmd slave = new InterpSlaveCmd(); slaveInterp.slave = slave; slaveInterp.setAssocData( "InterpSlaveCmd", slave ); slave.masterInterp = masterInterp; slave.path = pathString; slave.slaveInterp = slaveInterp; masterInterp.createCommand( pathString, slaveInterp.slave ); slaveInterp.slave.interpCmd = NamespaceCmd.findCommand( masterInterp, pathString, null, 0 ); SupportClass.PutElement( masterInterp.slaveTable, pathString, slaveInterp.slave ); slaveInterp.setVar( "tcl_interactive", "0", TCL.VarFlag.GLOBAL_ONLY ); // Inherit the recursion limit. slaveInterp.maxNestingDepth = masterInterp.maxNestingDepth; if ( safe ) { try { makeSafe( slaveInterp ); } catch ( TclException e ) { SupportClass.WriteStackTrace( e, Console.Error ); } } else { //Tcl_Init(slaveInterp); } return slaveInterp; }