Esempio n. 1
0
		/// <summary> See Tcl user documentation for details.</summary>
		
		public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
		{
			if ((argv.Length < 2) || (argv.Length > 3))
			{
				throw new TclNumArgsException(interp, 1, argv, "script ?count?");
			}
			
			int count;
			if (argv.Length == 2)
			{
				count = 1;
			}
			else
			{
				count = TclInteger.get(interp, argv[2]);
			}
			
			long startTime = System.DateTime.Now.Ticks;
			for (int i = 0; i < count; i++)
			{
				interp.eval(argv[1], 0);
			}
			long endTime = System.DateTime.Now.Ticks;
			long uSecs = (((endTime - startTime) / 10) / count);
			if (uSecs == 1)
			{
				interp.setResult(TclString.newInstance("1 microsecond per iteration"));
			}
			else
			{
				interp.setResult(TclString.newInstance(uSecs + " microseconds per iteration"));
			}
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 2
0
    /// <summary> Evaluates a Tcl expression. See Tcl user documentation for
    /// details.
    /// </summary>
    /// <exception cref=""> TclException If malformed expression.
    /// </exception>

    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {
      if ( argv.Length < 2 )
      {
        throw new TclNumArgsException( interp, 1, argv, "arg ?arg ...?" );
      }

      if ( argv.Length == 2 )
      {

        interp.setResult( interp.expr.eval( interp, argv[1].ToString() ) );
      }
      else
      {
        StringBuilder sbuf = new StringBuilder();

        sbuf.Append( argv[1].ToString() );
        for ( int i = 2; i < argv.Length; i++ )
        {
          sbuf.Append( ' ' );

          sbuf.Append( argv[i].ToString() );
        }
        interp.setResult( interp.expr.eval( interp, sbuf.ToString() ) );
      }
      return TCL.CompletionCode.RETURN;
    }
    /// <summary> This procedure is invoked to process the "eof" Tcl command.
    /// See the user documentation for details on what it does.
    /// 
    /// </summary>
    /// <param name="interp">the current interpreter.
    /// </param>
    /// <param name="argv">command arguments.
    /// </param>

    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {

      Channel chan; /* The channel being operated on this method */

      if ( argv.Length != 2 )
      {
        throw new TclNumArgsException( interp, 1, argv, "channelId" );
      }


      chan = TclIO.getChannel( interp, argv[1].ToString() );
      if ( chan == null )
      {

        throw new TclException( interp, "can not find channel named \"" + argv[1].ToString() + "\"" );
      }

      if ( chan.eof() )
      {
        interp.setResult( TclInteger.newInstance( 1 ) );
      }
      else
      {
        interp.setResult( TclInteger.newInstance( 0 ) );
      }
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 4
0
    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv )
    {
      TclObject varValue = null;

      if ( objv.Length < 2 )
      {
        throw new TclNumArgsException( interp, 1, objv, "varName ?value value ...?" );
      }
      else if ( objv.Length == 2 )
      {
        interp.resetResult();
        interp.setResult( interp.getVar( objv[1], 0 ) );
      }
      else
      {
        for ( int i = 2; i < objv.Length; i++ )
        {
          varValue = interp.setVar( objv[1], objv[i], TCL.VarFlag.APPEND_VALUE );
        }

        if ( varValue != null )
        {
          interp.resetResult();
          interp.setResult( varValue );
        }
        else
        {
          interp.resetResult();
        }
      }
      return TCL.CompletionCode.RETURN;
    }
    /// <summary> This procedure is invoked to process the "gets" Tcl command.
    /// See the user documentation for details on what it does.
    /// 
    /// </summary>
    /// <param name="interp">the current interpreter.
    /// </param>
    /// <param name="argv">command arguments.
    /// </param>

    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {

      bool writeToVar = false; // If true write to var passes as arg
      string varName = ""; // The variable to write value to
      Channel chan; // The channel being operated on
      int lineLen;
      TclObject line;

      if ( ( argv.Length < 2 ) || ( argv.Length > 3 ) )
      {
        throw new TclNumArgsException( interp, 1, argv, "channelId ?varName?" );
      }

      if ( argv.Length == 3 )
      {
        writeToVar = true;

        varName = argv[2].ToString();
      }


      chan = TclIO.getChannel( interp, argv[1].ToString() );
      if ( chan == null )
      {

        throw new TclException( interp, "can not find channel named \"" + argv[1].ToString() + "\"" );
      }

      try
      {
        line = TclString.newInstance( new StringBuilder( 64 ) );
        lineLen = chan.read( interp, line, TclIO.READ_LINE, 0 );
        if ( lineLen < 0 )
        {
          // FIXME: Need more specific posix error codes!
          if ( !chan.eof() && !chan.isBlocked( interp ) )
          {

            throw new TclPosixException( interp, TclPosixException.EIO, true, "error reading \"" + argv[1].ToString() + "\"" );
          }
          lineLen = -1;
        }
        if ( writeToVar )
        {
          interp.setVar( varName, line, 0 );
          interp.setResult( lineLen );
        }
        else
        {
          interp.setResult( line );
        }
      }
      catch ( IOException e )
      {
        throw new TclRuntimeError( "GetsCmd.cmdProc() Error: IOException when getting " + chan.ChanName + ": " + e.Message );
      }
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 6
0
		/// <summary> Creates an exception with the appropiate Tcl error message to
		/// indicate an error with variable access.
		/// 
		/// </summary>
		/// <param name="interp">currrent interpreter.
		/// </param>
		/// <param name="name1">first part of a variable name.
		/// </param>
		/// <param name="name2">second part of a variable name. May be null.
		/// </param>
		/// <param name="operation">either "read" or "set".
		/// </param>
		/// <param name="reason">a string message to explain why the operation fails..
		/// </param>
		
		internal TclVarException(Interp interp, string name1, string name2, string operation, string reason):base(TCL.CompletionCode.ERROR)
		{
			if (interp != null)
			{
				interp.resetResult();
				if ((System.Object) name2 == null)
				{
					interp.setResult("can't " + operation + " \"" + name1 + "\": " + reason);
				}
				else
				{
					interp.setResult("can't " + operation + " \"" + name1 + "(" + name2 + ")\": " + reason);
				}
			}
		}
Esempio n. 7
0
        /// <summary> Creates a TclException with the appropiate Tcl error
        /// message for having the wring number of arguments to a Tcl command.
        /// <p>
        /// Example: <pre>
        /// 
        /// if (argv.length != 3) {
        /// throw new TclNumArgsException(interp, 1, argv, "option name");
        /// }
        /// </pre>
        /// 
        /// </summary>
        /// <param name="interp">current Interpreter.
        /// </param>
        /// <param name="argc">the number of arguments to copy from the offending
        /// command to put into the error message.
        /// </param>
        /// <param name="argv">the arguments of the offending command.
        /// </param>
        /// <param name="message">extra message to appear in the error message that
        /// explains the proper usage of the command.
        /// </param>
        /// <exception cref=""> TclException is always thrown.
        /// </exception>
        public TclNumArgsException( Interp interp, int argc, TclObject[] argv, string message )
            : base(TCL.CompletionCode.ERROR)
        {
            if ( interp != null )
              {
            StringBuilder buff = new StringBuilder( 50 );
            buff.Append( "wrong # args: should be \"" );

            for ( int i = 0; i < argc; i++ )
            {
              if ( argv[i].InternalRep is TclIndex )
              {
            buff.Append( argv[i].InternalRep.ToString() );
              }
              else
              {
            buff.Append( argv[i].ToString() );
              }
              if ( i < ( argc - 1 ) )
              {
            buff.Append( " " );
              }
            }
            if ( ( message != null ) )
            {
              buff.Append( " " + message );
            }
            buff.Append( "\"" );
            interp.setResult( buff.ToString() );
              }
        }
Esempio n. 8
0
		/// <summary> This procedure is invoked to process the "tell" Tcl command.
		/// See the user documentation for details on what it does.
		/// 
		/// </summary>
		/// <param name="interp">the current interpreter.
		/// </param>
		/// <param name="argv">command arguments.
		/// </param>
		
		public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
		{
			
			Channel chan; /* The channel being operated on this method */
			
			if (argv.Length != 2)
			{
				throw new TclNumArgsException(interp, 1, argv, "channelId");
			}
			
			
			chan = TclIO.getChannel(interp, argv[1].ToString());
			if (chan == null)
			{
				
				throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
			}
			
			try
			{
				interp.setResult(TclInteger.newInstance((int) chan.tell()));
			}
			catch (System.IO.IOException e)
			{
				throw new TclException(interp, "Error in TellCmd");
			}
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 9
0
		public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
		{
			if (argv.Length < 2 || argv.Length > 4)
			{
				throw new TclNumArgsException(interp, 1, argv, "message ?errorInfo? ?errorCode?");
			}
			
			if (argv.Length >= 3)
			{
				
				string errorInfo = argv[2].ToString();
				
				if (!errorInfo.Equals(""))
				{
					interp.addErrorInfo(errorInfo);
					interp.errAlreadyLogged = true;
				}
			}
			
			if (argv.Length == 4)
			{
				interp.setErrorCode(argv[3]);
			}
			
			interp.setResult(argv[1]);
			throw new TclException(TCL.CompletionCode.ERROR);
		}
Esempio n. 10
0
		/// <summary> See Tcl user documentation for details.</summary>
		/// <exception cref=""> TclException If incorrect number of arguments.
		/// </exception>
		
		public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
		{
			if (argv.Length != 2)
			{
				throw new TclNumArgsException(interp, 1, argv, "list");
			}
			interp.setResult(TclInteger.newInstance(TclList.getLength(interp, argv[1])));
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 11
0
    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {
      bool debug;

      if ( argv.Length == 2 )
      {
        System.Diagnostics.Debug.WriteLine( "getting value of \"" + argv[1].ToString() + "\"" );

        interp.setResult( interp.getVar( argv[1], 0 ) );
      }
      else if ( argv.Length == 3 )
      {
        System.Diagnostics.Debug.WriteLine( "setting value of \"" + argv[1].ToString() + "\" to \"" + argv[2].ToString() + "\"" );
        interp.setResult( interp.setVar( argv[1], argv[2], 0 ) );
      }
      else
      {
        throw new TclNumArgsException( interp, 1, argv, "varName ?newValue?" );
      }
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 12
0
		protected internal TclException(Interp interp, string msg, TCL.CompletionCode ccode, int idx):base(msg)
		{
			if (ccode == TCL.CompletionCode.OK)
			{
				throw new TclRuntimeError("The reserved completion code TCL.CompletionCode.OK (0) cannot be used " + "in TclException");
			}
			compCode = ccode;
			errIndex = idx;
			
			if (interp != null && (System.Object) msg != null)
			{
				interp.setResult(msg);
			}
		}
    /// <summary> This procedure is invoked to process the "incr" Tcl command.
    /// See the user documentation for details on what it does.
    /// </summary>
    /// <exception cref=""> TclException if wrong # of args or increment is not an
    /// integer.
    /// </exception>

    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv )
    {
      int incrAmount;
      TclObject newValue;

      if ( ( objv.Length != 2 ) && ( objv.Length != 3 ) )
      {
        throw new TclNumArgsException( interp, 1, objv, "varName ?increment?" );
      }

      // Calculate the amount to increment by.

      if ( objv.Length == 2 )
      {
        incrAmount = 1;
      }
      else
      {
        try
        {
          incrAmount = TclInteger.get( interp, objv[2] );
        }
        catch ( TclException e )
        {
          interp.addErrorInfo( "\n    (reading increment)" );
          throw;
        }
      }

      // Increment the variable's value.

      newValue = Var.incrVar( interp, objv[1], null, incrAmount, TCL.VarFlag.LEAVE_ERR_MSG );

      // FIXME: we need to look at this exception throwing problem again
      /*
      if (newValue == null) {
      return TCL_ERROR;
      }
      */

      // Set the interpreter's object result to refer to the variable's new
      // value object.

      interp.setResult( newValue );
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 14
0
    /// <summary> See Tcl user documentation for details.</summary>
    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {
      TclObject list = TclList.newInstance();

      list.preserve();
      try
      {
          for ( int i = 1; i < argv.Length; i++ )
            TclList.append( interp, list, argv[i] );
        interp.setResult( list );
      }
      finally
      {
        list.release();
      }
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 15
0
    /// <summary> See Tcl user documentation for details.</summary>
    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {
      string sep = null;

      if ( argv.Length == 2 )
      {
        sep = null;
      }
      else if ( argv.Length == 3 )
      {

        sep = argv[2].ToString();
      }
      else
      {
        throw new TclNumArgsException( interp, 1, argv, "list ?joinString?" );
      }
      TclObject list = argv[1];
      int size = TclList.getLength( interp, list );

      if ( size == 0 )
      {
        interp.resetResult();
        return TCL.CompletionCode.RETURN;
      }


      StringBuilder sbuf = new StringBuilder( TclList.index( interp, list, 0 ).ToString() );

      for ( int i = 1; i < size; i++ )
      {
        if ( (System.Object)sep == null )
        {
          sbuf.Append( ' ' );
        }
        else
        {
          sbuf.Append( sep );
        }

        sbuf.Append( TclList.index( interp, list, i ).ToString() );
      }
      interp.setResult( sbuf.ToString() );
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 16
0
        public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
        {
            if ( argv.Length < 3 )
              {
            throw new TclNumArgsException( interp, 1, argv, "list index" );
              }

              int size = TclList.getLength( interp, argv[1] );
              int index = Util.getIntForIndex( interp, argv[2], size - 1 );
              TclObject element = TclList.index( interp, argv[1], index );

              if ( element != null )
              {
            interp.setResult( element );
              }
              else
              {
            interp.resetResult();
              }
              return TCL.CompletionCode.RETURN;
        }
Esempio n. 17
0
		/// <summary> This procedure is invoked to process the "fblocked" Tcl command.
		/// See the user documentation for details on what it does.
		/// 
		/// </summary>
		/// <param name="interp">the current interpreter.
		/// </param>
		/// <param name="argv">command arguments.
		/// </param>
		
		public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
		{
			
			Channel chan; // The channel being operated on this method
			
			if (argv.Length != 2)
			{
				throw new TclNumArgsException(interp, 1, argv, "channelId");
			}
			
			
			chan = TclIO.getChannel(interp, argv[1].ToString());
			if (chan == null)
			{
				
				throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
			}
			
			interp.setResult(chan.isBlocked(interp));
      return TCL.CompletionCode.RETURN;
    }
    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {
      if ( argv.Length != 1 )
      {
        throw new TclNumArgsException( interp, 1, argv, null );
      }

      // Get the name of the working dir.

      string dirName = interp.getWorkingDir().ToString();

      // Java File Object methods use backslashes on Windows.
      // Convert them to forward slashes before returning the dirName to Tcl.

      if ( JACL.PLATFORM == JACL.PLATFORM_WINDOWS )
      {
        dirName = dirName.Replace( '\\', '/' );
      }

      interp.setResult( dirName );
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 19
0
    /// <summary> See Tcl user documentation for details.</summary>
    /// <exception cref=""> TclException If incorrect number of arguments.
    /// </exception>

    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {
      if ( argv.Length != 4 )
      {
        throw new TclNumArgsException( interp, 1, argv, "lset list index element" );
      }

      int size = TclList.getLength( interp, argv[1] );
      int index = Util.getIntForIndex( interp, argv[2], size );
      TclObject list = argv[1];
      bool isDuplicate = false;

      // If the list object is unshared we can modify it directly. Otherwise
      // we create a copy to modify: this is "copy on write".

      if ( list.Shared )
      {
        list = list.duplicate();
        isDuplicate = true;
      }

      try
      { TclObject[] replace = new TclObject[1];
        replace[0]=argv[3];
        TclList.replace(interp,list,index,1,replace,0,0 );
        interp.setResult( list );
      }
      catch ( TclException e )
      {
        if ( isDuplicate )
        {
          list.release();
        }
        throw;
      }
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 20
0
		/// <summary> This procedure is invoked to process the "catch" Tcl command.
		/// See the user documentation for details on what it does.
		/// 
		/// </summary>
		/// <param name="interp">the current interpreter.
		/// </param>
		/// <param name="argv">command arguments.
		/// </param>
		/// <exception cref=""> TclException if wrong number of arguments.
		/// </exception>
		
		public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
		{
			if (argv.Length != 2 && argv.Length != 3)
			{
				throw new TclNumArgsException(interp, 1, argv, "command ?varName?");
			}
			
			TclObject result;
			TCL.CompletionCode code = TCL.CompletionCode.OK;
			
			try
			{
				interp.eval(argv[1], 0);
			}
			catch (TclException e)
			{
				code = e.getCompletionCode();
			}

      result = interp.getResult();

      if ( argv.Length == 3 )
			{
				try
				{
					interp.setVar(argv[2], result, 0);
				}
				catch (TclException e)
				{
					throw new TclException(interp, "couldn't save command result in variable");
				}
			}
			
			interp.resetResult();
			interp.setResult(TclInteger.newInstance((int)code));
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 21
0
    /// <summary> This procedure is invoked to process the "encoding" Tcl command.
    /// See the user documentation for details on what it does.
    /// 
    /// </summary>
    /// <param name="interp">the current interpreter.
    /// </param>
    /// <param name="argv">command arguments.
    /// </param>

    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {
      if ( argv.Length < 2 )
      {
        throw new TclNumArgsException( interp, 1, argv, "option ?arg ...?" );
      }

      int index = TclIndex.get( interp, argv[1], validCmds, "option", 0 );

      switch ( index )
      {

        case OPT_CONVERTTO:
        case OPT_CONVERTFROM:
          {
            string tclEncoding;
            Encoding javaEncoding;
            TclObject data;

            if ( argv.Length == 3 )
            {
              tclEncoding = systemTclEncoding;
              data = argv[2];
            }
            else if ( argv.Length == 4 )
            {

              tclEncoding = argv[2].ToString();
              data = argv[3];
            }
            else
            {
              throw new TclNumArgsException( interp, 2, argv, "?encoding? data" );
            }

            javaEncoding = getJavaName( tclEncoding );

            if ( (System.Object)javaEncoding == null )
            {
              throw new TclException( interp, "unknown encoding \"" + tclEncoding + "\"" );
            }

            try
            {
              if ( index == OPT_CONVERTFROM )
              {
                // Treat the string as binary data
                byte[] bytes = TclByteArray.getBytes( interp, data );

                // ATK
                interp.setResult( System.Text.Encoding.UTF8.GetString( bytes, 0, bytes.Length) );
              }
              else
              {
                // Store the result as binary data


                // ATK byte[] bytes = data.ToString().getBytes(javaEncoding);
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes( data.ToString() );
                interp.setResult( TclByteArray.newInstance( bytes ) );
              }
            }
            catch ( IOException ex )
            {
              throw new TclRuntimeError( "Encoding.cmdProc() error: " + "unsupported java encoding \"" + javaEncoding + "\"" );
            }

            break;
          }

        case OPT_NAMES:
          {
            if ( argv.Length > 2 )
            {
              throw new TclNumArgsException( interp, 2, argv, null );
            }

            TclObject list = TclList.newInstance();
            for ( int i = 0; i < tclNames.Length; i++ )
            {
              TclList.append( interp, list, TclString.newInstance( tclNames[i] ) );
            }
            interp.setResult( list );
            break;
          }

        case OPT_SYSTEM:
          {
            if ( argv.Length > 3 )
              throw new TclNumArgsException( interp, 2, argv, "?encoding?" );

            if ( argv.Length == 2 )
            {
              interp.setResult( systemTclEncoding );
            }
            else
            {

              string tclEncoding = argv[2].ToString();
              Encoding javaEncoding = getJavaName( tclEncoding );

              if ( javaEncoding == null )
              {
                throw new TclException( interp, "unknown encoding \"" + tclEncoding + "\"" );
              }

              systemTclEncoding = tclEncoding;
              systemJavaEncoding = javaEncoding;
            }

            break;
          }

        default:
          {
            throw new TclRuntimeError( "Encoding.cmdProc() error: " + "incorrect index returned from TclIndex.get()" );
          }

      }
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 22
0
    /// <summary> This procedure is invoked to process the "subst" Tcl command.
    /// See the user documentation for details on what it does.
    /// 
    /// </summary>
    /// <param name="interp">the current interpreter.
    /// </param>
    /// <param name="argv">command arguments.
    /// </param>
    /// <exception cref=""> TclException if wrong # of args or invalid argument(s).
    /// </exception>

    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;
    }
Esempio n. 23
0
 /// <summary> See Tcl user documentation for details.</summary>
 public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
 {
   interp.setResult( Util.concat( 1, argv.Length, argv ) );
   return TCL.CompletionCode.RETURN;
 }
Esempio n. 24
0
    public static void evalObjv( Interp interp, TclObject[] objv, int length, int flags )
    {
      Command cmd;
      WrappedCommand wCmd = null;
      TclObject[] newObjv;
      int i;
      CallFrame savedVarFrame; //Saves old copy of interp.varFrame
      // in case TCL.EVAL_GLOBAL was set.

      interp.resetResult();
      if ( objv.Length == 0 )
      {
        return;
      }

      // If the interpreter was deleted, return an error.

      if ( interp.deleted )
      {
        interp.setResult( "attempt to call eval in deleted interpreter" );
        interp.setErrorCode( TclString.newInstance( "CORE IDELETE {attempt to call eval in deleted interpreter}" ) );
        throw new TclException( TCL.CompletionCode.ERROR );
      }

      // Check depth of nested calls to eval:  if this gets too large,
      // it's probably because of an infinite loop somewhere.

      if ( interp.nestLevel >= interp.maxNestingDepth )
      {
        throw new TclException( interp, "too many nested calls to eval (infinite loop?)" );
      }
      interp.nestLevel++;

      try
      {
        // Find the procedure to execute this command. If there isn't one,
        // then see if there is a command "unknown".  If so, create a new
        // word array with "unknown" as the first word and the original
        // command words as arguments.  Then call ourselves recursively
        // to execute it.


        cmd = interp.getCommand( objv[0].ToString() );
        if ( cmd == null )
          wCmd = interp.getObjCommand( objv[0].ToString() );
        // See if we are running as a slave interpretor, and this is a windows command        
        if ( cmd == null && wCmd == null && interp.slave != null )
        {
          wCmd = interp.slave.masterInterp.getObjCommand( objv[0].ToString() );
        }
        if ( cmd == null && wCmd == null )
        {
          newObjv = new TclObject[objv.Length + 1];
          for ( i = ( objv.Length - 1 ); i >= 0; i-- )
          {
            newObjv[i + 1] = objv[i];
          }
          newObjv[0] = TclString.newInstance( "unknown" );
          newObjv[0].preserve();
          cmd = interp.getCommand( "unknown" );
          if ( cmd == null )
          {

            Debug.Assert( false, "invalid command name \"" + objv[0].ToString() + "\"" );
            throw new TclException( interp, "invalid command name \"" + objv[0].ToString() + "\"" );
          }
          else
          {
            evalObjv( interp, newObjv, length, 0 );
          }
          newObjv[0].release();
          return;
        }

        // Finally, invoke the Command's cmdProc.

        interp.cmdCount++;
        savedVarFrame = interp.varFrame;
        if ( ( flags & TCL.EVAL_GLOBAL ) != 0 )
        {
          interp.varFrame = null;
        }

        int rc = 0;
        if ( cmd != null )
        {
          if ( cmd.cmdProc( interp, objv ) == TCL.CompletionCode.EXIT )
            throw new TclException( TCL.CompletionCode.EXIT );
        }
        else
        {
          rc = wCmd.objProc( wCmd.objClientData, interp, objv.Length, objv );
          if ( rc != 0 )
          {
            if ( rc == TCL.TCL_RETURN )
              throw new TclException( TCL.CompletionCode.RETURN );
            throw new TclException( TCL.CompletionCode.ERROR );
          }
        }
        interp.varFrame = savedVarFrame;
      }
      finally
      {
        interp.nestLevel--;
      }
    }
Esempio n. 25
0
    public static TclParse parseVarName( Interp interp, char[] script_array, int script_index, int numBytes, TclParse parse, bool append )
    // Non-zero means append tokens to existing
    // information in parse; zero means ignore
    // existing tokens in parse and reinitialize
    // it. 
    {
      char cur;
      TclToken token, startToken;
      int endIndex, varIndex;

#if DEBUG
				System.Diagnostics.Debug.WriteLine();
				System.Diagnostics.Debug.WriteLine("Entered parseVarName()");
				System.Diagnostics.Debug.Write("now to parse var off the string \"");
				for (int k = script_index; k < script_array.Length; k++)
				{
					System.Diagnostics.Debug.Write(script_array[k]);
				}
				System.Diagnostics.Debug.WriteLine("\"");
#endif


      if ( numBytes >= 0 )
      {
        endIndex = script_index + numBytes;
      }
      else
      {
        endIndex = script_array.Length - 1;
      }
      if ( !append )
      {
        parse = new TclParse( interp, script_array, endIndex, null, -1 );
      }

      // Generate one token for the variable, an additional token for the
      // name, plus any number of additional tokens for the index, if
      // there is one.

      token = parse.getToken( parse.numTokens );
      token.type = TCL_TOKEN_VARIABLE;
      token.script_array = script_array;
      token.script_index = script_index;
      varIndex = parse.numTokens;
      parse.numTokens++;
      script_index++;
      if ( script_index >= endIndex )
      {
        // The dollar sign isn't followed by a variable name.
        // replace the TCL_TOKEN_VARIABLE token with a
        // TCL_TOKEN_TEXT token for the dollar sign.

        token.type = TCL_TOKEN_TEXT;
        token.size = 1;
        token.numComponents = 0;
        parse.result = TCL.CompletionCode.OK;
        return parse;
      }
      startToken = token;
      token = parse.getToken( parse.numTokens );

      // The name of the variable can have three forms:
      // 1. The $ sign is followed by an open curly brace.  Then 
      //    the variable name is everything up to the next close
      //    curly brace, and the variable is a scalar variable.
      // 2. The $ sign is not followed by an open curly brace.  Then
      //    the variable name is everything up to the next
      //    character that isn't a letter, digit, or underscore.
      //    :: sequences are also considered part of the variable
      //    name, in order to support namespaces. If the following
      //    character is an open parenthesis, then the information
      //    between parentheses is the array element name.
      // 3. The $ sign is followed by something that isn't a letter,
      //    digit, or underscore:  in this case, there is no variable
      //    name and the token is just "$".

      if ( script_array[script_index] == '{' )
      {
        System.Diagnostics.Debug.WriteLine( "parsing curley var name" );

        script_index++;
        token.type = TCL_TOKEN_TEXT;
        token.script_array = script_array;
        token.script_index = script_index;
        token.numComponents = 0;

        while ( true )
        {
          if ( script_index == endIndex )
          {
            if ( interp != null )
            {
              interp.setResult( "missing close-brace for variable name" );
            }
            parse.termIndex = token.script_index - 1;
            parse.incomplete = true;
            parse.result = TCL.CompletionCode.ERROR;
            return parse;
          }
          if ( script_array[script_index] == '}' )
          {
            break;
          }
          script_index++;
        }
        token.size = script_index - token.script_index;
        startToken.size = script_index - startToken.script_index;
        parse.numTokens++;
        script_index++;
      }
      else
      {
        System.Diagnostics.Debug.WriteLine( "parsing non curley var name" );

        token.type = TCL_TOKEN_TEXT;
        token.script_array = script_array;
        token.script_index = script_index;
        token.numComponents = 0;
        while ( script_index != endIndex )
        {
          cur = script_array[script_index];
          if ( ( System.Char.IsLetterOrDigit( cur ) ) || ( cur == '_' ) )
          {
            script_index++;
            continue;
          }
          if ( ( cur == ':' ) && ( ( ( script_index + 1 ) != endIndex ) && ( script_array[script_index + 1] == ':' ) ) )
          {
            script_index += 2;
            while ( ( script_index != endIndex ) && ( script_array[script_index] == ':' ) )
            {
              script_index++;
            }
            continue;
          }
          break;
        }
        token.size = script_index - token.script_index;
        if ( token.size == 0 )
        {
          // The dollar sign isn't followed by a variable name.
          // replace the TCL_TOKEN_VARIABLE token with a
          // TCL_TOKEN_TEXT token for the dollar sign.

          System.Diagnostics.Debug.WriteLine( "single $ with no var name found" );

          startToken.type = TCL_TOKEN_TEXT;
          startToken.size = 1;
          startToken.numComponents = 0;
          parse.result = TCL.CompletionCode.OK;
          return parse;
        }
        parse.numTokens++;
        if ( ( script_index != endIndex ) && ( script_array[script_index] == '(' ) )
        {
          // This is a reference to an array element.  Call
          // parseTokens recursively to parse the element name,
          // since it could contain any number of substitutions.

          System.Diagnostics.Debug.WriteLine( "parsing array element" );

          script_index++;
          parse = parseTokens( script_array, script_index, TYPE_CLOSE_PAREN, parse );
          if ( parse.result != TCL.CompletionCode.OK )
          {
            return parse;
          }
          if ( ( parse.termIndex == endIndex ) || ( parse.inString[parse.termIndex] != ')' ) )
          {
            if ( interp != null )
            {
              interp.setResult( "missing )" );
            }
            parse.termIndex = script_index - 1;
            parse.incomplete = true;
            parse.result = TCL.CompletionCode.ERROR;
            return parse;
          }
          script_index = parse.termIndex + 1;
        }
      }


#if DEBUG
				System.Diagnostics.Debug.WriteLine("default end parse case");
				System.Diagnostics.Debug.Write("var token is \"");
				for (int k = startToken.script_index; k < script_index; k++)
				{
					System.Diagnostics.Debug.Write(script_array[k]);
				}
				System.Diagnostics.Debug.WriteLine("\"");
#endif

      startToken.size = script_index - startToken.script_index;
      startToken.numComponents = parse.numTokens - ( varIndex + 1 );
      parse.result = TCL.CompletionCode.OK;
      return parse;
    }
Esempio n. 26
0
    public static void eval2( Interp interp, char[] script_array, int script_index, int numBytes, int flags )
    {
      int i;
      int objUsed = 0;
      int nextIndex, tokenIndex;
      int commandLength, bytesLeft;
      bool nested;
      TclObject[] objv;
      TclObject obj;
      TclParse parse = null;
      TclToken token;

      // Saves old copy of interp.varFrame in case TCL.EVAL_GLOBAL was set
      CallFrame savedVarFrame;

      // Take into account the trailing '\0'
      int script_length = script_array.Length - 1;


      // These are modified instead of script_array and script_index
      char[] src_array = script_array;
      int src_index = script_index;

#if DEBUG
				System.Diagnostics.Debug.WriteLine();
				System.Diagnostics.Debug.WriteLine("Entered eval2()");
				System.Diagnostics.Debug.Write("now to eval2 the string \"");
				for (int k = script_index; k < script_array.Length; k++)
				{
					System.Diagnostics.Debug.Write(script_array[k]);
				}
				System.Diagnostics.Debug.WriteLine("\"");
#endif



      if ( numBytes < 0 )
      {
        numBytes = script_length - script_index;
      }
      interp.resetResult();
      savedVarFrame = interp.varFrame;
      if ( ( flags & TCL.EVAL_GLOBAL ) != 0 )
      {
        interp.varFrame = null;
      }

      // Each iteration through the following loop parses the next
      // command from the script and then executes it.

      bytesLeft = numBytes;

      // Init objv with the most commonly used array size
      objv = grabObjv( interp, 3 );

      if ( ( interp.evalFlags & TCL_BRACKET_TERM ) != 0 )
      {
        nested = true;
      }
      else
      {
        nested = false;
      }
      interp.evalFlags &= ~TCL_BRACKET_TERM;

      try
      {

        do
        {
          parse = parseCommand( interp, src_array, src_index, bytesLeft, null, 0, nested );

          if ( parse.result != TCL.CompletionCode.OK )
          {
            throw new TclException( parse.result );
          }

          // The test on noEval is temporary.  As soon as the new expr
          // parser is implemented it should be removed.

          if ( parse.numWords > 0 && interp.noEval == 0 )
          {
            // Generate an array of objects for the words of the command.

            try
            {
              tokenIndex = 0;
              token = parse.getToken( tokenIndex );

              // Test to see if new space needs to be allocated.  If objv
              // is the EXACT size of parse.numWords, then no allocation
              // needs to be performed.

              if ( objv.Length != parse.numWords )
              {
                //System.out.println("need new size " + objv.length);
                releaseObjv( interp, objv ); //let go of resource
                objv = grabObjv( interp, parse.numWords ); //get new resource
              }
              else
              {
                //System.out.println("reusing size " + objv.length);
              }

              for ( objUsed = 0; objUsed < parse.numWords; objUsed++ )
              {
                obj = evalTokens( interp, parse.tokenList, tokenIndex + 1, token.numComponents );
                if ( obj == null )
                {
                  throw new TclException( TCL.CompletionCode.ERROR );
                }
                else
                {
                  objv[objUsed] = obj;
                  if ( token.type == TCL_TOKEN_EXPAND_WORD )
                  {
                    int numElements;
                    int code;
                    TclList.setListFromAny( null, objv[objUsed] );
                    TclObject[] elements = TclList.getElements( null, objv[objUsed] );
                    if ( elements.Length == 0 )
                    {
                      elements = new TclObject[1];
                      elements[0] = TclString.newInstance("{}") ;
                      TclList.setListFromAny( null, elements[0] );
                    }
                    numElements = elements.Length;
                    /*
                     * Some word expansion was requested. Check for objv resize.
                     */

                    int objIdx = objUsed + numElements - 1;
                    Array.Resize( ref objv, objIdx+1 );
                    while ( numElements-- != 0 )
                    {
                      objv[objIdx] = elements[numElements];
                      objv[objIdx].preserve();
                      objIdx--;
                    }
                    objUsed = objv.Length-1;
                  }
                }
                tokenIndex += ( token.numComponents + 1 );
                token = parse.getToken( tokenIndex );
              }

              // Execute the command and free the objects for its words.
              try
              {
                evalObjv( interp, objv, bytesLeft, 0 );
              }
              catch ( System.StackOverflowException e )
              {
                interp.setResult( "too many nested calls" + " to eval (infinite loop?)" );
                throw new TclException( TCL.CompletionCode.ERROR );
              }
            }
            catch ( TclException e )
            {
              // Generate various pieces of error information, such 
              // as the line number where the error occurred and 
              // information to add to the errorInfo variable.  Then 
              // free resources that had been allocated
              // to the command.

              if ( e.getCompletionCode() == TCL.CompletionCode.ERROR && !( interp.errAlreadyLogged ) )
              {
                commandLength = parse.commandSize;

                char term = script_array[parse.commandStart + commandLength - 1];
                int type = charType( term );
                int terminators;
                if ( nested )
                {
                  terminators = TYPE_COMMAND_END | TYPE_CLOSE_BRACK;
                }
                else
                {
                  terminators = TYPE_COMMAND_END;
                }
                if ( ( type & terminators ) != 0 )
                {
                  // The command where the error occurred didn't end 
                  // at the end of the script (i.e. it ended at a 
                  // terminator character such as ";".  Reduce the 
                  // length by one so that the error message
                  // doesn't include the terminator character.

                  commandLength -= 1;
                }
                interp.varFrame = savedVarFrame;
                logCommandInfo( interp, script_array, script_index, parse.commandStart, commandLength, e );
                throw e;
              }
              else
                throw;
            }
            finally
            {
              for ( i = 0; i < objUsed; i++ )
              {
                objv[i].release();
              }
              objUsed = 0;

              parse.release(); // Cleanup parser resources
            }
          }


          // Advance to the next command in the script.

          nextIndex = parse.commandStart + parse.commandSize;
          bytesLeft -= ( nextIndex - src_index );
          src_index = nextIndex;
          if ( nested && ( src_index > 1 ) && ( src_array[src_index - 1] == ']' ) )
          {

            // We get here in the special case where the TCL_BRACKET_TERM
            // flag was set in the interpreter and we reached a close
            // bracket in the script.  Return immediately.

            interp.termOffset = ( src_index - 1 ) - script_index;
            interp.varFrame = savedVarFrame;
            return;
          }
        }
        while ( bytesLeft > 0 );
      }
      finally
      {
        if ( parse != null )
        {
          parse.release(); // Let go of parser resources
        }
        releaseObjv( interp, objv ); // Let go of objv buffer
      }

      interp.termOffset = src_index - script_index;
      interp.varFrame = savedVarFrame;
      return;
    }
Esempio n. 27
0
    internal static void list( Interp interp, Interp slaveInterp )
    {
      TclObject result = TclList.newInstance();
      interp.setResult( result );

      IEnumerator aliases = slaveInterp.aliasTable.Values.GetEnumerator();
      while ( aliases.MoveNext() )
      {
        InterpAliasCmd alias = (InterpAliasCmd)aliases.Current;
        TclList.append( interp, result, alias.name );
      }
    }
Esempio n. 28
0
    internal static void describe( Interp interp, Interp slaveInterp, TclObject name )
    {
      // If the alias has been renamed in the slave, the master can still use
      // the original name (with which it was created) to find the alias to
      // describe it.


      string inString = name.ToString();
      if ( slaveInterp.aliasTable.ContainsKey( inString ) )
      {
        InterpAliasCmd alias = (InterpAliasCmd)slaveInterp.aliasTable[inString];
        interp.setResult( alias.prefix );
      }
    }
Esempio n. 29
0
    private const int GENERIC = 4; // Floating or exponential, 
    // depending on exponent. %g

    /// <summary> This procedure is invoked to process the "format" Tcl command.
    /// See the user documentation for details on what it does.
    /// 
    /// The first argument to the cmdProc is the formatString.  The cmdProc
    /// simply copies all the chars into the sbuf until a '%' is found.  At
    /// this point the cmdProc parces the formatString and determines the 
    /// format parameters.  The parcing of the formatString can be broken into
    /// six possible phases:
    /// 
    /// Phase 0 - Simply Print:            If the next char is %
    /// Phase 1 - XPG3 Position Specifier: If the format [1-n]$ is used
    /// Phase 2 - A Set of Flags:          One or more of the following + - 
    /// [space] 0 # 
    /// Phase 3 - A Minimun Field Width    Either [integer] or *
    /// Phase 4 - A Precision              If the format .[integer] or .*
    /// Phase 5 - A Length Modifier        If h is present
    /// Phase 6 - A Conversion Character   If one of the following is used
    /// d u i o x X c s f E g G
    /// 
    /// Any phase can skip ahead one or more phases, but are not allowed 
    /// to move back to previous phases.  Once the parameters are determined
    /// the cmdProc calls one of three private methods that returns a fully
    /// formatted string.  This loop occurs for ever '%' in the formatString.
    /// </summary>

    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv )
    {


      StringBuilder sbuf; // Stores the return value of the parsed
      // format string
      StrtoulResult stoul; // A return object to the strtoul call
      char[] format; // The format argument is converted to a char 
      // array and manipulated as such
      int phase; // Stores the current phase of the parsing
      int width; // Minimum field width
      int precision; // Field precision from field specifier
      int fmtFlags; // Used to store the format flags ( #,+,etc)
      int argIndex; // Index of argument to substitute next.
      int fmtIndex; // Used to locate end of the format fields.
      int endIndex; // Used to locate end of numerical fields.
      int intValue; // Generic storage variable
      long lngValue; // Store the TclInteger.get() result
      double dblValue; // Store the TclDouble.get() result
      bool noPercent; // Special case for speed:  indicates there's
      // no field specifier, just a string to copy.
      bool xpgSet; // Indicates that xpg has been used for the 
      // particular format of the main while loop
      bool gotXpg; // True means that an XPG3 %n$-style
      // specifier has been seen.
      bool gotSequential; // True means that a regular sequential
      // (non-XPG3) conversion specifier has
      // been seen.
      bool useShort; // Value to be printed is short 
      // (half word).
      bool precisionSet; // Used for f, e, and E conversions
      bool cont; // Used for phase 3

      if ( argv.Length < 2 )
      {
        throw new TclNumArgsException( interp, 1, argv, "formatString ?arg arg ...?" );
      }

      argIndex = 2;
      fmtIndex = 0;
      gotXpg = gotSequential = false;

      format = argv[1].ToString().ToCharArray();
      sbuf = new StringBuilder();

      // So, what happens here is to scan the format string one % group
      // at a time, making many individual appends to the StringBuffer.

      while ( fmtIndex < format.Length )
      {
        fmtFlags = phase = width = 0;
        noPercent = true;
        xpgSet = precisionSet = useShort = false;
        precision = -1;

        // Append all characters to sbuf that are not used for the
        // format specifier.


        if ( format[fmtIndex] != '%' )
        {
          int i;
          for ( i = fmtIndex; ( i < format.Length ); i++ )
          {
            if ( format[i] == '%' )
            {
              noPercent = false;
              break;
            }
          }
          sbuf.Append( new string( format, fmtIndex, i - fmtIndex ) );
          fmtIndex = i;
          if ( noPercent )
          {
            break;
          }
        }

        // If true, then a % has been indicated but we are at the end
        // of the format string.  Call function to throw exception.

        if ( fmtIndex + 1 >= format.Length )
        {
          errorEndMiddle( interp );
        }

        // Phase 0:
        // Check for %%.  If true then simply write a single '%'
        // to the list.

        checkOverFlow( interp, format, fmtIndex + 1 );
        if ( format[fmtIndex + 1] == '%' )
        {
          sbuf.Append( "%" );
          fmtIndex += 2;
          // Re-enter the loop 

          continue;
        }

        fmtIndex++;
        checkOverFlow( interp, format, fmtIndex );
        if ( System.Char.IsDigit( format[fmtIndex] ) )
        {
          // Parce the format array looking for the end of
          // the number. 

          stoul = strtoul( format, fmtIndex );
          intValue = (int)stoul.value;
          endIndex = stoul.index;

          if ( format[endIndex] == '$' )
          {
            if ( intValue == 0 )
            {
              errorBadIndex( interp, true );
            }

            // Phase 1:
            // Check for an XPG3-style %n$ specification.  
            // Note: there must not be a mixture of XPG3
            // specs and non-XPG3 specs in the same format string.

            if ( gotSequential )
            {
              errorMixedXPG( interp );
            }
            gotXpg = true;
            xpgSet = true;
            phase = 2;
            fmtIndex = endIndex + 1;
            argIndex = intValue + 1;
            if ( ( argIndex < 2 ) || ( argIndex >= argv.Length ) )
            {
              errorBadIndex( interp, gotXpg );
            }
          }
          else
          {
            // Phase 3:
            // Format jumped straight to phase 3; Setting 
            // width field.  Again, verify that all format
            // specifiers are sequential.

            if ( gotXpg )
            {
              errorMixedXPG( interp );
            }
            gotSequential = true;
            if ( format[fmtIndex] != '0' )
            {
              fmtIndex = endIndex;
              width = intValue;
              phase = 4;
            }
          }
        }
        else
        {
          if ( gotXpg )
          {
            errorMixedXPG( interp );
          }
          gotSequential = true;
        }

        // Phase 2:
        // Setting the Format Flags.  At this point the phase value
        // can be either zero or three.  Anything greater is an
        // incorrect format.

        if ( phase < 3 )
        {
          checkOverFlow( interp, format, fmtIndex );
          char ch = format[fmtIndex];
          cont = true;
          while ( cont )
          {
            switch ( ch )
            {

              case '-':
                {
                  fmtFlags |= LEFT_JUSTIFY;
                  break;
                }

              case '#':
                {
                  fmtFlags |= ALT_OUTPUT;
                  break;
                }

              case '0':
                {
                  fmtFlags |= PAD_W_ZERO;
                  break;
                }

              case ' ':
                {
                  fmtFlags |= SPACE_OR_SIGN;
                  break;
                }

              case '+':
                {
                  fmtFlags |= SHOW_SIGN;
                  break;
                }

              default:
                {
                  cont = false;
                }
                break;

            }
            if ( cont )
            {
              fmtIndex++;
              checkOverFlow( interp, format, fmtIndex );
              ch = format[fmtIndex];
            }
          }
          phase = 3;
        }

        // Phase 3:
        // Setting width field.  Partially redundant code from the
        // Phase 1 if/else statement, but this is made to run fast.

        checkOverFlow( interp, format, fmtIndex );
        if ( System.Char.IsDigit( format[fmtIndex] ) )
        {
          stoul = strtoul( format, fmtIndex );
          width = (int)stoul.value;
          fmtIndex = stoul.index;
        }
        else if ( format[fmtIndex] == '*' )
        {
          if ( argv.Length > argIndex )
          {
            width = TclInteger.get( interp, argv[argIndex] );
            if ( width < 0 )
            {
              width = -width;
              fmtFlags |= LEFT_JUSTIFY;
            }
            argIndex++;
            fmtIndex++;
          }
        }

        // Phase 4:
        // Setting the precision field.

        checkOverFlow( interp, format, fmtIndex );
        if ( format[fmtIndex] == '.' )
        {
          fmtIndex++;
          checkOverFlow( interp, format, fmtIndex );
          if ( System.Char.IsDigit( format[fmtIndex] ) )
          {
            precisionSet = true;

            stoul = strtoul( format, fmtIndex );
            precision = (int)stoul.value;
            fmtIndex = stoul.index;
          }
          else if ( format[fmtIndex] == '*' )
          {
            if ( argv.Length > argIndex )
            {
              precisionSet = true;
              precision = TclInteger.get( interp, argv[argIndex] );
              argIndex++;
              fmtIndex++;
              checkOverFlow( interp, format, fmtIndex );
            }
          }
          else
          {
            // Format field had a '.' without an integer or '*'
            // preceeding it  (eg  %2.d  or %2.-5d)

            errorBadField( interp, format[fmtIndex] );
          }
        }

        // Phase 5:
        // Setting the length modifier.

        if ( format[fmtIndex] == 'h' )
        {
          fmtIndex++;
          checkOverFlow( interp, format, fmtIndex );
          useShort = true;
        }
        else if ( format[fmtIndex] == 'l' )
        {
          fmtIndex++;
          checkOverFlow( interp, format, fmtIndex );

          // 'l' is ignored, but should still be processed.
        }

        if ( ( argIndex < 2 ) || ( argIndex >= argv.Length ) )
        {
          errorBadIndex( interp, gotXpg );
        }

        // Phase 6:
        // Setting conversion field.
        // At this point, variables are initialized as follows:
        //
        // width               The specified field width.  This is always
        //                         non-negative.  Zero is the default.
        // precision           The specified precision.  The default
        //                         is -1.
        // argIndex            The argument index from the argv array 
        //                         for the appropriate arg.
        // fmtFlags            The format flags are set via bitwise 
        //                         operations.  Below are the bits
        //                         and their meanings.

        //     ALT_OUTPUT          set if a '#' is present.
        //     SHOW_SIGN           set if a '+' is present.
        //     SPACE_OR_SIGN       set if a ' ' is present.
        //     LEFT_JUSTIFY        set if a '-' is present or if the
        //                           field width was negative.
        //     PAD_W_ZERO          set if a '0' is present

        string strValue = "";
        char index = format[fmtIndex];

        switch ( index )
        {

          case 'u':
          case 'd':
          case 'o':
          case 'x':
          case 'X':
          case 'i':
            {
              if ( index == 'u' )
              {
                // Since Java does not provide unsigned ints we need to 
                // make our own.  If the value is negative we need to 
                // clear out all of the leading bits from the 33rd bit
                // and on.  The result is a long value equal to that
                // of an unsigned int.

                lngValue = (long)TclInteger.get( interp, argv[argIndex] );
                if ( lngValue < 0 )
                {
                  lngValue = ( lngValue << 32 );
                  lngValue = ( SupportClass.URShift( lngValue, 32 ) );
                }
              }
              else
              {
                fmtFlags |= SIGNED_VALUE;
                lngValue = (long)TclInteger.get( interp, argv[argIndex] );
              }

              // If the useShort option has been selected, we need
              // to clear all but the first 16 bits.

              if ( useShort )
              {
                lngValue = ( lngValue << 48 );
                lngValue = ( lngValue >> 48 );
              }

              if ( index == 'o' )
              {
                sbuf.Append( cvtLngToStr( lngValue, width, precision, fmtFlags, 8, "01234567".ToCharArray(), "0" ) );
              }
              else if ( index == 'x' )
              {
                sbuf.Append( cvtLngToStr( lngValue, width, precision, fmtFlags, 16, "0123456789abcdef".ToCharArray(), "0x" ) );
              }
              else if ( index == 'X' )
              {
                sbuf.Append( cvtLngToStr( lngValue, width, precision, fmtFlags, 16, "0123456789ABCDEF".ToCharArray(), "0X" ) );
              }
              else
              {
                sbuf.Append( cvtLngToStr( lngValue, width, precision, fmtFlags, 10, "0123456789".ToCharArray(), "" ) );
              }
              break;
            }

          case 'c':
            {
              intValue = 0;
              char[] arr = new char[] { (char)TclInteger.get( interp, argv[argIndex] ) };
              strValue = new string( arr );
              sbuf.Append( cvtStrToStr( strValue, width, precision, fmtFlags ) );
              break;
            }

          case 's':
            {

              strValue = argv[argIndex].ToString();
              sbuf.Append( cvtStrToStr( strValue, width, precision, fmtFlags ) );
              break;
            }

          case 'f':
            {
              dblValue = TclDouble.get( interp, argv[argIndex] );
              sbuf.Append( cvtDblToStr( dblValue, width, precision, fmtFlags, 10, "0123456789".ToCharArray(), "", FLOAT ) );
              break;
            }

          case 'e':
            {
              dblValue = TclDouble.get( interp, argv[argIndex] );
              sbuf.Append( cvtDblToStr( dblValue, width, precision, fmtFlags, 10, "e".ToCharArray(), "", EXP ) );
              break;
            }

          case 'E':
            {
              dblValue = TclDouble.get( interp, argv[argIndex] );
              sbuf.Append( cvtDblToStr( dblValue, width, precision, fmtFlags, 10, "E".ToCharArray(), "", EXP ) );
              break;
            }

          case 'g':
            {
              dblValue = TclDouble.get( interp, argv[argIndex] );
              sbuf.Append( cvtDblToStr( dblValue, width, precision, fmtFlags, 10, "e".ToCharArray(), "", GENERIC ) );
              break;
            }

          case 'G':
            {
              dblValue = TclDouble.get( interp, argv[argIndex] );
              sbuf.Append( cvtDblToStr( dblValue, width, precision, fmtFlags, 10, "E".ToCharArray(), "", GENERIC ) );
              break;
            }

          default:
            {
              errorBadField( interp, format[fmtIndex] );
            }
            break;

        }
        fmtIndex++;
        argIndex++;
      }
      interp.setResult( sbuf.ToString() );
      return TCL.CompletionCode.RETURN;
    }
Esempio n. 30
0
    internal static void create( Interp interp, Interp slaveInterp, Interp masterInterp, TclObject name, TclObject targetName, int objIx, TclObject[] objv )
    {

      string inString = name.ToString();

      InterpAliasCmd alias = new InterpAliasCmd();

      alias.name = name;
      name.preserve();

      alias.slaveInterp = slaveInterp;
      alias.targetInterp = masterInterp;

      alias.prefix = TclList.newInstance();
      alias.prefix.preserve();
      TclList.append( interp, alias.prefix, targetName );
      TclList.insert( interp, alias.prefix, 1, objv, objIx, objv.Length - 1 );

      slaveInterp.createCommand( inString, alias );
      alias.slaveCmd = NamespaceCmd.findCommand( slaveInterp, inString, null, 0 );

      try
      {
        interp.preventAliasLoop( slaveInterp, alias.slaveCmd );
      }
      catch ( TclException e )
      {
        // Found an alias loop!  The last call to Tcl_CreateObjCommand made
        // the alias point to itself.  Delete the command and its alias
        // record.  Be careful to wipe out its client data first, so the
        // command doesn't try to delete itself.

        slaveInterp.deleteCommandFromToken( alias.slaveCmd );
        throw;
      }

      // Make an entry in the alias table. If it already exists delete
      // the alias command. Then retry.

      if ( slaveInterp.aliasTable.ContainsKey( inString ) )
      {
        InterpAliasCmd oldAlias = (InterpAliasCmd)slaveInterp.aliasTable[inString];
        slaveInterp.deleteCommandFromToken( oldAlias.slaveCmd );
      }

      alias.aliasEntry = inString;
      SupportClass.PutElement( slaveInterp.aliasTable, inString, alias );

      // Create the new command. We must do it after deleting any old command,
      // because the alias may be pointing at a renamed alias, as in:
      //
      // interp alias {} foo {} bar		# Create an alias "foo"
      // rename foo zop				# Now rename the alias
      // interp alias {} foo {} zop		# Now recreate "foo"...

      SupportClass.PutElement( masterInterp.targetTable, alias.slaveCmd, slaveInterp );

      interp.setResult( name );
    }