예제 #1
0
        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;
        }
예제 #2
0
    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;
    }