Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        internal static int FormatNumber(Interp interp, char type, TclObject src, byte[] resultBytes, int cursor)
        {
            if (type == 'd')
            {
                double dvalue                 = TclDouble.get(interp, src);
                System.IO.MemoryStream ms     = new System.IO.MemoryStream(resultBytes, cursor, 8);
                System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms);
                writer.Write(dvalue);
                cursor += 8;
                writer.Close();
                ms.Close();
            }
            else if (type == 'f')
            {
                float fvalue = (float)TclDouble.get(interp, src);
                System.IO.MemoryStream ms     = new System.IO.MemoryStream(resultBytes, cursor, 4);
                System.IO.BinaryWriter writer = new System.IO.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);
        }
Ejemplo n.º 3
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?");
        }
Ejemplo n.º 4
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);
     }
 }
Ejemplo n.º 5
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);
     }
 }
Ejemplo n.º 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);
        }
Ejemplo n.º 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)));
            }
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 9
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;
            }
            System.Environment.Exit(code);
            return(TCL.CompletionCode.RETURN);
        }
Ejemplo n.º 10
0
        private static void  setDoubleFromAny(Interp interp, TclObject tobj)
        {
            InternalRep 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());
            }
        }
Ejemplo n.º 11
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)
        {
            InternalRep 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());
            }
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
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)
        {
            System.Text.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 System.Text.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);
        }
Ejemplo n.º 14
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);
        }
Ejemplo n.º 15
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 (System.IO.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 (System.IO.IOException e)
                {
                    throw new TclException(interp, "cannot open file: " + argv[1].ToString());
                }
            }
            else
            {
                /*
                 * Pipeline code here...
                 */
            }
            return(TCL.CompletionCode.RETURN);
        }
 public static bool Tcl_GetIntFromObj(Interp interp, TclObject to, ref int value)
 {
     try { value = TclInteger.get(interp, to); return(false); }
     catch { return(true); }
 }
Ejemplo n.º 17
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            int      i;
            Notifier notifier = (Notifier)interp.getNotifier();
            Object   info;

            if (assocData == null)
            {
                /*
                 * Create the "after" information associated for this
                 * interpreter, if it doesn't already exist.
                 */

                assocData = (AfterAssocData)interp.getAssocData("tclAfter");
                if (assocData == null)
                {
                    assocData = new AfterAssocData(this);
                    interp.setAssocData("tclAfter", assocData);
                }
            }

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

            /*
             * First lets see if the command was passed a number as the first argument.
             */

            bool isNumber = false;
            int  ms       = 0;

            if (argv[1].InternalRep is TclInteger)
            {
                ms       = TclInteger.get(interp, argv[1]);
                isNumber = true;
            }
            else
            {
                string s = argv[1].ToString();
                if ((s.Length > 0) && (System.Char.IsDigit(s[0])))
                {
                    ms       = TclInteger.get(interp, argv[1]);
                    isNumber = true;
                }
            }

            if (isNumber)
            {
                if (ms < 0)
                {
                    ms = 0;
                }
                if (argv.Length == 2)
                {
                    /*
                     * Sleep for at least the given milliseconds and return.
                     */

                    long endTime = System.DateTime.Now.Ticks / 10000 + ms;
                    while (true)
                    {
                        try
                        {
                            System.Threading.Thread.Sleep(ms);
                            return(TCL.CompletionCode.RETURN);
                        }
                        catch (System.Threading.ThreadInterruptedException e)
                        {
                            /*
                             * We got interrupted. Sleep again if we havn't slept
                             * long enough yet.
                             */

                            long sysTime = System.DateTime.Now.Ticks / 10000;
                            if (sysTime >= endTime)
                            {
                                return(TCL.CompletionCode.RETURN);
                            }
                            ms = (int)(endTime - sysTime);
                            continue;
                        }
                    }
                }

                TclObject cmd = getCmdObject(argv);
                cmd.preserve();

                assocData.lastAfterId++;
                TimerInfo timerInfo = new TimerInfo(this, notifier, ms);
                timerInfo.interp  = interp;
                timerInfo.command = cmd;
                timerInfo.id      = assocData.lastAfterId;

                assocData.handlers.Add(timerInfo);

                interp.setResult("after#" + timerInfo.id);

                return(TCL.CompletionCode.RETURN);
            }

            /*
             * If it's not a number it must be a subcommand.
             */

            int index;

            try
            {
                index = TclIndex.get(interp, argv[1], validOpts, "option", 0);
            }
            catch (TclException e)
            {
                throw new TclException(interp, "bad argument \"" + argv[1] + "\": must be cancel, idle, info, or a number");
            }

            switch (index)
            {
            case OPT_CANCEL:
                if (argv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "id|command");
                }

                TclObject arg = getCmdObject(argv);
                arg.preserve();

                /*
                 * Search the timer/idle handler by id or by command.
                 */

                info = null;
                for (i = 0; i < assocData.handlers.Count; i++)
                {
                    Object obj = assocData.handlers[i];
                    if (obj is TimerInfo)
                    {
                        TclObject cmd = ((TimerInfo)obj).command;

                        if ((cmd == arg) || cmd.ToString().Equals(arg.ToString()))
                        {
                            info = obj;
                            break;
                        }
                    }
                    else
                    {
                        TclObject cmd = ((IdleInfo)obj).command;

                        if ((cmd == arg) || cmd.ToString().Equals(arg.ToString()))
                        {
                            info = obj;
                            break;
                        }
                    }
                }
                if (info == null)
                {
                    info = getAfterEvent(arg.ToString());
                }
                arg.release();

                /*
                 * Cancel the handler.
                 */

                if (info != null)
                {
                    if (info is TimerInfo)
                    {
                        ((TimerInfo)info).cancel();
                        ((TimerInfo)info).command.release();
                    }
                    else
                    {
                        ((IdleInfo)info).cancel();
                        ((IdleInfo)info).command.release();
                    }

                    SupportClass.VectorRemoveElement(assocData.handlers, info);
                }
                break;


            case OPT_IDLE:
                if (argv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "script script ...");
                }

                TclObject cmd2 = getCmdObject(argv);
                cmd2.preserve();
                assocData.lastAfterId++;

                IdleInfo idleInfo = new IdleInfo(this, notifier);
                idleInfo.interp  = interp;
                idleInfo.command = cmd2;
                idleInfo.id      = assocData.lastAfterId;

                assocData.handlers.Add(idleInfo);

                interp.setResult("after#" + idleInfo.id);
                break;


            case OPT_INFO:
                if (argv.Length == 2)
                {
                    /*
                     * No id is given. Return a list of current after id's.
                     */

                    TclObject list = TclList.newInstance();
                    for (i = 0; i < assocData.handlers.Count; i++)
                    {
                        int    id;
                        Object obj = assocData.handlers[i];
                        if (obj is TimerInfo)
                        {
                            id = ((TimerInfo)obj).id;
                        }
                        else
                        {
                            id = ((IdleInfo)obj).id;
                        }
                        TclList.append(interp, list, TclString.newInstance("after#" + id));
                    }
                    interp.resetResult();
                    interp.setResult(list);
                    return(TCL.CompletionCode.RETURN);
                }
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "?id?");
                }

                /*
                 * Return command and type of the given after id.
                 */


                info = getAfterEvent(argv[2].ToString());
                if (info == null)
                {
                    throw new TclException(interp, "event \"" + argv[2] + "\" doesn't exist");
                }
                TclObject list2 = TclList.newInstance();
                TclList.append(interp, list2, ((info is TimerInfo)?((TimerInfo)info).command:((IdleInfo)info).command));
                TclList.append(interp, list2, TclString.newInstance((info is TimerInfo)?"timer":"idle"));

                interp.resetResult();
                interp.setResult(list2);
                break;
            }
            return(TCL.CompletionCode.RETURN);
        }
Ejemplo n.º 18
0
        /// <summary>----------------------------------------------------------------------
        ///
        /// Tcl_StringObjCmd -> StringCmd.cmdProc
        ///
        /// This procedure is invoked to process the "string" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// Results:
        /// None.
        ///
        /// Side effects:
        /// See the user documentation.
        ///
        /// ----------------------------------------------------------------------
        /// </summary>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "option arg ?arg ...?");
            }
            int index = TclIndex.get(interp, objv[1], options, "option", 0);

            switch (index)
            {
            case STR_EQUAL:
            case STR_COMPARE:  {
                if (objv.Length < 4 || objv.Length > 7)
                {
                    throw new TclNumArgsException(interp, 2, objv, "?-nocase? ?-length int? string1 string2");
                }

                bool nocase    = false;
                int  reqlength = -1;
                for (int i = 2; i < objv.Length - 2; i++)
                {
                    string string2 = objv[i].ToString();
                    int    length2 = string2.Length;
                    if ((length2 > 1) && "-nocase".StartsWith(string2))
                    {
                        nocase = true;
                    }
                    else if ((length2 > 1) && "-length".StartsWith(string2))
                    {
                        if (i + 1 >= objv.Length - 2)
                        {
                            throw new TclNumArgsException(interp, 2, objv, "?-nocase? ?-length int? string1 string2");
                        }
                        reqlength = TclInteger.get(interp, objv[++i]);
                    }
                    else
                    {
                        throw new TclException(interp, "bad option \"" + string2 + "\": must be -nocase or -length");
                    }
                }


                string string1 = objv[objv.Length - 2].ToString();

                string string3 = objv[objv.Length - 1].ToString();
                int    length1 = string1.Length;
                int    length3 = string3.Length;

                // This is the min length IN BYTES of the two strings

                int length = (length1 < length3)?length1:length3;

                int match;

                if (reqlength == 0)
                {
                    // Anything matches at 0 chars, right?

                    match = 0;
                }
                else if (nocase || ((reqlength > 0) && (reqlength <= length)))
                {
                    // In Java, strings are always encoded in unicode, so we do
                    // not need to worry about individual char lengths

                    // Do the reqlength check again, against 0 as well for
                    // the benfit of nocase

                    if ((reqlength > 0) && (reqlength < length))
                    {
                        length = reqlength;
                    }
                    else if (reqlength < 0)
                    {
                        // The requested length is negative, so we ignore it by
                        // setting it to the longer of the two lengths.

                        reqlength = (length1 > length3)?length1:length3;
                    }
                    if (nocase)
                    {
                        string1 = string1.ToLower();
                        string3 = string3.ToLower();
                    }
                    match = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(string1, 0, length, string3, 0, length, System.Globalization.CompareOptions.Ordinal);
                    // match = string1.Substring(0, (length) - (0)).CompareTo(string3.Substring(0, (length) - (0)));

                    if ((match == 0) && (reqlength > length))
                    {
                        match = length1 - length3;
                    }
                }
                else
                {
                    match = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(string1, 0, length, string3, 0, length, System.Globalization.CompareOptions.Ordinal);
                    // ATK match = string1.Substring(0, (length) - (0)).CompareTo(string3.Substring(0, (length) - (0)));
                    if (match == 0)
                    {
                        match = length1 - length3;
                    }
                }

                if (index == STR_EQUAL)
                {
                    interp.setResult((match != 0)?false:true);
                }
                else
                {
                    interp.setResult(((match > 0)?1:(match < 0)?-1:0));
                }
                break;
            }


            case STR_FIRST:  {
                if (objv.Length < 4 || objv.Length > 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "subString string ?startIndex?");
                }

                string string1 = objv[2].ToString();

                string string2 = objv[3].ToString();
                int    length2 = string2.Length;

                int start = 0;

                if (objv.Length == 5)
                {
                    // If a startIndex is specified, we will need to fast
                    // forward to that point in the string before we think
                    // about a match.

                    start = Util.getIntForIndex(interp, objv[4], length2 - 1);
                    if (start >= length2)
                    {
                        interp.setResult(-1);
                        return(TCL.CompletionCode.RETURN);
                    }
                }

                if (string1.Length == 0)
                {
                    interp.setResult(-1);
                }
                else
                {
                    interp.setResult(string2.IndexOf(string1, start));
                }
                break;
            }


            case STR_INDEX:  {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "string charIndex");
                }


                string string1 = objv[2].ToString();
                int    length1 = string1.Length;

                int i = Util.getIntForIndex(interp, objv[3], length1 - 1);

                if ((i >= 0) && (i < length1))
                {
                    interp.setResult(string1.Substring(i, (i + 1) - (i)));
                }
                break;
            }


            case STR_IS:  {
                if (objv.Length < 4 || objv.Length > 7)
                {
                    throw new TclNumArgsException(interp, 2, objv, "class ?-strict? ?-failindex var? str");
                }
                index = TclIndex.get(interp, objv[2], isOptions, "class", 0);

                bool      strict     = false;
                TclObject failVarObj = null;

                if (objv.Length != 4)
                {
                    for (int i = 3; i < objv.Length - 1; i++)
                    {
                        string string2 = objv[i].ToString();
                        int    length2 = string2.Length;
                        if ((length2 > 1) && "-strict".StartsWith(string2))
                        {
                            strict = true;
                        }
                        else if ((length2 > 1) && "-failindex".StartsWith(string2))
                        {
                            if (i + 1 >= objv.Length - 1)
                            {
                                throw new TclNumArgsException(interp, 3, objv, "?-strict? ?-failindex var? str");
                            }
                            failVarObj = objv[++i];
                        }
                        else
                        {
                            throw new TclException(interp, "bad option \"" + string2 + "\": must be -strict or -failindex");
                        }
                    }
                }

                bool result = true;
                int  failat = 0;

                // We get the objPtr so that we can short-cut for some classes
                // by checking the object type (int and double), but we need
                // the string otherwise, because we don't want any conversion
                // of type occuring (as, for example, Tcl_Get*FromObj would do

                TclObject obj = objv[objv.Length - 1];

                string string1 = obj.ToString();
                int    length1 = string1.Length;
                if (length1 == 0)
                {
                    if (strict)
                    {
                        result = false;
                    }
                }

                switch (index)
                {
                case STR_IS_BOOL:
                case STR_IS_TRUE:
                case STR_IS_FALSE:  {
                    if (obj.InternalRep is TclBoolean)
                    {
                        if (((index == STR_IS_TRUE) && !TclBoolean.get(interp, obj)) || ((index == STR_IS_FALSE) && TclBoolean.get(interp, obj)))
                        {
                            result = false;
                        }
                    }
                    else
                    {
                        try
                        {
                            bool i = TclBoolean.get(null, obj);
                            if (((index == STR_IS_TRUE) && !i) || ((index == STR_IS_FALSE) && i))
                            {
                                result = false;
                            }
                        }
                        catch (TclException e)
                        {
                            result = false;
                        }
                    }
                    break;
                }

                case STR_IS_DOUBLE:  {
                    if ((obj.InternalRep is TclDouble) || (obj.InternalRep is TclInteger))
                    {
                        break;
                    }

                    // This is adapted from Tcl_GetDouble
                    //
                    // The danger in this function is that
                    // "12345678901234567890" is an acceptable 'double',
                    // but will later be interp'd as an int by something
                    // like [expr].  Therefore, we check to see if it looks
                    // like an int, and if so we do a range check on it.
                    // If strtoul gets to the end, we know we either
                    // received an acceptable int, or over/underflow

                    if (Expression.looksLikeInt(string1, length1, 0))
                    {
                        char          c      = string1[0];
                        int           signIx = (c == '-' || c == '+')?1:0;
                        StrtoulResult res    = Util.strtoul(string1, signIx, 0);
                        if (res.index == length1)
                        {
                            if (res.errno == TCL.INTEGER_RANGE)
                            {
                                result = false;
                                failat = -1;
                            }
                            break;
                        }
                    }

                    char         c2      = string1[0];
                    int          signIx2 = (c2 == '-' || c2 == '+')?1:0;
                    StrtodResult res2    = Util.strtod(string1, signIx2);
                    if (res2.errno == TCL.DOUBLE_RANGE)
                    {
                        // if (errno == ERANGE), then it was an over/underflow
                        // problem, but in this method, we only want to know
                        // yes or no, so bad flow returns 0 (false) and sets
                        // the failVarObj to the string length.

                        result = false;
                        failat = -1;
                    }
                    else if (res2.index == 0)
                    {
                        // In this case, nothing like a number was found

                        result = false;
                        failat = 0;
                    }
                    else
                    {
                        // Go onto SPACE, since we are
                        // allowed trailing whitespace

                        failat = res2.index;
                        for (int i = res2.index; i < length1; i++)
                        {
                            if (!System.Char.IsWhiteSpace(string1[i]))
                            {
                                result = false;
                                break;
                            }
                        }
                    }
                    break;
                }

                case STR_IS_INT:  {
                    if (obj.InternalRep is TclInteger)
                    {
                        break;
                    }
                    bool isInteger = true;
                    try
                    {
                        TclInteger.get(null, obj);
                    }
                    catch (TclException e)
                    {
                        isInteger = false;
                    }
                    if (isInteger)
                    {
                        break;
                    }

                    char          c      = string1[0];
                    int           signIx = (c == '-' || c == '+')?1:0;
                    StrtoulResult res    = Util.strtoul(string1, signIx, 0);
                    if (res.errno == TCL.INTEGER_RANGE)
                    {
                        // if (errno == ERANGE), then it was an over/underflow
                        // problem, but in this method, we only want to know
                        // yes or no, so bad flow returns false and sets
                        // the failVarObj to the string length.

                        result = false;
                        failat = -1;
                    }
                    else if (res.index == 0)
                    {
                        // In this case, nothing like a number was found

                        result = false;
                        failat = 0;
                    }
                    else
                    {
                        // Go onto SPACE, since we are
                        // allowed trailing whitespace

                        failat = res.index;
                        for (int i = res.index; i < length1; i++)
                        {
                            if (!System.Char.IsWhiteSpace(string1[i]))
                            {
                                result = false;
                                break;
                            }
                        }
                    }
                    break;
                }

                default:  {
                    for (failat = 0; failat < length1; failat++)
                    {
                        char c = string1[failat];
                        switch (index)
                        {
                        case STR_IS_ASCII:

                            result = c < 0x80;
                            break;

                        case STR_IS_ALNUM:
                            result = System.Char.IsLetterOrDigit(c);
                            break;

                        case STR_IS_ALPHA:
                            result = System.Char.IsLetter(c);
                            break;

                        case STR_IS_DIGIT:
                            result = System.Char.IsDigit(c);
                            break;

                        case STR_IS_GRAPH:
                            result = ((1 << (int)System.Char.GetUnicodeCategory(c)) & PRINT_BITS) != 0 && c != ' ';
                            break;

                        case STR_IS_PRINT:
                            result = ((1 << (int)System.Char.GetUnicodeCategory(c)) & PRINT_BITS) != 0;
                            break;

                        case STR_IS_PUNCT:
                            result = ((1 << (int)System.Char.GetUnicodeCategory(c)) & PUNCT_BITS) != 0;
                            break;

                        case STR_IS_UPPER:
                            result = System.Char.IsUpper(c);
                            break;

                        case STR_IS_SPACE:
                            result = System.Char.IsWhiteSpace(c);
                            break;

                        case STR_IS_CONTROL:
                            result = (System.Char.GetUnicodeCategory(c) == System.Globalization.UnicodeCategory.Control);
                            break;

                        case STR_IS_LOWER:
                            result = System.Char.IsLower(c);
                            break;

                        case STR_IS_WORD:
                            result = ((1 << (int)System.Char.GetUnicodeCategory(c)) & WORD_BITS) != 0;
                            break;

                        case STR_IS_XDIGIT:
                            result = "0123456789ABCDEFabcdef".IndexOf(c) >= 0;
                            break;

                        default:
                            throw new TclRuntimeError("unimplemented");
                        }
                        if (!result)
                        {
                            break;
                        }
                    }
                }
                break;
                }

                // Only set the failVarObj when we will return 0
                // and we have indicated a valid fail index (>= 0)

                if ((!result) && (failVarObj != null))
                {
                    interp.setVar(failVarObj, TclInteger.newInstance(failat), 0);
                }
                interp.setResult(result);
                break;
            }


            case STR_LAST:  {
                if (objv.Length < 4 || objv.Length > 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "subString string ?startIndex?");
                }

                string string1 = objv[2].ToString();

                string string2 = objv[3].ToString();
                int    length2 = string2.Length;

                int start = 0;
                if (objv.Length == 5)
                {
                    // If a startIndex is specified, we will need to fast
                    // forward to that point in the string before we think
                    // about a match.

                    start = Util.getIntForIndex(interp, objv[4], length2 - 1);
                    if (start < 0)
                    {
                        interp.setResult(-1);
                        break;
                    }
                    else if (start < length2)
                    {
                        string2 = string2.Substring(0, (start + 1) - (0));
                    }
                }

                if (string1.Length == 0)
                {
                    interp.setResult(-1);
                }
                else
                {
                    interp.setResult(string2.LastIndexOf(string1));
                }
                break;
            }


            case STR_BYTELENGTH:
                if (objv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "string");
                }

                interp.setResult(Utf8Count(objv[2].ToString()));
                break;


            case STR_LENGTH:  {
                if (objv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "string");
                }

                interp.setResult(objv[2].ToString().Length);
                break;
            }


            case STR_MAP:  {
                if (objv.Length < 4 || objv.Length > 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "?-nocase? charMap string");
                }

                bool nocase = false;
                if (objv.Length == 5)
                {
                    string string2 = objv[2].ToString();
                    int    length2 = string2.Length;
                    if ((length2 > 1) && "-nocase".StartsWith(string2))
                    {
                        nocase = true;
                    }
                    else
                    {
                        throw new TclException(interp, "bad option \"" + string2 + "\": must be -nocase");
                    }
                }

                TclObject[] mapElemv = TclList.getElements(interp, objv[objv.Length - 2]);
                if (mapElemv.Length == 0)
                {
                    // empty charMap, just return whatever string was given

                    interp.setResult(objv[objv.Length - 1]);
                }
                else if ((mapElemv.Length % 2) != 0)
                {
                    // The charMap must be an even number of key/value items

                    throw new TclException(interp, "char map list unbalanced");
                }

                string string1 = objv[objv.Length - 1].ToString();
                string cmpString1;
                if (nocase)
                {
                    cmpString1 = string1.ToLower();
                }
                else
                {
                    cmpString1 = string1;
                }
                int length1 = string1.Length;
                if (length1 == 0)
                {
                    // Empty input string, just stop now

                    break;
                }

                // Precompute pointers to the unicode string and length.
                // This saves us repeated function calls later,
                // significantly speeding up the algorithm.

                string[] mapStrings = new string[mapElemv.Length];
                int[]    mapLens    = new int[mapElemv.Length];
                for (int ix = 0; ix < mapElemv.Length; ix++)
                {
                    mapStrings[ix] = mapElemv[ix].ToString();
                    mapLens[ix]    = mapStrings[ix].Length;
                }
                string[] cmpStrings;
                if (nocase)
                {
                    cmpStrings = new string[mapStrings.Length];
                    for (int ix = 0; ix < mapStrings.Length; ix++)
                    {
                        cmpStrings[ix] = mapStrings[ix].ToLower();
                    }
                }
                else
                {
                    cmpStrings = mapStrings;
                }

                TclObject result = TclString.newInstance("");
                int       p, str1;
                for (p = 0, str1 = 0; str1 < length1; str1++)
                {
                    for (index = 0; index < mapStrings.Length; index += 2)
                    {
                        // Get the key string to match on

                        string string2 = mapStrings[index];
                        int    length2 = mapLens[index];
                        if ((length2 > 0) && (cmpString1.Substring(str1).StartsWith(cmpStrings[index])))
                        {
                            if (p != str1)
                            {
                                // Put the skipped chars onto the result first

                                TclString.append(result, string1.Substring(p, (str1) - (p)));
                                p = str1 + length2;
                            }
                            else
                            {
                                p += length2;
                            }

                            // Adjust len to be full length of matched string

                            str1 = p - 1;

                            // Append the map value to the unicode string

                            TclString.append(result, mapStrings[index + 1]);
                            break;
                        }
                    }
                }

                if (p != str1)
                {
                    // Put the rest of the unmapped chars onto result

                    TclString.append(result, string1.Substring(p, (str1) - (p)));
                }
                interp.setResult(result);
                break;
            }


            case STR_MATCH:  {
                if (objv.Length < 4 || objv.Length > 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "?-nocase? pattern string");
                }

                string string1, string2;
                if (objv.Length == 5)
                {
                    string inString = objv[2].ToString();
                    if (!((inString.Length > 1) && "-nocase".StartsWith(inString)))
                    {
                        throw new TclException(interp, "bad option \"" + inString + "\": must be -nocase");
                    }

                    string1 = objv[4].ToString().ToLower();

                    string2 = objv[3].ToString().ToLower();
                }
                else
                {
                    string1 = objv[3].ToString();

                    string2 = objv[2].ToString();
                }

                interp.setResult(Util.stringMatch(string1, string2));
                break;
            }


            case STR_RANGE:  {
                if (objv.Length != 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "string first last");
                }


                string string1 = objv[2].ToString();
                int    length1 = string1.Length;

                int first = Util.getIntForIndex(interp, objv[3], length1 - 1);
                if (first < 0)
                {
                    first = 0;
                }
                int last = Util.getIntForIndex(interp, objv[4], length1 - 1);
                if (last >= length1)
                {
                    last = length1 - 1;
                }

                if (first > last)
                {
                    interp.resetResult();
                }
                else
                {
                    interp.setResult(string1.Substring(first, (last + 1) - (first)));
                }
                break;
            }


            case STR_REPEAT:  {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "string count");
                }

                int count = TclInteger.get(interp, objv[3]);


                string string1 = objv[2].ToString();
                if (string1.Length > 0)
                {
                    TclObject tstr = TclString.newInstance("");
                    for (index = 0; index < count; index++)
                    {
                        TclString.append(tstr, string1);
                    }
                    interp.setResult(tstr);
                }
                break;
            }


            case STR_REPLACE:  {
                if (objv.Length < 5 || objv.Length > 6)
                {
                    throw new TclNumArgsException(interp, 2, objv, "string first last ?string?");
                }


                string string1 = objv[2].ToString();
                int    length1 = string1.Length - 1;

                int first = Util.getIntForIndex(interp, objv[3], length1);
                int last  = Util.getIntForIndex(interp, objv[4], length1);

                if ((last < first) || (first > length1) || (last < 0))
                {
                    interp.setResult(objv[2]);
                }
                else
                {
                    if (first < 0)
                    {
                        first = 0;
                    }
                    string start = string1.Substring(first);
                    int    ind   = ((last > length1)?length1:last) - first + 1;
                    string end;
                    if (ind <= 0)
                    {
                        end = start;
                    }
                    else if (ind >= start.Length)
                    {
                        end = "";
                    }
                    else
                    {
                        end = start.Substring(ind);
                    }

                    TclObject tstr = TclString.newInstance(string1.Substring(0, (first) - (0)));

                    if (objv.Length == 6)
                    {
                        TclString.append(tstr, objv[5]);
                    }
                    if (last < length1)
                    {
                        TclString.append(tstr, end);
                    }

                    interp.setResult(tstr);
                }
                break;
            }


            case STR_TOLOWER:
            case STR_TOUPPER:
            case STR_TOTITLE:  {
                if (objv.Length < 3 || objv.Length > 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "string ?first? ?last?");
                }

                string string1 = objv[2].ToString();

                if (objv.Length == 3)
                {
                    if (index == STR_TOLOWER)
                    {
                        interp.setResult(string1.ToLower());
                    }
                    else if (index == STR_TOUPPER)
                    {
                        interp.setResult(string1.ToUpper());
                    }
                    else
                    {
                        interp.setResult(Util.toTitle(string1));
                    }
                }
                else
                {
                    int length1 = string1.Length - 1;
                    int first   = Util.getIntForIndex(interp, objv[3], length1);
                    if (first < 0)
                    {
                        first = 0;
                    }
                    int last = first;
                    if (objv.Length == 5)
                    {
                        last = Util.getIntForIndex(interp, objv[4], length1);
                    }
                    if (last >= length1)
                    {
                        last = length1;
                    }
                    if (last < first)
                    {
                        interp.setResult(objv[2]);
                        break;
                    }

                    string string2;
                    System.Text.StringBuilder buf = new System.Text.StringBuilder();
                    buf.Append(string1.Substring(0, (first) - (0)));
                    if (last + 1 > length1)
                    {
                        string2 = string1.Substring(first);
                    }
                    else
                    {
                        string2 = string1.Substring(first, (last + 1) - (first));
                    }
                    if (index == STR_TOLOWER)
                    {
                        buf.Append(string2.ToLower());
                    }
                    else if (index == STR_TOUPPER)
                    {
                        buf.Append(string2.ToUpper());
                    }
                    else
                    {
                        buf.Append(Util.toTitle(string2));
                    }
                    if (last + 1 <= length1)
                    {
                        buf.Append(string1.Substring(last + 1));
                    }

                    interp.setResult(buf.ToString());
                }
                break;
            }


            case STR_TRIM:  {
                if (objv.Length == 3)
                {
                    // Case 1: "string trim str" --
                    // Remove leading and trailing white space


                    interp.setResult(objv[2].ToString().Trim());
                }
                else if (objv.Length == 4)
                {
                    // Case 2: "string trim str chars" --
                    // Remove leading and trailing chars in the chars set


                    string tmp = Util.TrimLeft(objv[2].ToString(), objv[3].ToString());

                    interp.setResult(Util.TrimRight(tmp, objv[3].ToString()));
                }
                else
                {
                    // Case 3: Wrong # of args

                    throw new TclNumArgsException(interp, 2, objv, "string ?chars?");
                }
                break;
            }


            case STR_TRIMLEFT:  {
                if (objv.Length == 3)
                {
                    // Case 1: "string trimleft str" --
                    // Remove leading and trailing white space


                    interp.setResult(Util.TrimLeft(objv[2].ToString()));
                }
                else if (objv.Length == 4)
                {
                    // Case 2: "string trimleft str chars" --
                    // Remove leading and trailing chars in the chars set


                    interp.setResult(Util.TrimLeft(objv[2].ToString(), objv[3].ToString()));
                }
                else
                {
                    // Case 3: Wrong # of args

                    throw new TclNumArgsException(interp, 2, objv, "string ?chars?");
                }
                break;
            }


            case STR_TRIMRIGHT:  {
                if (objv.Length == 3)
                {
                    // Case 1: "string trimright str" --
                    // Remove leading and trailing white space


                    interp.setResult(Util.TrimRight(objv[2].ToString()));
                }
                else if (objv.Length == 4)
                {
                    // Case 2: "string trimright str chars" --
                    // Remove leading and trailing chars in the chars set


                    interp.setResult(Util.TrimRight(objv[2].ToString(), objv[3].ToString()));
                }
                else
                {
                    // Case 3: Wrong # of args

                    throw new TclNumArgsException(interp, 2, objv, "string ?chars?");
                }
                break;
            }


            case STR_WORDEND:  {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "string index");
                }


                string string1  = objv[2].ToString();
                char[] strArray = string1.ToCharArray();
                int    cur;
                int    length1 = string1.Length;
                index = Util.getIntForIndex(interp, objv[3], length1 - 1);

                if (index < 0)
                {
                    index = 0;
                }
                if (index >= length1)
                {
                    interp.setResult(length1);
                    return(TCL.CompletionCode.RETURN);
                }
                for (cur = index; cur < length1; cur++)
                {
                    char c = strArray[cur];
                    if (((1 << (int)System.Char.GetUnicodeCategory(c)) & WORD_BITS) == 0)
                    {
                        break;
                    }
                }
                if (cur == index)
                {
                    cur = index + 1;
                }
                interp.setResult(cur);
                break;
            }


            case STR_WORDSTART:  {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "string index");
                }


                string string1  = objv[2].ToString();
                char[] strArray = string1.ToCharArray();
                int    cur;
                int    length1 = string1.Length;
                index = Util.getIntForIndex(interp, objv[3], length1 - 1);

                if (index > length1)
                {
                    index = length1 - 1;
                }
                if (index < 0)
                {
                    interp.setResult(0);
                    return(TCL.CompletionCode.RETURN);
                }
                for (cur = index; cur >= 0; cur--)
                {
                    char c = strArray[cur];
                    if (((1 << (int)System.Char.GetUnicodeCategory(c)) & WORD_BITS) == 0)
                    {
                        break;
                    }
                }
                if (cur != index)
                {
                    cur += 1;
                }
                interp.setResult(cur);
                break;
            }
            }
            return(TCL.CompletionCode.RETURN);
        }
Ejemplo n.º 19
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);
        }
Ejemplo n.º 20
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);
        }
Ejemplo n.º 21
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 System.Text.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 (System.IO.IOException e)
            {
                throw new TclRuntimeError("ReadCmd.cmdProc() Error: IOException when reading " + chan.ChanName);
            }
            return(TCL.CompletionCode.RETURN);
        }
Ejemplo n.º 22
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:
                System.Text.StringBuilder sbuf = new System.Text.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);
            }
        }