Example #1
0
        /// <summary> This procedure is invoked to process the "seek" Tcl command.
        /// See the user documentation for details on what it does.
        /// </summary>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan; /* The channel being operated on this method */
            int     mode; /* Stores the search mode, either beg, cur or end
                           * of file.  See the TclIO class for more info */

            if (argv.Length != 3 && argv.Length != 4)
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId offset ?origin?");
            }

            // default is the beginning of the file

            mode = TclIO.SEEK_SET;
            if (argv.Length == 4)
            {
                int index = TclIndex.Get(interp, argv[3], validOrigins, "origin", 0);

                switch (index)
                {
                case OPT_START:
                {
                    mode = TclIO.SEEK_SET;
                    break;
                }

                case OPT_CURRENT:
                {
                    mode = TclIO.SEEK_CUR;
                    break;
                }

                case OPT_END:
                {
                    mode = TclIO.SEEK_END;
                    break;
                }
                }
            }


            chan = TclIO.getChannel(interp, argv[1].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
            }
            long offset = TclInteger.Get(interp, argv[2]);

            try
            {
                chan.seek(interp, offset, mode);
            }
            catch (IOException e)
            {
                // FIXME: Need to figure out Tcl specific error conditions.
                // Should we also wrap an IOException in a ReflectException?
                throw new TclRuntimeError("SeekCmd.cmdProc() Error: IOException when seeking " + chan.ChanName + ":" + e.Message);
            }
            return(TCL.CompletionCode.RETURN);
        }
Example #2
0
        /*
         *----------------------------------------------------------------------
         *
         * InfoLevelCmd --
         *
         *      Called to implement the "info level" command that returns
         *      information about the call stack. Handles the following syntax:
         *
         *          info level ?number?
         *
         * Results:
         *      Returns if successful, raises TclException otherwise.
         *
         * Side effects:
         *      Returns a result in the interpreter's result object.
         *
         *----------------------------------------------------------------------
         */

        private static void InfoLevelCmd(Interp interp, TclObject[] objv)
        {
            int       level;
            CallFrame frame;
            TclObject list;

            if (objv.Length == 2)
            {
                // just "info level"
                if (interp.VarFrame == null)
                {
                    interp.SetResult(0);
                }
                else
                {
                    interp.SetResult(interp.VarFrame.Level);
                }
                return;
            }
            else if (objv.Length == 3)
            {
                level = TclInteger.Get(interp, objv[2]);

                if (level <= 0)
                {
                    if (interp.VarFrame == null)
                    {
                        throw new TclException(interp, "bad level \"" + objv[2].ToString() + "\"");
                    }

                    level += interp.VarFrame.Level;
                }

                for (frame = interp.VarFrame; frame != null; frame = frame.CallerVar)
                {
                    if (frame.Level == level)
                    {
                        break;
                    }
                }
                if ((frame == null) || frame.Objv == null)
                {
                    throw new TclException(interp, "bad level \"" + objv[2].ToString() + "\"");
                }

                list = TclList.NewInstance();
                for (int i = 0; i < frame.Objv.Length; i++)
                {
                    TclList.Append(interp, list, TclString.NewInstance(frame.Objv[i]));
                }
                interp.SetResult(list);
                return;
            }

            throw new TclNumArgsException(interp, 2, objv, "?number?");
        }
Example #3
0
 internal static int FormatNumber(Interp interp, char type, TclObject src, byte[] resultBytes, int cursor)
 {
     if (type == 'd')
     {
         double       dvalue = TclDouble.Get(interp, src);
         MemoryStream ms     = new MemoryStream(resultBytes, cursor, 8);
         BinaryWriter writer = new BinaryWriter(ms);
         writer.Write(dvalue);
         cursor += 8;
         writer.Close();
         ms.Close();
     }
     else if (type == 'f')
     {
         float        fvalue = (float)TclDouble.Get(interp, src);
         MemoryStream ms     = new MemoryStream(resultBytes, cursor, 4);
         BinaryWriter writer = new BinaryWriter(ms);
         writer.Write(fvalue);
         cursor += 4;
         writer.Close();
         ms.Close();
     }
     else
     {
         int value = TclInteger.Get(interp, src);
         if (type == 'c')
         {
             resultBytes[cursor++] = (byte)value;
         }
         else if (type == 's')
         {
             resultBytes[cursor++] = (byte)value;
             resultBytes[cursor++] = (byte)(value >> 8);
         }
         else if (type == 'S')
         {
             resultBytes[cursor++] = (byte)(value >> 8);
             resultBytes[cursor++] = (byte)value;
         }
         else if (type == 'i')
         {
             resultBytes[cursor++] = (byte)value;
             resultBytes[cursor++] = (byte)(value >> 8);
             resultBytes[cursor++] = (byte)(value >> 16);
             resultBytes[cursor++] = (byte)(value >> 24);
         }
         else if (type == 'I')
         {
             resultBytes[cursor++] = (byte)(value >> 24);
             resultBytes[cursor++] = (byte)(value >> 16);
             resultBytes[cursor++] = (byte)(value >> 8);
             resultBytes[cursor++] = (byte)value;
         }
     }
     return(cursor);
 }
Example #4
0
 public static bool Tcl_GetInt(Interp interp, TclObject to, out u32 value)
 {
     try
     {
         value = (u32)TclInteger.Get(interp, to);
         return(false);
     }
     catch
     {
         value = 0;
         return(true);
     }
 }
Example #5
0
 public static int Tcl_GetIntFromObj(Interp interp, TclObject to, out int value)
 {
     try
     {
         value = TclInteger.Get(interp, to);
         return(TCL.TCL_OK);
     }
     catch
     {
         value = 0;
         return(TCL.TCL_ERROR);
     }
 }
Example #6
0
        /// <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);
        }
Example #7
0
        internal static int getIntForIndex(Interp interp, TclObject tobj, int endValue)
        {
            int length, offset;

            if (tobj.InternalRep is TclInteger)
            {
                return(TclInteger.Get(interp, tobj));
            }


            string bytes = tobj.ToString();

            length = bytes.Length;

            string intforindex_error = "bad index \"" + bytes + "\": must be integer or end?-integer?" + checkBadOctal(interp, bytes);

            // FIXME : should we replace this call to regionMatches with a generic strncmp?
            if (!(String.Compare("end", 0, bytes, 0, (length > 3) ? 3 : length) == 0))
            {
                try
                {
                    offset = TclInteger.Get(null, tobj);
                }
                catch (TclException e)
                {
                    throw new TclException(interp, "bad index \"" + bytes + "\": must be integer or end?-integer?" + checkBadOctal(interp, bytes));
                }
                return(offset);
            }

            if (length <= 3)
            {
                return(endValue);
            }
            else if (bytes[3] == '-')
            {
                // This is our limited string expression evaluator

                offset = Util.getInt(interp, bytes.Substring(3));
                return(endValue + offset);
            }
            else
            {
                throw new TclException(interp, "bad index \"" + bytes + "\": must be integer or end?-integer?" + checkBadOctal(interp, bytes.Substring(3)));
            }
        }
Example #8
0
        /// <summary> See Tcl user documentation for details.</summary>
        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            int code;

            if (argv.Length > 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "?returnCode?");
            }
            if (argv.Length == 2)
            {
                code = TclInteger.Get(interp, argv[1]);
            }
            else
            {
                code = 0;
            }
            return(TCL.CompletionCode.EXIT);
        }
Example #9
0
        private static void setDoubleFromAny(Interp interp, TclObject tobj)
        {
            IInternalRep rep = tobj.InternalRep;

            if (rep is TclDouble)
            {
                /*
                 * Do nothing.
                 */
            }
            else if (rep is TclBoolean)
            {
                /*
                 * Short-cut.
                 */

                bool b = TclBoolean.get(interp, tobj);
                if (b)
                {
                    tobj.InternalRep = new TclDouble(1.0);
                }
                else
                {
                    tobj.InternalRep = new TclDouble(0.0);
                }
            }
            else if (rep is TclInteger)
            {
                /*
                 * Short-cut.
                 */

                int i = TclInteger.Get(interp, tobj);
                tobj.InternalRep = new TclDouble(i);
            }
            else
            {
                tobj.InternalRep = new TclDouble(interp, tobj.ToString());
            }
        }
Example #10
0
        /// <summary> Called to convert the other object's internal rep to boolean.
        ///
        /// </summary>
        /// <param name="interp">current interpreter.
        /// </param>
        /// <param name="tobj">the TclObject to convert to use the
        /// representation provided by this class.
        /// </param>
        private static void setBooleanFromAny(Interp interp, TclObject tobj)
        {
            IInternalRep rep = tobj.InternalRep;

            if (rep is TclBoolean)
            {
                /*
                 * Do nothing.
                 */
            }
            else if (rep is TclInteger)
            {
                int i = TclInteger.Get(interp, tobj);
                tobj.InternalRep = new TclBoolean(i != 0);
            }
            else
            {
                /*
                 * (ToDo) other short-cuts
                 */
                tobj.InternalRep = new TclBoolean(interp, tobj.ToString());
            }
        }
Example #11
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);
        }
Example #12
0
        /// <summary> Compares the order of two items in the array.
        ///
        /// </summary>
        /// <param name="obj1">first item.
        /// </param>
        /// <param name="obj2">second item.
        /// </param>
        /// <returns> 0 if they are equal, 1 if obj1 > obj2, -1 otherwise.
        ///
        /// </returns>
        /// <exception cref=""> TclException if an error occurs during sorting.
        /// </exception>
        private int compare(TclObject obj1, TclObject obj2)
        {
            int index;
            int code = 0;

            if (sortIndex != -1)
            {
                // The "-index" option was specified.  Treat each object as a
                // list, extract the requested element from each list, and
                // compare the elements, not the lists.  The special index "end"
                // is signaled here with a negative index (other than -1).

                TclObject obj;
                if (sortIndex < -1)
                {
                    index = TclList.getLength(sortInterp, obj1) - 1;
                }
                else
                {
                    index = sortIndex;
                }

                obj = TclList.index(sortInterp, obj1, index);
                if (obj == null)
                {
                    throw new TclException(sortInterp, "element " + index + " missing from sublist \"" + obj1 + "\"");
                }
                obj1 = obj;

                if (sortIndex < -1)
                {
                    index = TclList.getLength(sortInterp, obj2) - 1;
                }
                else
                {
                    index = sortIndex;
                }

                obj = TclList.index(sortInterp, obj2, index);
                if (obj == null)
                {
                    throw new TclException(sortInterp, "element " + index + " missing from sublist \"" + obj2 + "\"");
                }
                obj2 = obj;
            }

            switch (sortMode)
            {
            case ASCII:
                // ATK C# CompareTo use option
                // similar to -dictionary but a > A
                code = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(obj1.ToString(), obj2.ToString(), System.Globalization.CompareOptions.Ordinal);
                // code = obj1.ToString().CompareTo(obj2.ToString());
                break;

            case DICTIONARY:

                code = doDictionary(obj1.ToString(), obj2.ToString());
                break;

            case INTEGER:
                try
                {
                    int int1 = TclInteger.Get(sortInterp, obj1);
                    int int2 = TclInteger.Get(sortInterp, obj2);

                    if (int1 > int2)
                    {
                        code = 1;
                    }
                    else if (int2 > int1)
                    {
                        code = -1;
                    }
                }
                catch (TclException e1)
                {
                    sortInterp.AddErrorInfo("\n    (converting list element from string to integer)");
                    throw e1;
                }
                break;

            case REAL:
                try
                {
                    double f1 = TclDouble.Get(sortInterp, obj1);
                    double f2 = TclDouble.Get(sortInterp, obj2);

                    if (f1 > f2)
                    {
                        code = 1;
                    }
                    else if (f2 > f1)
                    {
                        code = -1;
                    }
                }
                catch (TclException e2)
                {
                    sortInterp.AddErrorInfo("\n    (converting list element from string to real)");
                    throw e2;
                }
                break;

            case COMMAND:
                StringBuilder sbuf = new StringBuilder(sortCommand);

                Util.appendElement(sortInterp, sbuf, obj1.ToString());

                Util.appendElement(sortInterp, sbuf, obj2.ToString());
                try
                {
                    sortInterp.Eval(sbuf.ToString(), 0);
                }
                catch (TclException e3)
                {
                    sortInterp.AddErrorInfo("\n    (user-defined comparison command)");
                    throw e3;
                }

                try
                {
                    code = TclInteger.Get(sortInterp, sortInterp.GetResult());
                }
                catch (TclException e)
                {
                    sortInterp.ResetResult();
                    TclException e4 = new TclException(sortInterp, "comparison command returned non-numeric result");
                    throw e4;
                }
                break;


            default:

                throw new TclRuntimeError("Unknown sortMode " + sortMode);
            }

            if (sortIncreasing)
            {
                return(code);
            }
            else
            {
                return(-code);
            }
        }
Example #13
0
        /// <summary> This procedure is invoked to process the "read" 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
            int       i      = 1;        // Index to the next arg in argv
            int       toRead = 0;        // Number of bytes or chars to read from channel
            int       charactersRead;    // Number of bytes or chars read from channel
            bool      readAll   = true;  // If true read-all else toRead
            bool      noNewline = false; // If true, strip the newline if there
            TclObject result;


            if ((argv.Length != 2) && (argv.Length != 3))
            {
                errorWrongNumArgs(interp, argv[0].ToString());
            }


            if (argv[i].ToString().Equals("-nonewline"))
            {
                noNewline = true;
                i++;
            }

            if (i == argv.Length)
            {
                errorWrongNumArgs(interp, argv[0].ToString());
            }


            chan = TclIO.getChannel(interp, argv[i].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[i].ToString() + "\"");
            }

            // Consumed channel name.

            i++;

            // Compute how many bytes or chars to read, and see whether the final
            // noNewline should be dropped.

            if (i < argv.Length)
            {
                string arg = argv[i].ToString();

                if (System.Char.IsDigit(arg[0]))
                {
                    toRead  = TclInteger.Get(interp, argv[i]);
                    readAll = false;
                }
                else if (arg.Equals("nonewline"))
                {
                    noNewline = true;
                }
                else
                {
                    throw new TclException(interp, "bad argument \"" + arg + "\": should be \"nonewline\"");
                }
            }

            try
            {
                if ((System.Object)chan.Encoding == null)
                {
                    result = TclByteArray.NewInstance();
                }
                else
                {
                    result = TclString.NewInstance(new StringBuilder(64));
                }
                if (readAll)
                {
                    charactersRead = chan.read(interp, result, TclIO.READ_ALL, 0);

                    // If -nonewline was specified, and we have not hit EOF
                    // and the last char is a "\n", then remove it and return.

                    if (noNewline)
                    {
                        string inStr = result.ToString();
                        if ((charactersRead > 0) && (inStr[charactersRead - 1] == '\n'))
                        {
                            interp.SetResult(inStr.Substring(0, ((charactersRead - 1)) - (0)));
                            return(TCL.CompletionCode.RETURN);
                        }
                    }
                }
                else
                {
                    // FIXME: Bug here, the -nonewline flag must be respected
                    // when reading a set number of bytes
                    charactersRead = chan.read(interp, result, TclIO.READ_N_BYTES, toRead);
                }

                /*
                 * // FIXME: Port this -nonewline logic from the C code.
                 * if (charactersRead < 0) {
                 * Tcl_ResetResult(interp);
                 * Tcl_AppendResult(interp, "error reading \"", name, "\": ",
                 * Tcl_PosixError(interp), (char *) NULL);
                 * Tcl_DecrRefCount(resultPtr);
                 * return TCL_ERROR;
                 * }
                 *
                 * // If requested, remove the last newline in the channel if at EOF.
                 *
                 * if ((charactersRead > 0) && (newline != 0)) {
                 * char *result;
                 * int length;
                 *
                 * result = Tcl_GetStringFromObj(resultPtr, length);
                 * if (result[length - 1] == '\n') {
                 * Tcl_SetObjLength(resultPtr, length - 1);
                 * }
                 * }
                 *
                 */

                interp.SetResult(result);
            }
            catch (IOException e)
            {
                throw new TclRuntimeError("ReadCmd.cmdProc() Error: IOException when reading " + chan.ChanName);
            }
            return(TCL.CompletionCode.RETURN);
        }
Example #14
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);
        }
Example #15
0
        /// <summary> This procedure is invoked to process the "fconfigure" 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) || (((argv.Length % 2) == 1) && (argv.Length != 3)))
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId ?optionName? ?value? ?optionName value?...");
            }


            chan = TclIO.getChannel(interp, argv[1].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
            }

            if (argv.Length == 2)
            {
                // return list of all name/value pairs for this channelId
                TclObject list = TclList.NewInstance();

                TclList.Append(interp, list, TclString.NewInstance("-blocking"));
                TclList.Append(interp, list, TclBoolean.newInstance(chan.Blocking));

                TclList.Append(interp, list, TclString.NewInstance("-buffering"));
                TclList.Append(interp, list, TclString.NewInstance(TclIO.getBufferingString(chan.Buffering)));

                TclList.Append(interp, list, TclString.NewInstance("-buffersize"));
                TclList.Append(interp, list, TclInteger.NewInstance(chan.BufferSize));

                // -encoding

                TclList.Append(interp, list, TclString.NewInstance("-encoding"));

                System.Text.Encoding javaEncoding = chan.Encoding;
                string tclEncoding;
                if ((System.Object)javaEncoding == null)
                {
                    tclEncoding = "binary";
                }
                else
                {
                    tclEncoding = EncodingCmd.getTclName(javaEncoding);
                }
                TclList.Append(interp, list, TclString.NewInstance(tclEncoding));

                // -eofchar

                TclList.Append(interp, list, TclString.NewInstance("-eofchar"));
                if (chan.ReadOnly)
                {
                    char eofChar = chan.InputEofChar;
                    TclList.Append(interp, list, (eofChar == 0) ? TclString.NewInstance("") : TclString.NewInstance(eofChar));
                }
                else if (chan.WriteOnly)
                {
                    char eofChar = chan.OutputEofChar;
                    TclList.Append(interp, list, (eofChar == 0) ? TclString.NewInstance("") : TclString.NewInstance(eofChar));
                }
                else if (chan.ReadWrite)
                {
                    char inEofChar  = chan.InputEofChar;
                    char outEofChar = chan.OutputEofChar;

                    TclObject eofchar_pair = TclList.NewInstance();

                    TclList.Append(interp, eofchar_pair, (inEofChar == 0) ? TclString.NewInstance("") : TclString.NewInstance(inEofChar));

                    TclList.Append(interp, eofchar_pair, (outEofChar == 0) ? TclString.NewInstance("") : TclString.NewInstance(outEofChar));

                    TclList.Append(interp, list, eofchar_pair);
                }
                else
                {
                    // Not readable or writeable, do nothing
                }

                // -translation

                TclList.Append(interp, list, TclString.NewInstance("-translation"));

                if (chan.ReadOnly)
                {
                    TclList.Append(interp, list, TclString.NewInstance(TclIO.getTranslationString(chan.InputTranslation)));
                }
                else if (chan.WriteOnly)
                {
                    TclList.Append(interp, list, TclString.NewInstance(TclIO.getTranslationString(chan.OutputTranslation)));
                }
                else if (chan.ReadWrite)
                {
                    TclObject translation_pair = TclList.NewInstance();

                    TclList.Append(interp, translation_pair, TclString.NewInstance(TclIO.getTranslationString(chan.InputTranslation)));
                    TclList.Append(interp, translation_pair, TclString.NewInstance(TclIO.getTranslationString(chan.OutputTranslation)));

                    TclList.Append(interp, list, translation_pair);
                }
                else
                {
                    // Not readable or writeable, do nothing
                }

                interp.SetResult(list);
            }

            if (argv.Length == 3)
            {
                // return value for supplied name

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

                switch (index)
                {
                case OPT_BLOCKING:
                {
                    // -blocking
                    interp.SetResult(chan.Blocking);
                    break;
                }

                case OPT_BUFFERING:
                {
                    // -buffering
                    interp.SetResult(TclIO.getBufferingString(chan.Buffering));
                    break;
                }

                case OPT_BUFFERSIZE:
                {
                    // -buffersize
                    interp.SetResult(chan.BufferSize);
                    break;
                }

                case OPT_ENCODING:
                {
                    // -encoding
                    System.Text.Encoding javaEncoding = chan.Encoding;
                    if ((System.Object)javaEncoding == null)
                    {
                        interp.SetResult("binary");
                    }
                    else
                    {
                        interp.SetResult(EncodingCmd.getTclName(javaEncoding));
                    }
                    break;
                }

                case OPT_EOFCHAR:
                {
                    // -eofchar
                    if (chan.ReadOnly)
                    {
                        char eofChar = chan.InputEofChar;
                        interp.SetResult((eofChar == 0) ? TclString.NewInstance("") : TclString.NewInstance(eofChar));
                    }
                    else if (chan.WriteOnly)
                    {
                        char eofChar = chan.OutputEofChar;
                        interp.SetResult((eofChar == 0) ? TclString.NewInstance("") : TclString.NewInstance(eofChar));
                    }
                    else if (chan.ReadWrite)
                    {
                        char inEofChar  = chan.InputEofChar;
                        char outEofChar = chan.OutputEofChar;

                        TclObject eofchar_pair = TclList.NewInstance();

                        TclList.Append(interp, eofchar_pair, (inEofChar == 0) ? TclString.NewInstance("") : TclString.NewInstance(inEofChar));

                        TclList.Append(interp, eofchar_pair, (outEofChar == 0) ? TclString.NewInstance("") : TclString.NewInstance(outEofChar));

                        interp.SetResult(eofchar_pair);
                    }
                    else
                    {
                        // Not readable or writeable, do nothing
                    }

                    break;
                }

                case OPT_TRANSLATION:
                {
                    // -translation
                    if (chan.ReadOnly)
                    {
                        interp.SetResult(TclIO.getTranslationString(chan.InputTranslation));
                    }
                    else if (chan.WriteOnly)
                    {
                        interp.SetResult(TclIO.getTranslationString(chan.OutputTranslation));
                    }
                    else if (chan.ReadWrite)
                    {
                        TclObject translation_pair = TclList.NewInstance();

                        TclList.Append(interp, translation_pair, TclString.NewInstance(TclIO.getTranslationString(chan.InputTranslation)));
                        TclList.Append(interp, translation_pair, TclString.NewInstance(TclIO.getTranslationString(chan.OutputTranslation)));

                        interp.SetResult(translation_pair);
                    }
                    else
                    {
                        // Not readable or writeable, do nothing
                    }

                    break;
                }

                default:
                {
                    throw new TclRuntimeError("Fconfigure.cmdProc() error: " + "incorrect index returned from TclIndex.get()");
                }
                }
            }
            for (int i = 3; i < argv.Length; i += 2)
            {
                // Iterate through the list setting the name with the
                // corresponding value.

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

                switch (index)
                {
                case OPT_BLOCKING:
                {
                    // -blocking
                    chan.Blocking = TclBoolean.get(interp, argv[i]);
                    break;
                }

                case OPT_BUFFERING:
                {
                    // -buffering

                    int id = TclIO.getBufferingID(argv[i].ToString());

                    if (id == -1)
                    {
                        throw new TclException(interp, "bad value for -buffering: must be " + "one of full, line, or none");
                    }

                    chan.Buffering = id;
                    break;
                }

                case OPT_BUFFERSIZE:
                {
                    // -buffersize
                    chan.BufferSize = TclInteger.Get(interp, argv[i]);
                    break;
                }

                case OPT_ENCODING:
                {
                    // -encoding

                    string tclEncoding = argv[i].ToString();

                    if (tclEncoding.Equals("") || tclEncoding.Equals("binary"))
                    {
                        chan.Encoding = null;
                    }
                    else
                    {
                        System.Text.Encoding javaEncoding = EncodingCmd.getJavaName(tclEncoding);
                        if ((System.Object)javaEncoding == null)
                        {
                            throw new TclException(interp, "unknown encoding \"" + tclEncoding + "\"");
                        }
                        chan.Encoding = javaEncoding;
                    }

                    break;
                }

                case OPT_EOFCHAR:
                {
                    // -eofchar
                    TclList.setListFromAny(interp, argv[i]);
                    int length = TclList.getLength(interp, argv[i]);

                    if (length > 2)
                    {
                        throw new TclException(interp, "bad value for -eofchar: " + "should be a list of zero, one, or two elements");
                    }

                    char   inputEofChar, outputEofChar;
                    string s;

                    if (length == 0)
                    {
                        inputEofChar = outputEofChar = (char)(0);
                    }
                    else if (length == 1)
                    {
                        s            = TclList.index(interp, argv[i], 0).ToString();
                        inputEofChar = outputEofChar = s[0];
                    }
                    else
                    {
                        s            = TclList.index(interp, argv[i], 0).ToString();
                        inputEofChar = s[0];


                        s             = TclList.index(interp, argv[i], 1).ToString();
                        outputEofChar = s[0];
                    }

                    chan.InputEofChar  = inputEofChar;
                    chan.OutputEofChar = outputEofChar;

                    break;
                }

                case OPT_TRANSLATION:
                {
                    // -translation
                    TclList.setListFromAny(interp, argv[i]);
                    int length = TclList.getLength(interp, argv[i]);

                    if (length < 1 || length > 2)
                    {
                        throw new TclException(interp, "bad value for -translation: " + "must be a one or two element list");
                    }

                    string inputTranslationArg, outputTranslationArg;
                    int    inputTranslation, outputTranslation;

                    if (length == 2)
                    {
                        inputTranslationArg = TclList.index(interp, argv[i], 0).ToString();
                        inputTranslation    = TclIO.getTranslationID(inputTranslationArg);

                        outputTranslationArg = TclList.index(interp, argv[i], 1).ToString();
                        outputTranslation    = TclIO.getTranslationID(outputTranslationArg);
                    }
                    else
                    {
                        outputTranslationArg = inputTranslationArg = argv[i].ToString();
                        outputTranslation    = inputTranslation = TclIO.getTranslationID(outputTranslationArg);
                    }

                    if ((inputTranslation == -1) || (outputTranslation == -1))
                    {
                        throw new TclException(interp, "bad value for -translation: " + "must be one of auto, binary, cr, lf, " + "crlf, or platform");
                    }

                    if (outputTranslation == TclIO.TRANS_AUTO)
                    {
                        outputTranslation = TclIO.TRANS_PLATFORM;
                    }

                    if (chan.ReadOnly)
                    {
                        chan.InputTranslation = inputTranslation;
                        if (inputTranslationArg.Equals("binary"))
                        {
                            chan.Encoding = null;
                        }
                    }
                    else if (chan.WriteOnly)
                    {
                        chan.OutputTranslation = outputTranslation;
                        if (outputTranslationArg.Equals("binary"))
                        {
                            chan.Encoding = null;
                        }
                    }
                    else if (chan.ReadWrite)
                    {
                        chan.InputTranslation  = inputTranslation;
                        chan.OutputTranslation = outputTranslation;
                        if (inputTranslationArg.Equals("binary") || outputTranslationArg.Equals("binary"))
                        {
                            chan.Encoding = null;
                        }
                    }
                    else
                    {
                        // Not readable or writeable, do nothing
                    }

                    break;
                }

                default:
                {
                    throw new TclRuntimeError("Fconfigure.cmdProc() error: " + "incorrect index returned from TclIndex.get()");
                }
                }
            }
            return(TCL.CompletionCode.RETURN);
        }
Example #16
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 && 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 = DateTime.Now.Ticks / 10000 + ms;
                    while (true)
                    {
                        try
                        {
                            Thread.Sleep(ms);
                            return(TCL.CompletionCode.RETURN);
                        }
                        catch (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);
        }
Example #17
0
        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            interp._errorCode = null;
            interp._errorInfo = null;
            TCL.CompletionCode returnCode;
            int i;

            /*
             * Note: returnCode is the value given by the -code option. Don't
             * confuse this value with the compCode variable of the
             * TclException thrown by this method, which is always TCL.CompletionCode.RETURN.
             */

            returnCode = TCL.CompletionCode.OK;
            for (i = 1; i < argv.Length - 1; i += 2)
            {
                if (argv[i].ToString().Equals("-code"))
                {
                    if (argv[i + 1].ToString().Equals("ok"))
                    {
                        returnCode = TCL.CompletionCode.OK;
                    }
                    else
                    {
                        if (argv[i + 1].ToString().Equals("error"))
                        {
                            returnCode = TCL.CompletionCode.ERROR;
                        }
                        else
                        {
                            if (argv[i + 1].ToString().Equals("return"))
                            {
                                returnCode = TCL.CompletionCode.RETURN;
                            }
                            else
                            {
                                if (argv[i + 1].ToString().Equals("break"))
                                {
                                    returnCode = TCL.CompletionCode.BREAK;
                                }
                                else
                                {
                                    if (argv[i + 1].ToString().Equals("continue"))
                                    {
                                        returnCode = TCL.CompletionCode.CONTINUE;
                                    }
                                    else
                                    {
                                        try
                                        {
                                            returnCode = (TCL.CompletionCode)TclInteger.Get(interp, argv[i + 1]);
                                        }
                                        catch (TclException e)
                                        {
                                            throw new TclException(interp, "bad completion code \"" + argv[i + 1] + "\": must be ok, error, return, break, " + "continue, or an integer");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (argv[i].ToString().Equals("-errorcode"))
                    {
                        interp._errorCode = argv[i + 1].ToString();
                    }
                    else
                    {
                        if (argv[i].ToString().Equals("-errorinfo"))
                        {
                            interp._errorInfo = argv[i + 1].ToString();
                        }
                        else
                        {
                            throw new TclException(interp, "bad option \"" + argv[i] + "\": must be -code, -errorcode, or -errorinfo");
                        }
                    }
                }
            }
            if (i != argv.Length)
            {
                interp.SetResult(argv[argv.Length - 1]);
            }

            interp._returnCode = returnCode;
            throw new TclException(TCL.CompletionCode.RETURN);
        }
Example #18
0
        /*
         *-----------------------------------------------------------------------------
         *
         * cmdProc --
         *
         *      This procedure is invoked to process the "lsearch" Tcl command.
         *      See the user documentation for details on what it does.
         *
         * Results:
         *      None.
         *
         * Side effects:
         *      See the user documentation.
         *
         *-----------------------------------------------------------------------------
         */

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv)
        {
            int       mode         = GLOB;
            int       dataType     = ASCII;
            bool      isIncreasing = true;
            TclObject pattern;
            TclObject list;

            if (objv.Length < 3)
            {
                throw new TclNumArgsException(interp, 1, objv, "?options? list pattern");
            }

            for (int i = 1; i < objv.Length - 2; i++)
            {
                switch (TclIndex.Get(interp, objv[i], options, "option", 0))
                {
                case LSEARCH_ASCII:
                    dataType = ASCII;
                    break;

                case LSEARCH_DECREASING:
                    isIncreasing = false;
                    break;

                case LSEARCH_DICTIONARY:
                    dataType = DICTIONARY;
                    break;

                case LSEARCH_EXACT:
                    mode = EXACT;
                    break;

                case LSEARCH_INCREASING:
                    isIncreasing = true;
                    break;

                case LSEARCH_INTEGER:
                    dataType = INTEGER;
                    break;

                case LSEARCH_GLOB:
                    mode = GLOB;
                    break;

                case LSEARCH_REAL:
                    dataType = REAL;
                    break;

                case LSEARCH_REGEXP:
                    mode = REGEXP;
                    break;

                case LSEARCH_SORTED:
                    mode = SORTED;
                    break;
                }
            }

            // Make sure the list argument is a list object and get its length and
            // a pointer to its array of element pointers.

            TclObject[] listv = TclList.getElements(interp, objv[objv.Length - 2]);

            TclObject patObj       = objv[objv.Length - 1];
            string    patternBytes = null;
            int       patInt       = 0;
            double    patDouble    = 0.0;
            int       length       = 0;

            if (mode == EXACT || mode == SORTED)
            {
                switch (dataType)
                {
                case ASCII:
                case DICTIONARY:

                    patternBytes = patObj.ToString();
                    length       = patternBytes.Length;
                    break;

                case INTEGER:
                    patInt = TclInteger.Get(interp, patObj);
                    break;

                case REAL:
                    patDouble = TclDouble.Get(interp, patObj);
                    break;
                }
            }
            else
            {
                patternBytes = patObj.ToString();
                length       = patternBytes.Length;
            }

            // Set default index value to -1, indicating failure; if we find the
            // item in the course of our search, index will be set to the correct
            // value.

            int index = -1;

            if (mode == SORTED)
            {
                // If the data is sorted, we can do a more intelligent search.
                int match = 0;
                int lower = -1;
                int upper = listv.Length;
                while (lower + 1 != upper)
                {
                    int i = (lower + upper) / 2;
                    switch (dataType)
                    {
                    case ASCII:
                    {
                        string bytes = listv[i].ToString();
                        match = patternBytes.CompareTo(bytes);
                        break;
                    }

                    case DICTIONARY:
                    {
                        string bytes = listv[i].ToString();
                        match = DictionaryCompare(patternBytes, bytes);
                        break;
                    }

                    case INTEGER:
                    {
                        int objInt = TclInteger.Get(interp, listv[i]);
                        if (patInt == objInt)
                        {
                            match = 0;
                        }
                        else if (patInt < objInt)
                        {
                            match = -1;
                        }
                        else
                        {
                            match = 1;
                        }
                        break;
                    }

                    case REAL:
                    {
                        double objDouble = TclDouble.Get(interp, listv[i]);
                        if (patDouble == objDouble)
                        {
                            match = 0;
                        }
                        else if (patDouble < objDouble)
                        {
                            match = -1;
                        }
                        else
                        {
                            match = 1;
                        }
                        break;
                    }
                    }
                    if (match == 0)
                    {
                        // Normally, binary search is written to stop when it
                        // finds a match.  If there are duplicates of an element in
                        // the list, our first match might not be the first occurance.
                        // Consider:  0 0 0 1 1 1 2 2 2
                        // To maintain consistancy with standard lsearch semantics,
                        // we must find the leftmost occurance of the pattern in the
                        // list.  Thus we don't just stop searching here.  This
                        // variation means that a search always makes log n
                        // comparisons (normal binary search might "get lucky" with
                        // an early comparison).

                        index = i;
                        upper = i;
                    }
                    else if (match > 0)
                    {
                        if (isIncreasing)
                        {
                            lower = i;
                        }
                        else
                        {
                            upper = i;
                        }
                    }
                    else
                    {
                        if (isIncreasing)
                        {
                            upper = i;
                        }
                        else
                        {
                            lower = i;
                        }
                    }
                }
            }
            else
            {
                for (int i = 0; i < listv.Length; i++)
                {
                    bool match = false;
                    switch (mode)
                    {
                    case SORTED:
                    case EXACT:
                    {
                        switch (dataType)
                        {
                        case ASCII:
                        {
                            string bytes   = listv[i].ToString();
                            int    elemLen = bytes.Length;
                            if (length == elemLen)
                            {
                                match = bytes.Equals(patternBytes);
                            }
                            break;
                        }

                        case DICTIONARY:
                        {
                            string bytes = listv[i].ToString();
                            match = (DictionaryCompare(bytes, patternBytes) == 0);
                            break;
                        }

                        case INTEGER:
                        {
                            int objInt = TclInteger.Get(interp, listv[i]);
                            match = (objInt == patInt);
                            break;
                        }

                        case REAL:
                        {
                            double objDouble = TclDouble.Get(interp, listv[i]);
                            match = (objDouble == patDouble);
                            break;
                        }
                        }
                        break;
                    }

                    case GLOB:
                    {
                        match = Util.StringMatch(listv[i].ToString(), patternBytes);
                        break;
                    }

                    case REGEXP:
                    {
                        match = Util.regExpMatch(interp, listv[i].ToString(), patObj);
                        break;
                    }
                    }
                    if (match)
                    {
                        index = i;
                        break;
                    }
                }
            }
            interp.SetResult(index);
            return(TCL.CompletionCode.RETURN);
        }
Example #19
0
        /// <summary> This procedure is invoked to process the "open" 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 pipeline  = false;        /* True if opening pipeline chan */
            int  prot      = 438;          /* Final rdwr permissions of file */
            int  modeFlags = TclIO.RDONLY; /* Rdwr mode for the file.  See the
                                            * TclIO class for more info on the
                                            * valid modes */

            if ((argv.Length < 2) || (argv.Length > 4))
            {
                throw new TclNumArgsException(interp, 1, argv, "fileName ?access? ?permissions?");
            }

            if (argv.Length > 2)
            {
                TclObject mode = argv[2];

                string modeStr = mode.ToString();
                int    len     = modeStr.Length;

                // This "r+1" hack is just to get a test case to pass
                if ((len == 0) || (modeStr.StartsWith("r+") && len >= 3))
                {
                    throw new TclException(interp, "illegal access mode \"" + modeStr + "\"");
                }

                if (len < 3)
                {
                    switch (modeStr[0])
                    {
                    case 'r':
                    {
                        if (len == 1)
                        {
                            modeFlags = TclIO.RDONLY;
                            break;
                        }
                        else if (modeStr[1] == '+')
                        {
                            modeFlags = TclIO.RDWR;
                            break;
                        }
                    }
                        goto case 'w';

                    case 'w':
                    {
                        FileInfo f = FileUtil.getNewFileObj(interp, argv[1].ToString());
                        bool     tmpBool;
                        if (File.Exists(f.FullName))
                        {
                            tmpBool = true;
                        }
                        else
                        {
                            tmpBool = Directory.Exists(f.FullName);
                        }
                        if (tmpBool)
                        {
                            bool tmpBool2;
                            try
                            {
                                if (File.Exists(f.FullName))
                                {
                                    File.SetAttributes(f.FullName, FileAttributes.Normal);
                                    File.Delete(f.FullName);
                                    tmpBool2 = true;
                                }
                                else if (Directory.Exists(f.FullName))
                                {
                                    Directory.Delete(f.FullName);
                                    tmpBool2 = true;
                                }
                                else
                                {
                                    tmpBool2 = false;
                                }
                            }
                            // ATK added because .NET do not allow often to delete
                            // files used by another process
                            catch (IOException e)
                            {
                                throw new TclException(interp, "cannot open file: " + argv[1].ToString());
                            }
                            bool generatedAux = tmpBool2;
                        }
                        if (len == 1)
                        {
                            modeFlags = (TclIO.WRONLY | TclIO.CREAT);
                            break;
                        }
                        else if (modeStr[1] == '+')
                        {
                            modeFlags = (TclIO.RDWR | TclIO.CREAT);
                            break;
                        }
                    }
                        goto case 'a';

                    case 'a':
                    {
                        if (len == 1)
                        {
                            modeFlags = (TclIO.WRONLY | TclIO.APPEND);
                            break;
                        }
                        else if (modeStr[1] == '+')
                        {
                            modeFlags = (TclIO.RDWR | TclIO.CREAT | TclIO.APPEND);
                            break;
                        }
                    }
                        goto default;

                    default:
                    {
                        throw new TclException(interp, "illegal access mode \"" + modeStr + "\"");
                    }
                    }
                }
                else
                {
                    modeFlags = 0;
                    bool gotRorWflag = false;
                    int  mlen        = TclList.getLength(interp, mode);
                    for (int i = 0; i < mlen; i++)
                    {
                        TclObject marg = TclList.index(interp, mode, i);

                        if (marg.ToString().Equals("RDONLY"))
                        {
                            modeFlags  |= TclIO.RDONLY;
                            gotRorWflag = true;
                        }
                        else
                        {
                            if (marg.ToString().Equals("WRONLY"))
                            {
                                modeFlags  |= TclIO.WRONLY;
                                gotRorWflag = true;
                            }
                            else
                            {
                                if (marg.ToString().Equals("RDWR"))
                                {
                                    modeFlags  |= TclIO.RDWR;
                                    gotRorWflag = true;
                                }
                                else
                                {
                                    if (marg.ToString().Equals("APPEND"))
                                    {
                                        modeFlags |= TclIO.APPEND;
                                    }
                                    else
                                    {
                                        if (marg.ToString().Equals("CREAT"))
                                        {
                                            modeFlags |= TclIO.CREAT;
                                        }
                                        else
                                        {
                                            if (marg.ToString().Equals("EXCL"))
                                            {
                                                modeFlags |= TclIO.EXCL;
                                            }
                                            else
                                            {
                                                if (marg.ToString().Equals("TRUNC"))
                                                {
                                                    modeFlags |= TclIO.TRUNC;
                                                }
                                                else
                                                {
                                                    throw new TclException(interp, "invalid access mode \"" + marg.ToString() + "\": must be RDONLY, WRONLY, RDWR, APPEND, " + "CREAT EXCL, NOCTTY, NONBLOCK, or TRUNC");
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (!gotRorWflag)
                    {
                        throw new TclException(interp, "access mode must include either RDONLY, WRONLY, or RDWR");
                    }
                }
            }

            if (argv.Length == 4)
            {
                prot = TclInteger.Get(interp, argv[3]);
                throw new TclException(interp, "setting permissions not implemented yet");
            }

            if ((argv[1].ToString().Length > 0) && (argv[1].ToString()[0] == '|'))
            {
                pipeline = true;
                throw new TclException(interp, "pipes not implemented yet");
            }

            /*
             * Open the file or create a process pipeline.
             */

            if (!pipeline)
            {
                try
                {
                    FileChannel file = new FileChannel();

                    file.open(interp, argv[1].ToString(), modeFlags);
                    TclIO.registerChannel(interp, file);
                    interp.SetResult(file.ChanName);
                }
                catch (IOException e)
                {
                    throw new TclException(interp, "cannot open file: " + argv[1].ToString());
                }
            }
            else
            {
                /*
                 * Pipeline code here...
                 */
            }
            return(TCL.CompletionCode.RETURN);
        }