Пример #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);
        }
Пример #2
0
 public static bool Tcl_GetIndexFromObj(Interp interp, TclObject to, string[] table, string msg, int flags, out int index)
 {
     try
     {
         index = TclIndex.get(interp, to, table, msg, flags);
         return(false);
     }
     catch
     {
         index = 0;
         return(true);
     }
 }
Пример #3
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            int flags;

            if (argv.Length == 1)
            {
                flags = TCL.ALL_EVENTS | TCL.DONT_WAIT;
            }
            else if (argv.Length == 2)
            {
                TclIndex.get(interp, argv[1], validOpts, "option", 0);

                /*
                 * Since we just have one valid option, if the above call returns
                 * without an exception, we've got "idletasks" (or abreviations).
                 */

                flags = TCL.IDLE_EVENTS | TCL.DONT_WAIT;
            }
            else
            {
                throw new TclNumArgsException(interp, 1, argv, "?idletasks?");
            }

            while (interp.getNotifier().doOneEvent(flags) != 0)
            {
                /* Empty loop body */
            }

            /*
             * Must clear the interpreter's result because event handlers could
             * have executed commands.
             */

            interp.resetResult();
            return(TCL.CompletionCode.RETURN);
        }
Пример #4
0
        private static void  fileDelete(Interp interp, TclObject[] argv)
        {
            bool force       = false;
            int  firstSource = 2;

            for (bool last = false; (firstSource < argv.Length) && (!last); firstSource++)
            {
                if (!argv[firstSource].ToString().StartsWith("-"))
                {
                    break;
                }
                int opt = TclIndex.get(interp, argv[firstSource], validOptions, "option", 1);
                switch (opt)
                {
                case OPT_FORCE:
                    force = true;
                    break;

                case OPT_LAST:
                    last = true;
                    break;

                default:
                    throw new TclRuntimeError("FileCmd.cmdProc: bad option " + opt + " index to validOptions");
                }
            }

            if (firstSource >= argv.Length)
            {
                throw new TclNumArgsException(interp, 2, argv, "?options? file ?file ...?");
            }

            for (int i = firstSource; i < argv.Length; i++)
            {
                deleteOneFile(interp, argv[i].ToString(), force);
            }
        }
Пример #5
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            int len;

            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "option [arg arg ...]");
            }
            int opt = TclIndex.get(interp, objv[1], validCmds, "option", 0);

            switch (opt)
            {
            case OPT_VARIABLE:
            case OPT_VDELETE:
                if (objv.Length != 5)
                {
                    if (opt == OPT_VARIABLE)
                    {
                        throw new TclNumArgsException(interp, 1, objv, "variable name ops command");
                    }
                    else
                    {
                        throw new TclNumArgsException(interp, 1, objv, "vdelete name ops command");
                    }
                }

                TCL.VarFlag flags = 0;

                string ops = objv[3].ToString();
                len = ops.Length;
                {
                    for (int i = 0; i < len; i++)
                    {
                        switch (ops[i])
                        {
                        case 'r':
                            flags |= TCL.VarFlag.TRACE_READS;
                            break;

                        case 'w':
                            flags |= TCL.VarFlag.TRACE_WRITES;
                            break;

                        case 'u':
                            flags |= TCL.VarFlag.TRACE_UNSETS;
                            break;

                        default:
                            flags = 0;
                            goto check_ops_brk;
                        }
                    }
                }

check_ops_brk:
                ;


                if (flags == 0)
                {
                    throw new TclException(interp, "bad operations \"" + objv[3] + "\": should be one or more of rwu");
                }

                if (opt == OPT_VARIABLE)
                {
                    CmdTraceProc trace = new CmdTraceProc(objv[4].ToString(), flags);
                    Var.traceVar(interp, objv[2], flags, trace);
                }
                else
                {
                    // Search through all of our traces on this variable to
                    // see if there's one with the given command.  If so, then
                    // delete the first one that matches.


                    ArrayList traces = Var.getTraces(interp, objv[2].ToString(), 0);
                    if (traces != null)
                    {
                        len = traces.Count;
                        for (int i = 0; i < len; i++)
                        {
                            TraceRecord rec = (TraceRecord)traces[i];

                            if (rec.trace is CmdTraceProc)
                            {
                                CmdTraceProc proc = (CmdTraceProc)rec.trace;

                                if (proc.flags == flags && proc.command.ToString().Equals(objv[4].ToString()))
                                {
                                    Var.untraceVar(interp, objv[2], flags, proc);
                                    break;
                                }
                            }
                        }
                    }
                }
                break;


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

                ArrayList traces2 = Var.getTraces(interp, objv[2].ToString(), 0);
                if (traces2 != null)
                {
                    len = traces2.Count;
                    TclObject list = TclList.newInstance();
                    TclObject cmd  = null;
                    list.preserve();

                    try
                    {
                        for (int i = 0; i < len; i++)
                        {
                            TraceRecord rec = (TraceRecord)traces2[i];

                            if (rec.trace is CmdTraceProc)
                            {
                                CmdTraceProc proc = (CmdTraceProc)rec.trace;
                                TCL.VarFlag  mode = proc.flags;
                                mode &= (TCL.VarFlag.TRACE_READS | TCL.VarFlag.TRACE_WRITES | TCL.VarFlag.TRACE_UNSETS);
                                int modeInt = (int)mode;
                                modeInt /= ((int)TCL.VarFlag.TRACE_READS);

                                cmd = TclList.newInstance();
                                TclList.append(interp, cmd, opStr[modeInt]);
                                TclList.append(interp, cmd, TclString.newInstance(proc.command));
                                TclList.append(interp, list, cmd);
                            }
                        }
                        interp.setResult(list);
                    }
                    finally
                    {
                        list.release();
                    }
                }
                break;
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #6
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            int arg;                      // Index of next argument to consume.

            char[] format = null;         // User specified format string.
            char   cmd;                   // Current format character.
            int    cursor;                // Current position within result buffer.
            int    maxPos;                // Greatest position within result buffer that
            // cursor has visited.
            int value = 0;                // Current integer value to be packed.
            // Initialized to avoid compiler warning.
            int offset, size = 0, length; //, index;

            if (argv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "option ?arg arg ...?");
            }
            int cmdIndex = TclIndex.get(interp, argv[1], validCmds, "option", 0);

            switch (cmdIndex)
            {
            case CMD_FORMAT:
            {
                if (argv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "formatString ?arg arg ...?");
                }

                // To avoid copying the data, we format the string in two passes.
                // The first pass computes the size of the output buffer.  The
                // second pass places the formatted data into the buffer.

                format = argv[2].ToString().ToCharArray();
                arg    = 3;
                length = 0;
                offset = 0;
                System.Int32 parsePos = 0;

                while ((cmd = GetFormatSpec(format, ref parsePos)) != FORMAT_END)
                {
                    int count = GetFormatCount(format, ref parsePos);

                    switch (cmd)
                    {
                    case 'a':
                    case 'A':
                    case 'b':
                    case 'B':
                    case 'h':
                    case 'H':
                    {
                        // For string-type specifiers, the count corresponds
                        // to the number of bytes in a single argument.

                        if (arg >= argv.Length)
                        {
                            missingArg(interp);
                        }
                        if (count == BINARY_ALL)
                        {
                            count = TclByteArray.getLength(interp, argv[arg]);
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        arg++;
                        switch (cmd)
                        {
                        case 'a':
                        case 'A': offset += count; break;

                        case 'b':
                        case 'B': offset += (count + 7) / 8; break;

                        case 'h':
                        case 'H': offset += (count + 1) / 2; break;
                        }
                        break;
                    }

                    case 'c':
                    case 's':
                    case 'S':
                    case 'i':
                    case 'I':
                    case 'f':
                    case 'd':
                    {
                        if (arg >= argv.Length)
                        {
                            missingArg(interp);
                        }
                        switch (cmd)
                        {
                        case 'c': size = 1; break;

                        case 's':
                        case 'S': size = 2; break;

                        case 'i':
                        case 'I': size = 4; break;

                        case 'f': size = 4; break;

                        case 'd': size = 8; break;
                        }

                        // For number-type specifiers, the count corresponds
                        // to the number of elements in the list stored in
                        // a single argument.  If no count is specified, then
                        // the argument is taken as a single non-list value.

                        if (count == BINARY_NOCOUNT)
                        {
                            arg++;
                            count = 1;
                        }
                        else
                        {
                            int listc = TclList.getLength(interp, argv[arg++]);
                            if (count == BINARY_ALL)
                            {
                                count = listc;
                            }
                            else if (count > listc)
                            {
                                throw new TclException(interp, "number of elements in list" + " does not match count");
                            }
                        }
                        offset += count * size;
                        break;
                    }

                    case 'x':
                    {
                        if (count == BINARY_ALL)
                        {
                            throw new TclException(interp, "cannot use \"*\"" + " in format string with \"x\"");
                        }
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        offset += count;
                        break;
                    }

                    case 'X':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if ((count > offset) || (count == BINARY_ALL))
                        {
                            count = offset;
                        }
                        if (offset > length)
                        {
                            length = offset;
                        }
                        offset -= count;
                        break;
                    }

                    case '@':
                    {
                        if (offset > length)
                        {
                            length = offset;
                        }
                        if (count == BINARY_ALL)
                        {
                            offset = length;
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            alephWithoutCount(interp);
                        }
                        else
                        {
                            offset = count;
                        }
                        break;
                    }

                    default:
                    {
                        badField(interp, cmd);
                    }
                    break;
                    }
                }
                if (offset > length)
                {
                    length = offset;
                }
                if (length == 0)
                {
                    return(TCL.CompletionCode.RETURN);
                }

                // Prepare the result object by preallocating the calculated
                // number of bytes and filling with nulls.

                TclObject resultObj = TclByteArray.newInstance();
                resultObj._typePtr = "bytearray";
                byte[] resultBytes = TclByteArray.setLength(interp, resultObj, length);
                interp.setResult(resultObj);

                // Pack the data into the result object.  Note that we can skip
                // the error checking during this pass, since we have already
                // parsed the string once.

                arg      = 3;
                cursor   = 0;
                maxPos   = cursor;
                parsePos = 0;

                while ((cmd = GetFormatSpec(format, ref parsePos)) != FORMAT_END)
                {
                    int count = GetFormatCount(format, ref parsePos);

                    if ((count == 0) && (cmd != '@'))
                    {
                        arg++;
                        continue;
                    }

                    switch (cmd)
                    {
                    case 'a':
                    case 'A':
                    {
                        byte   pad   = (cmd == 'a') ? (byte)0 : (byte)SupportClass.Identity(' ');
                        byte[] bytes = TclByteArray.getBytes(interp, argv[arg++]);
                        length = bytes.Length;

                        if (count == BINARY_ALL)
                        {
                            count = length;
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if (length >= count)
                        {
                            Array.Copy(bytes, 0, resultBytes, cursor, count);
                        }
                        else
                        {
                            Array.Copy(bytes, 0, resultBytes, cursor, length);
                            for (int ix = 0; ix < count - length; ix++)
                            {
                                resultBytes[cursor + length + ix] = pad;
                            }
                        }
                        cursor += count;
                        break;
                    }

                    case 'b':
                    case 'B':
                    {
                        char[] str = argv[arg++].ToString().ToCharArray();
                        if (count == BINARY_ALL)
                        {
                            count = str.Length;
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        int last = cursor + ((count + 7) / 8);
                        if (count > str.Length)
                        {
                            count = str.Length;
                        }
                        if (cmd == 'B')
                        {
                            for (offset = 0; offset < count; offset++)
                            {
                                value <<= 1;
                                if (str[offset] == '1')
                                {
                                    value |= 1;
                                }
                                else if (str[offset] != '0')
                                {
                                    expectedButGot(interp, "binary", new string( str ));
                                }
                                if (((offset + 1) % 8) == 0)
                                {
                                    resultBytes[cursor++] = (byte)value;
                                    value = 0;
                                }
                            }
                        }
                        else
                        {
                            for (offset = 0; offset < count; offset++)
                            {
                                value >>= 1;
                                if (str[offset] == '1')
                                {
                                    value |= 128;
                                }
                                else if (str[offset] != '0')
                                {
                                    expectedButGot(interp, "binary", new string( str ));
                                }
                                if (((offset + 1) % 8) == 0)
                                {
                                    resultBytes[cursor++] = (byte)value;
                                    value = 0;
                                }
                            }
                        }
                        if ((offset % 8) != 0)
                        {
                            if (cmd == 'B')
                            {
                                value <<= 8 - (offset % 8);
                            }
                            else
                            {
                                value >>= 8 - (offset % 8);
                            }
                            resultBytes[cursor++] = (byte)value;
                        }
                        while (cursor < last)
                        {
                            resultBytes[cursor++] = 0;
                        }
                        break;
                    }

                    case 'h':
                    case 'H':
                    {
                        char[] str = argv[arg++].ToString().ToCharArray();
                        if (count == BINARY_ALL)
                        {
                            count = str.Length;
                        }
                        else if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        int last = cursor + ((count + 1) / 2);
                        if (count > str.Length)
                        {
                            count = str.Length;
                        }
                        if (cmd == 'H')
                        {
                            for (offset = 0; offset < count; offset++)
                            {
                                value <<= 4;
                                int c = HEXDIGITS.IndexOf(Char.ToLower(str[offset]));
                                if (c < 0)
                                {
                                    expectedButGot(interp, "hexadecimal", new string( str ));
                                }
                                value |= (c & 0xf);
                                if ((offset % 2) != 0)
                                {
                                    resultBytes[cursor++] = (byte)value;
                                    value = 0;
                                }
                            }
                        }
                        else
                        {
                            for (offset = 0; offset < count; offset++)
                            {
                                value >>= 4;
                                int c = HEXDIGITS.IndexOf(Char.ToLower(str[offset]));
                                if (c < 0)
                                {
                                    expectedButGot(interp, "hexadecimal", new string( str ));
                                }
                                value |= ((c << 4) & 0xf0);
                                if ((offset % 2) != 0)
                                {
                                    resultBytes[cursor++] = (byte)value;
                                    value = 0;
                                }
                            }
                        }
                        if ((offset % 2) != 0)
                        {
                            if (cmd == 'H')
                            {
                                value <<= 4;
                            }
                            else
                            {
                                value >>= 4;
                            }
                            resultBytes[cursor++] = (byte)value;
                        }
                        while (cursor < last)
                        {
                            resultBytes[cursor++] = 0;
                        }
                        break;
                    }

                    case 'c':
                    case 's':
                    case 'S':
                    case 'i':
                    case 'I':
                    case 'f':
                    case 'd':
                    {
                        TclObject[] listv;

                        if (count == BINARY_NOCOUNT)
                        {
                            listv    = new TclObject[1];
                            listv[0] = argv[arg++];
                            count    = 1;
                        }
                        else
                        {
                            listv = TclList.getElements(interp, argv[arg++]);
                            if (count == BINARY_ALL)
                            {
                                count = listv.Length;
                            }
                        }
                        for (int ix = 0; ix < count; ix++)
                        {
                            cursor = FormatNumber(interp, cmd, listv[ix], resultBytes, cursor);
                        }
                        break;
                    }

                    case 'x':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        for (int ix = 0; ix < count; ix++)
                        {
                            resultBytes[cursor++] = 0;
                        }
                        break;
                    }

                    case 'X':
                    {
                        if (cursor > maxPos)
                        {
                            maxPos = cursor;
                        }
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if (count == BINARY_ALL || count > cursor)
                        {
                            cursor = 0;
                        }
                        else
                        {
                            cursor -= count;
                        }
                        break;
                    }

                    case '@':
                    {
                        if (cursor > maxPos)
                        {
                            maxPos = cursor;
                        }
                        if (count == BINARY_ALL)
                        {
                            cursor = maxPos;
                        }
                        else
                        {
                            cursor = count;
                        }
                        break;
                    }
                    }
                }
                break;
            }

            case CMD_SCAN:
            {
                if (argv.Length < 4)
                {
                    throw new TclNumArgsException(interp, 2, argv, "value formatString ?varName varName ...?");
                }
                byte[] src = TclByteArray.getBytes(interp, argv[2]);
                length = src.Length;
                format = argv[3].ToString().ToCharArray();
                arg    = 4;
                cursor = 0;
                offset = 0;
                System.Int32 parsePos = 0;

                while ((cmd = GetFormatSpec(format, ref parsePos)) != FORMAT_END)
                {
                    int count = GetFormatCount(format, ref parsePos);

                    switch (cmd)
                    {
                    case 'a':
                    case 'A':
                    {
                        if (arg >= argv.Length)
                        {
                            missingArg(interp);
                        }
                        if (count == BINARY_ALL)
                        {
                            count = length - offset;
                        }
                        else
                        {
                            if (count == BINARY_NOCOUNT)
                            {
                                count = 1;
                            }
                            if (count > length - offset)
                            {
                                break;
                            }
                        }

                        size = count;

                        // Trim trailing nulls and spaces, if necessary.

                        if (cmd == 'A')
                        {
                            while (size > 0)
                            {
                                if (src[offset + size - 1] != '\x0000' && src[offset + size - 1] != ' ')
                                {
                                    break;
                                }
                                size--;
                            }
                        }

                        interp.setVar(argv[arg++], TclByteArray.newInstance(src, offset, size), 0);

                        offset += count;
                        break;
                    }

                    case 'b':
                    case 'B':
                    {
                        if (arg >= argv.Length)
                        {
                            missingArg(interp);
                        }
                        if (count == BINARY_ALL)
                        {
                            count = (length - offset) * 8;
                        }
                        else
                        {
                            if (count == BINARY_NOCOUNT)
                            {
                                count = 1;
                            }
                            if (count > (length - offset) * 8)
                            {
                                break;
                            }
                        }
                        System.Text.StringBuilder s = new System.Text.StringBuilder(count);
                        int thisOffset = offset;

                        if (cmd == 'b')
                        {
                            for (int ix = 0; ix < count; ix++)
                            {
                                if ((ix % 8) != 0)
                                {
                                    value >>= 1;
                                }
                                else
                                {
                                    value = src[thisOffset++];
                                }
                                s.Append((value & 1) != 0 ? '1' : '0');
                            }
                        }
                        else
                        {
                            for (int ix = 0; ix < count; ix++)
                            {
                                if ((ix % 8) != 0)
                                {
                                    value <<= 1;
                                }
                                else
                                {
                                    value = src[thisOffset++];
                                }
                                s.Append((value & 0x80) != 0 ? '1' : '0');
                            }
                        }

                        interp.setVar(argv[arg++], TclString.newInstance(s.ToString()), 0);

                        offset += (count + 7) / 8;
                        break;
                    }

                    case 'h':
                    case 'H':
                    {
                        if (arg >= argv.Length)
                        {
                            missingArg(interp);
                        }
                        if (count == BINARY_ALL)
                        {
                            count = (length - offset) * 2;
                        }
                        else
                        {
                            if (count == BINARY_NOCOUNT)
                            {
                                count = 1;
                            }
                            if (count > (length - offset) * 2)
                            {
                                break;
                            }
                        }
                        System.Text.StringBuilder s = new System.Text.StringBuilder(count);
                        int thisOffset = offset;

                        if (cmd == 'h')
                        {
                            for (int ix = 0; ix < count; ix++)
                            {
                                if ((ix % 2) != 0)
                                {
                                    value >>= 4;
                                }
                                else
                                {
                                    value = src[thisOffset++];
                                }
                                s.Append(HEXDIGITS[value & 0xf]);
                            }
                        }
                        else
                        {
                            for (int ix = 0; ix < count; ix++)
                            {
                                if ((ix % 2) != 0)
                                {
                                    value <<= 4;
                                }
                                else
                                {
                                    value = src[thisOffset++];
                                }
                                s.Append(HEXDIGITS[value >> 4 & 0xf]);
                            }
                        }

                        interp.setVar(argv[arg++], TclString.newInstance(s.ToString()), 0);

                        offset += (count + 1) / 2;
                        break;
                    }

                    case 'c':
                    case 's':
                    case 'S':
                    case 'i':
                    case 'I':
                    case 'f':
                    case 'd':
                    {
                        if (arg >= argv.Length)
                        {
                            missingArg(interp);
                        }
                        switch (cmd)
                        {
                        case 'c': size = 1; break;

                        case 's':
                        case 'S': size = 2; break;

                        case 'i':
                        case 'I': size = 4; break;

                        case 'f': size = 4; break;

                        case 'd': size = 8; break;
                        }
                        TclObject valueObj;
                        if (count == BINARY_NOCOUNT)
                        {
                            if (length - offset < size)
                            {
                                break;
                            }
                            valueObj = ScanNumber(src, offset, cmd);
                            offset  += size;
                        }
                        else
                        {
                            if (count == BINARY_ALL)
                            {
                                count = (length - offset) / size;
                            }
                            if (length - offset < count * size)
                            {
                                break;
                            }
                            valueObj = TclList.newInstance();
                            int thisOffset = offset;
                            for (int ix = 0; ix < count; ix++)
                            {
                                TclList.append(null, valueObj, ScanNumber(src, thisOffset, cmd));
                                thisOffset += size;
                            }
                            offset += count * size;
                        }

                        interp.setVar(argv[arg++], valueObj, 0);

                        break;
                    }

                    case 'x':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if (count == BINARY_ALL || count > length - offset)
                        {
                            offset = length;
                        }
                        else
                        {
                            offset += count;
                        }
                        break;
                    }

                    case 'X':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            count = 1;
                        }
                        if (count == BINARY_ALL || count > offset)
                        {
                            offset = 0;
                        }
                        else
                        {
                            offset -= count;
                        }
                        break;
                    }

                    case '@':
                    {
                        if (count == BINARY_NOCOUNT)
                        {
                            alephWithoutCount(interp);
                        }
                        if (count == BINARY_ALL || count > length)
                        {
                            offset = length;
                        }
                        else
                        {
                            offset = count;
                        }
                        break;
                    }

                    default:
                    {
                        badField(interp, cmd);
                    }
                    break;
                    }
                }

                // Set the result to the last position of the cursor.

                interp.setResult(arg - 4);
            }
            break;
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #7
0
        /// <summary> Tcl_InfoObjCmd -> InfoCmd.cmdProc
        ///
        /// This procedure is invoked to process the "info" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException if wrong # of args or invalid argument(s).
        /// </exception>
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            int index;

            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "option ?arg arg ...?");
            }
            index = TclIndex.get(interp, objv[1], validCmds, "option", 0);

            switch (index)
            {
            case OPT_ARGS:
                InfoArgsCmd(interp, objv);
                break;

            case OPT_BODY:
                InfoBodyCmd(interp, objv);
                break;

            case OPT_CMDCOUNT:
                InfoCmdCountCmd(interp, objv);
                break;

            case OPT_COMMANDS:
                InfoCommandsCmd(interp, objv);
                break;

            case OPT_COMPLETE:
                InfoCompleteCmd(interp, objv);
                break;

            case OPT_DEFAULT:
                InfoDefaultCmd(interp, objv);
                break;

            case OPT_EXISTS:
                InfoExistsCmd(interp, objv);
                break;

            case OPT_GLOBALS:
                InfoGlobalsCmd(interp, objv);
                break;

            case OPT_HOSTNAME:
                InfoHostnameCmd(interp, objv);
                break;

            case OPT_LEVEL:
                InfoLevelCmd(interp, objv);
                break;

            case OPT_LIBRARY:
                InfoLibraryCmd(interp, objv);
                break;

            case OPT_LOADED:
                InfoLoadedCmd(interp, objv);
                break;

            case OPT_LOCALS:
                InfoLocalsCmd(interp, objv);
                break;

            case OPT_NAMEOFEXECUTABLE:
                InfoNameOfExecutableCmd(interp, objv);
                break;

            case OPT_PATCHLEVEL:
                InfoPatchLevelCmd(interp, objv);
                break;

            case OPT_PROCS:
                InfoProcsCmd(interp, objv);
                break;

            case OPT_SCRIPT:
                InfoScriptCmd(interp, objv);
                break;

            case OPT_SHAREDLIBEXTENSION:
                InfoSharedlibCmd(interp, objv);
                break;

            case OPT_TCLVERSION:
                InfoTclVersionCmd(interp, objv);
                break;

            case OPT_VARS:
                InfoVarsCmd(interp, objv);
                break;
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #8
0
        /// <summary> This procedure is invoked to process the "array" Tcl command.
        /// See the user documentation for details on what it does.
        /// </summary>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            Var    var = null, array = null;
            bool   notArray = false;
            string varName, msg;
            int    index;//, result;

            if (objv.Length < 3)
            {
                throw new TclNumArgsException(interp, 1, objv, "option arrayName ?arg ...?");
            }

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

            // Locate the array variable (and it better be an array).


            varName = objv[2].ToString();
            Var[] retArray = Var.lookupVar(interp, varName, null, 0, null, false, false);

            // Assign the values returned in the array
            if (retArray != null)
            {
                var   = retArray[0];
                array = retArray[1];
            }

            if ((var == null) || !var.isVarArray() || var.isVarUndefined())
            {
                notArray = true;
            }

            // Special array trace used to keep the env array in sync for
            // array names, array get, etc.

            if (var != null && var.traces != null)
            {
                msg = Var.callTraces(interp, array, var, varName, null, (TCL.VarFlag.LEAVE_ERR_MSG | TCL.VarFlag.NAMESPACE_ONLY | TCL.VarFlag.GLOBAL_ONLY | TCL.VarFlag.TRACE_ARRAY));
                if ((System.Object)msg != null)
                {
                    throw new TclVarException(interp, varName, null, "trace array", msg);
                }
            }

            switch (index)
            {
            case OPT_ANYMORE:
            {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName searchId");
                }
                if (notArray)
                {
                    errorNotArray(interp, objv[2].ToString());
                }

                if (var.sidVec == null)
                {
                    errorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString());
                }


                SearchId e = var.getSearch(objv[3].ToString());
                if (e == null)
                {
                    errorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString());
                }

                if (e.HasMore)
                {
                    interp.setResult("1");
                }
                else
                {
                    interp.setResult("0");
                }
                break;
            }

            case OPT_DONESEARCH:
            {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName searchId");
                }
                if (notArray)
                {
                    errorNotArray(interp, objv[2].ToString());
                }

                bool rmOK = true;
                if (var.sidVec != null)
                {
                    rmOK = (var.removeSearch(objv[3].ToString()));
                }
                if ((var.sidVec == null) || !rmOK)
                {
                    errorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString());
                }
                break;
            }

            case OPT_EXISTS:
            {
                if (objv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName");
                }
                interp.setResult(!notArray);
                break;
            }

            case OPT_GET:
            {
                // Due to the differences in the hashtable implementation
                // from the Tcl core and Java, the output will be rearranged.
                // This is not a negative side effect, however, test results
                // will differ.

                if ((objv.Length != 3) && (objv.Length != 4))
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName ?pattern?");
                }
                if (notArray)
                {
                    return(TCL.CompletionCode.RETURN);
                }

                string pattern = null;
                if (objv.Length == 4)
                {
                    pattern = objv[3].ToString();
                }

                Hashtable table = (Hashtable)var.value;
                TclObject tobj  = TclList.newInstance();

                string arrayName = objv[2].ToString();
                string key, strValue;
                Var    var2;

                // Go through each key in the hash table.  If there is a
                // pattern, test for a match.  Each valid key and its value
                // is written into sbuf, which is returned.

                // FIXME : do we need to port over the 8.1 code for this loop?

                for (IDictionaryEnumerator e = table.GetEnumerator(); e.MoveNext();)
                {
                    key  = ((string)e.Key);
                    var2 = (Var)e.Value;
                    if (var2.isVarUndefined())
                    {
                        continue;
                    }

                    if ((System.Object)pattern != null && !Util.stringMatch(key, pattern))
                    {
                        continue;
                    }


                    strValue = interp.getVar(arrayName, key, 0).ToString();

                    TclList.append(interp, tobj, TclString.newInstance(key));
                    TclList.append(interp, tobj, TclString.newInstance(strValue));
                }
                interp.setResult(tobj);
                break;
            }

            case OPT_NAMES:
            {
                if ((objv.Length != 3) && (objv.Length != 4))
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName ?pattern?");
                }
                if (notArray)
                {
                    return(TCL.CompletionCode.RETURN);
                }

                string pattern = null;
                if (objv.Length == 4)
                {
                    pattern = objv[3].ToString();
                }

                Hashtable table = (Hashtable)var.value;
                TclObject tobj  = TclList.newInstance();
                string    key;

                // Go through each key in the hash table.  If there is a
                // pattern, test for a match. Each valid key and its value
                // is written into sbuf, which is returned.

                for (IDictionaryEnumerator e = table.GetEnumerator(); e.MoveNext();)
                {
                    key = (string)e.Key;
                    Var elem = (Var)e.Value;
                    if (!elem.isVarUndefined())
                    {
                        if ((System.Object)pattern != null)
                        {
                            if (!Util.stringMatch(key, pattern))
                            {
                                continue;
                            }
                        }
                        TclList.append(interp, tobj, TclString.newInstance(key));
                    }
                }
                interp.setResult(tobj);
                break;
            }

            case OPT_NEXTELEMENT:
            {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName searchId");
                }
                if (notArray)
                {
                    errorNotArray(interp, objv[2].ToString());
                }

                if (var.sidVec == null)
                {
                    errorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString());
                }


                SearchId e = var.getSearch(objv[3].ToString());
                if (e == null)
                {
                    errorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString());
                }
                if (e.HasMore)
                {
                    Hashtable       table = (Hashtable)var.value;
                    DictionaryEntry entry = e.nextEntry();
                    string          key   = (string)entry.Key;
                    Var             elem  = (Var)entry.Value;
                    if ((elem.flags & VarFlags.UNDEFINED) == 0)
                    {
                        interp.setResult(key);
                    }
                    else
                    {
                        interp.setResult("");
                    }
                }
                break;
            }

            case OPT_SET:
            {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName list");
                }
                int size = TclList.getLength(interp, objv[3]);
                if (size % 2 != 0)
                {
                    throw new TclException(interp, "list must have an even number of elements");
                }

                int i;

                string name1 = objv[2].ToString();
                string name2, strValue;

                // Set each of the array variable names in the interp

                for (i = 0; i < size; i++)
                {
                    name2 = TclList.index(interp, objv[3], i++).ToString();

                    strValue = TclList.index(interp, objv[3], i).ToString();
                    interp.setVar(name1, name2, TclString.newInstance(strValue), 0);
                }
                break;
            }

            case OPT_SIZE:
            {
                if (objv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName");
                }
                if (notArray)
                {
                    interp.setResult(0);
                }
                else
                {
                    Hashtable table = (Hashtable)var.value;
                    int       size  = 0;
                    for (IDictionaryEnumerator e = table.GetEnumerator(); e.MoveNext();)
                    {
                        Var elem = (Var)e.Value;
                        if ((elem.flags & VarFlags.UNDEFINED) == 0)
                        {
                            size++;
                        }
                    }
                    interp.setResult(size);
                }
                break;
            }

            case OPT_STARTSEARCH:
            {
                if (objv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName");
                }
                if (notArray)
                {
                    errorNotArray(interp, objv[2].ToString());
                }

                if (var.sidVec == null)
                {
                    var.sidVec = new ArrayList(10);
                }

                // Create a SearchId Object:
                // To create a new SearchId object, a unique string
                // identifier needs to be composed and we need to
                // create an Enumeration of the array keys.  The
                // unique string identifier is created from three
                // strings:
                //
                //     "s-"   is the default prefix
                //     "i"    is a unique number that is 1+ the greatest
                //	      SearchId index currently on the ArrayVar.
                //     "name" is the name of the array
                //
                // Once the SearchId string is created we construct a
                // new SearchId object using the string and the
                // Enumeration.  From now on the string is used to
                // uniquely identify the SearchId object.

                int i = var.NextIndex;

                string s = "s-" + i + "-" + objv[2].ToString();
                IDictionaryEnumerator e = ((Hashtable)var.value).GetEnumerator();
                var.sidVec.Add(new SearchId(e, s, i));
                interp.setResult(s);
                break;
            }

            case OPT_UNSET:
            {
                string pattern;
                string name;

                if ((objv.Length != 3) && (objv.Length != 4))
                {
                    throw new TclNumArgsException(interp, 2, objv, "arrayName ?pattern?");
                }
                if (notArray)
                {
                    //Ignot this error -- errorNotArray(interp, objv[2].ToString());
                    break;
                }
                if (objv.Length == 3)
                {
                    // When no pattern is given, just unset the whole array

                    interp.unsetVar(objv[2], 0);
                }
                else
                {
                    pattern = objv[3].ToString();
                    Hashtable table = (Hashtable)(((Hashtable)var.value).Clone());
                    for (IDictionaryEnumerator e = table.GetEnumerator(); e.MoveNext();)
                    {
                        name = (string)e.Key;
                        Var elem = (Var)e.Value;
                        if (var.isVarUndefined())
                        {
                            continue;
                        }
                        if (Util.stringMatch(name, pattern))
                        {
                            interp.unsetVar(varName, name, 0);
                        }
                    }
                }
                break;
            }
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #9
0
        /// <summary> This procedure is invoked to process the "subst" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException if wrong # of args or invalid argument(s).
        /// </exception>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            int  currentObjIndex, len, i;
            int  objc          = argv.Length - 1;
            bool doBackslashes = true;
            bool doCmds        = true;
            bool doVars        = true;

            System.Text.StringBuilder result = new System.Text.StringBuilder();
            string s;
            char   c;

            for (currentObjIndex = 1; currentObjIndex < objc; currentObjIndex++)
            {
                if (!argv[currentObjIndex].ToString().StartsWith("-"))
                {
                    break;
                }
                int opt = TclIndex.get(interp, argv[currentObjIndex], validCmds, "switch", 0);
                switch (opt)
                {
                case OPT_NOBACKSLASHES:
                    doBackslashes = false;
                    break;

                case OPT_NOCOMMANDS:
                    doCmds = false;
                    break;

                case OPT_NOVARS:
                    doVars = false;
                    break;

                default:
                    throw new TclException(interp, "SubstCmd.cmdProc: bad option " + opt + " index to cmds");
                }
            }
            if (currentObjIndex != objc)
            {
                throw new TclNumArgsException(interp, currentObjIndex, argv, "?-nobackslashes? ?-nocommands? ?-novariables? string");
            }

            /*
             * Scan through the string one character at a time, performing
             * command, variable, and backslash substitutions.
             */


            s   = argv[currentObjIndex].ToString();
            len = s.Length;
            i   = 0;
            while (i < len)
            {
                c = s[i];

                if ((c == '[') && doCmds)
                {
                    ParseResult res;
                    try
                    {
                        interp.evalFlags = Parser.TCL_BRACKET_TERM;
                        interp.eval(s.Substring(i + 1, (len) - (i + 1)));
                        TclObject interp_result = interp.getResult();
                        interp_result.preserve();
                        res = new ParseResult(interp_result, i + interp.termOffset);
                    }
                    catch (TclException e)
                    {
                        i = e.errIndex + 1;
                        throw;
                    }
                    i = res.nextIndex + 2;

                    result.Append(res.value.ToString());
                    res.release();
                }
                else if (c == '\r')
                {
                    /*
                     * (ToDo) may not be portable on Mac
                     */

                    i++;
                }
                else if ((c == '$') && doVars)
                {
                    ParseResult vres = Parser.parseVar(interp, s.Substring(i, (len) - (i)));
                    i += vres.nextIndex;

                    result.Append(vres.value.ToString());
                    vres.release();
                }
                else if ((c == '\\') && doBackslashes)
                {
                    BackSlashResult bs = tcl.lang.Interp.backslash(s, i, len);
                    i = bs.nextIndex;
                    if (bs.isWordSep)
                    {
                        break;
                    }
                    else
                    {
                        result.Append(bs.c);
                    }
                }
                else
                {
                    result.Append(c);
                    i++;
                }
            }

            interp.setResult(result.ToString());
            return(TCL.CompletionCode.RETURN);
        }
Пример #10
0
        private static void  fileCopyRename(Interp interp, TclObject[] argv, bool copyFlag)
        {
            int  firstSource = 2;
            bool force       = false;

            for (bool last = false; (firstSource < argv.Length) && (!last); firstSource++)
            {
                if (!argv[firstSource].ToString().StartsWith("-"))
                {
                    break;
                }
                int opt = TclIndex.get(interp, argv[firstSource], validOptions, "option", 1);
                switch (opt)
                {
                case OPT_FORCE:
                    force = true;
                    break;

                case OPT_LAST:
                    last = true;
                    break;

                default:
                    throw new TclRuntimeError("FileCmd.cmdProc: bad option " + opt + " index to validOptions");
                }
            }

            if (firstSource >= (argv.Length - 1))
            {
                throw new TclNumArgsException(interp, firstSource, argv, "?options? source ?source ...? target");
            }

            // WARNING:  ignoring links because Java does not support them.

            int target = argv.Length - 1;

            string targetName = argv[target].ToString();

            System.IO.FileInfo targetObj = FileUtil.getNewFileObj(interp, targetName);
            if (System.IO.Directory.Exists(targetObj.FullName))
            {
                // If the target is a directory, move each source file into target
                // directory.  Extract the tailname from each source, and append it to
                // the end of the target path.

                for (int source = firstSource; source < target; source++)
                {
                    string sourceName = argv[source].ToString();

                    if (targetName.Length == 0)
                    {
                        copyRenameOneFile(interp, sourceName, targetName, copyFlag, force);
                    }
                    else
                    {
                        string tailName = getTail(interp, sourceName);

                        TclObject[] joinArrayObj = new TclObject[2];
                        joinArrayObj[0] = TclString.newInstance(targetName);
                        joinArrayObj[1] = TclString.newInstance(tailName);

                        string fullTargetName = FileUtil.joinPath(interp, joinArrayObj, 0, 2);

                        copyRenameOneFile(interp, sourceName, fullTargetName, copyFlag, force);
                    }
                }
            }
            else
            {
                // If there is more than 1 source file and the target is not a
                // directory, then throw an exception.

                if (firstSource + 1 != target)
                {
                    string action;
                    if (copyFlag)
                    {
                        action = "copying";
                    }
                    else
                    {
                        action = "renaming";
                    }

                    throw new TclPosixException(interp, TclPosixException.ENOTDIR, "error " + action + ": target \"" + argv[target].ToString() + "\" is not a directory");
                }

                string sourceName = argv[firstSource].ToString();
                copyRenameOneFile(interp, sourceName, targetName, copyFlag, force);
            }
        }
Пример #11
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);
        }
Пример #12
0
        /*
         *----------------------------------------------------------------------
         *
         * cmdProc --
         *
         *	This procedure is invoked as part of the Command interface to
         *	process the "lsort" Tcl command.  See the user documentation for
         *	details on what it does.
         *
         * Results:
         *	A standard Tcl result.
         *
         * Side effects:
         *	See the user documentation.
         *
         *----------------------------------------------------------------------
         */

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

            string command        = null;
            int    sortMode       = QSort.ASCII;
            int    sortIndex      = -1;
            bool   sortIncreasing = true;
            bool   unique         = false;

            for (int i = 1; i < argv.Length - 1; i++)
            {
                int index = TclIndex.get(interp, argv[i], validOpts, "option", 0);

                switch (index)
                {
                case 0:
                    sortMode = QSort.ASCII;
                    break;


                case 1:
                    if (i == argv.Length - 2)
                    {
                        throw new TclException(interp, "\"-command\" option must be" + " followed by comparison command");
                    }
                    sortMode = QSort.COMMAND;

                    command = argv[i + 1].ToString();
                    i++;
                    break;


                case 2:
                    sortIncreasing = false;
                    break;


                case 3:
                    sortMode = QSort.DICTIONARY;
                    break;


                case 4:
                    sortIncreasing = true;
                    break;


                case 5:
                    if (i == argv.Length - 2)
                    {
                        throw new TclException(interp, "\"-index\" option must be followed by list index");
                    }
                    sortIndex = Util.getIntForIndex(interp, argv[i + 1], -2);

                    command = argv[i + 1].ToString();
                    i++;
                    break;


                case 6:
                    sortMode = QSort.INTEGER;
                    break;


                case 7:
                    sortMode = QSort.REAL;
                    break;

                case 8:         /* -unique */
                    unique = true;
                    break;
                }
            }

            TclObject list        = argv[argv.Length - 1];
            bool      isDuplicate = false;

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

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

            try
            {
                TclList.sort(interp, list, sortMode, sortIndex, sortIncreasing, command, unique);
                interp.setResult(list);
            }
            catch (TclException e)
            {
                if (isDuplicate)
                {
                    list.release();
                }
                throw;
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #13
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "option ?arg ...?");
            }

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

            System.IO.FileInfo fileObj = null;

            switch (opt)
            {
            case OPT_ATIME:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                // FIXME:  Currently returns the same thing as MTIME.
                // Java does not support retrieval of access time.



                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());

                interp.setResult(getMtime(interp, argv[2].ToString(), fileObj));
                return(TCL.CompletionCode.RETURN);


            case OPT_ATTRIBUTES:
                if (argv[3].ToString() == "-readonly")
                {
                    fileSetReadOnly(interp, argv);
                }
                else
                {
                    throw new TclException(interp, "sorry, \"file attributes\" is not implemented yet");
                }
                return(TCL.CompletionCode.RETURN);


            case OPT_CHANNELS:

                throw new TclException(interp, "sorry, \"file channels\" is not implemented yet");


            case OPT_COPY:
                fileCopyRename(interp, argv, true);
                return(TCL.CompletionCode.RETURN);


            case OPT_DELETE:
                fileDelete(interp, argv);
                return(TCL.CompletionCode.RETURN);


            case OPT_DIRNAME:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                path = argv[2].ToString();

                // Return all but the last component.  If there is only one
                // component, return it if the path was non-relative, otherwise
                // return the current directory.


                TclObject[] splitArrayObj = TclList.getElements(interp, FileUtil.splitAndTranslate(interp, path));

                if (splitArrayObj.Length > 1)
                {
                    interp.setResult(FileUtil.joinPath(interp, splitArrayObj, 0, splitArrayObj.Length - 1));
                }
                else if ((splitArrayObj.Length == 0) || (FileUtil.getPathType(path) == FileUtil.PATH_RELATIVE))
                {
                    if (JACL.PLATFORM == JACL.PLATFORM_MAC)
                    {
                        interp.setResult(":");
                    }
                    else
                    {
                        interp.setResult(".");
                    }
                }
                else
                {
                    interp.setResult(splitArrayObj[0].ToString());
                }
                return(TCL.CompletionCode.RETURN);


            case OPT_EXECUTABLE:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }
                bool isExe = false;

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());

                // A file must exist to be executable.  Directories are always
                // executable.

                bool tmpBool;
                if (System.IO.File.Exists(fileObj.FullName))
                {
                    tmpBool = true;
                }
                else
                {
                    tmpBool = System.IO.Directory.Exists(fileObj.FullName);
                }
                if (tmpBool)
                {
                    isExe = System.IO.Directory.Exists(fileObj.FullName);
                    if (isExe)
                    {
                        interp.setResult(isExe);
                        return(TCL.CompletionCode.RETURN);
                    }

                    if (Util.Windows)
                    {
                        // File that ends with .exe, .com, or .bat is executable.


                        string fileName = argv[2].ToString();
                        isExe = (fileName.EndsWith(".exe") || fileName.EndsWith(".com") || fileName.EndsWith(".bat"));
                    }
                    else if (Util.Mac)
                    {
                        // FIXME:  Not yet implemented on Mac.  For now, return true.
                        // Java does not support executability checking.

                        isExe = true;
                    }
                    else
                    {
                        // FIXME:  Not yet implemented on Unix.  For now, return true.
                        // Java does not support executability checking.

                        isExe = true;
                    }
                }
                interp.setResult(isExe);
                return(TCL.CompletionCode.RETURN);


            case OPT_EXISTS:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());
                bool tmpBool2;
                if (System.IO.File.Exists(fileObj.FullName))
                {
                    tmpBool2 = true;
                }
                else
                {
                    tmpBool2 = System.IO.Directory.Exists(fileObj.FullName);
                }
                interp.setResult(tmpBool2);
                return(TCL.CompletionCode.RETURN);


            case OPT_EXTENSION:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                interp.setResult(getExtension(argv[2].ToString()));
                return(TCL.CompletionCode.RETURN);


            case OPT_ISDIRECTORY:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());
                interp.setResult(System.IO.Directory.Exists(fileObj.FullName));
                return(TCL.CompletionCode.RETURN);


            case OPT_ISFILE:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());
                interp.setResult(System.IO.File.Exists(fileObj.FullName));
                return(TCL.CompletionCode.RETURN);


            case OPT_JOIN:
                if (argv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name ?name ...?");
                }
                interp.setResult(FileUtil.joinPath(interp, argv, 2, argv.Length));
                return(TCL.CompletionCode.RETURN);


            case OPT_LINK:

                throw new TclException(interp, "sorry, \"file link\" is not implemented yet");


            case OPT_LSTAT:
                if (argv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name varName");
                }

                // FIXME:  Not yet implemented.
                // Java does not support link access.


                throw new TclException(interp, "file command with opt " + argv[1].ToString() + " is not yet implemented");



            case OPT_MTIME:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());

                interp.setResult(getMtime(interp, argv[2].ToString(), fileObj));
                return(TCL.CompletionCode.RETURN);


            case OPT_MKDIR:
                fileMakeDirs(interp, argv);
                return(TCL.CompletionCode.RETURN);


            case OPT_NATIVENAME:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }


                interp.setResult(FileUtil.translateFileName(interp, argv[2].ToString()));
                return(TCL.CompletionCode.RETURN);


            case OPT_NORMALIZE:

                throw new TclException(interp, "sorry, \"file normalize\" is not implemented yet");


            case OPT_OWNED:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());
                interp.setResult(isOwner(interp, fileObj));
                return(TCL.CompletionCode.RETURN);


            case OPT_PATHTYPE:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                switch (FileUtil.getPathType(argv[2].ToString()))
                {
                case FileUtil.PATH_RELATIVE:
                    interp.setResult("relative");
                    return(TCL.CompletionCode.RETURN);

                case FileUtil.PATH_VOLUME_RELATIVE:
                    interp.setResult("volumerelative");
                    return(TCL.CompletionCode.RETURN);

                case FileUtil.PATH_ABSOLUTE:
                    interp.setResult("absolute");
                    break;
                }
                return(TCL.CompletionCode.RETURN);


            case OPT_READABLE:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());

                // interp.setResult(fileObj.canRead());
                // HACK
                interp.setResult(true);
                return(TCL.CompletionCode.RETURN);


            case OPT_READLINK:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                // FIXME:  Not yet implemented.
                // Java does not support link access.


                throw new TclException(interp, "file command with opt " + argv[1].ToString() + " is not yet implemented");


            case OPT_RENAME:
                fileCopyRename(interp, argv, false);
                return(TCL.CompletionCode.RETURN);


            case OPT_ROOTNAME:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                string fileName2  = argv[2].ToString();
                string extension  = getExtension(fileName2);
                int    diffLength = fileName2.Length - extension.Length;
                interp.setResult(fileName2.Substring(0, (diffLength) - (0)));
                return(TCL.CompletionCode.RETURN);


            case OPT_SEPARATOR:

                throw new TclException(interp, "sorry, \"file separator\" is not implemented yet");


            case OPT_SIZE:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());
                bool tmpBool3;
                if (System.IO.File.Exists(fileObj.FullName))
                {
                    tmpBool3 = true;
                }
                else
                {
                    tmpBool3 = System.IO.Directory.Exists(fileObj.FullName);
                }
                if (!tmpBool3)
                {
                    throw new TclPosixException(interp, TclPosixException.ENOENT, true, "could not read \"" + argv[2].ToString() + "\"");
                }
                interp.setResult((int)SupportClass.FileLength(fileObj));
                return(TCL.CompletionCode.RETURN);


            case OPT_SPLIT:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                interp.setResult(FileUtil.splitPath(interp, argv[2].ToString()));
                return(TCL.CompletionCode.RETURN);


            case OPT_STAT:
                if (argv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name varName");
                }

                getAndStoreStatData(interp, argv[2].ToString(), argv[3].ToString());
                return(TCL.CompletionCode.RETURN);


            case OPT_SYSTEM:

                throw new TclException(interp, "sorry, \"file system\" is not implemented yet");


            case OPT_TAIL:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                interp.setResult(getTail(interp, argv[2].ToString()));
                return(TCL.CompletionCode.RETURN);


            case OPT_TYPE:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());

                interp.setResult(getType(interp, argv[2].ToString(), fileObj));
                return(TCL.CompletionCode.RETURN);


            case OPT_VOLUMES:
                if (argv.Length != 2)
                {
                    throw new TclNumArgsException(interp, 2, argv, null);
                }

                // use Java 1.2's File.listRoots() method if available

                if (listRootsMethod == null)
                {
                    throw new TclException(interp, "\"file volumes\" is not supported");
                }

                try
                {
                    System.IO.FileInfo[] roots = (System.IO.FileInfo[])listRootsMethod.Invoke(null, (System.Object[]) new System.Object[0]);
                    if (roots != null)
                    {
                        TclObject list = TclList.newInstance();
                        for (int i = 0; i < roots.Length; i++)
                        {
                            string root = roots[i].FullName;
                            TclList.append(interp, list, TclString.newInstance(root));
                        }
                        interp.setResult(list);
                    }
                }
                catch (System.UnauthorizedAccessException ex)
                {
                    throw new TclRuntimeError("IllegalAccessException in volumes cmd");
                }
                catch (System.ArgumentException ex)
                {
                    throw new TclRuntimeError("IllegalArgumentException in volumes cmd");
                }
                catch (System.Reflection.TargetInvocationException ex)
                {
                    System.Exception t = ex.GetBaseException();

                    if (t is System.ApplicationException)
                    {
                        throw (System.ApplicationException)t;
                    }
                    else
                    {
                        throw new TclRuntimeError("unexected exception in volumes cmd");
                    }
                }

                return(TCL.CompletionCode.RETURN);

            case OPT_WRITABLE:
                if (argv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, argv, "name");
                }

                fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString());
                interp.setResult(SupportClass.FileCanWrite(fileObj));
                return(TCL.CompletionCode.RETURN);

            default:

                throw new TclRuntimeError("file command with opt " + argv[1].ToString() + " is not implemented");
            }
        }
Пример #14
0
        /// <summary> This procedure is invoked to process the "encoding" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>

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

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

            switch (index)
            {
            case OPT_CONVERTTO:
            case OPT_CONVERTFROM:
            {
                string    tclEncoding;
                Encoding  javaEncoding;
                TclObject data;

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

                javaEncoding = getJavaName(tclEncoding);

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

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

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


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

                break;
            }

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

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

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

                if (argv.Length == 2)
                {
                    interp.setResult(systemTclEncoding);
                }
                else
                {
                    string   tclEncoding  = argv[2].ToString();
                    Encoding javaEncoding = getJavaName(tclEncoding);

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

                    systemTclEncoding  = tclEncoding;
                    systemJavaEncoding = javaEncoding;
                }

                break;
            }

            default:
            {
                throw new TclRuntimeError("Encoding.cmdProc() error: " + "incorrect index returned from TclIndex.get()");
            }
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #15
0
        /// <summary> This procedure is invoked to process the "fconfigure" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan; // The channel being operated on this method

            if ((argv.Length < 2) || (((argv.Length % 2) == 1) && (argv.Length != 3)))
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId ?optionName? ?value? ?optionName value?...");
            }


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

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

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

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

                TclList.append(interp, list, TclString.newInstance("-buffersize"));
                TclList.append(interp, list, TclInteger.newInstance(chan.BufferSize));

                // -encoding

                TclList.append(interp, list, TclString.newInstance("-encoding"));

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

                // -eofchar

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

                    TclObject eofchar_pair = TclList.newInstance();

                    TclList.append(interp, eofchar_pair, (inEofChar == 0) ? TclString.newInstance("") : TclString.newInstance(inEofChar));

                    TclList.append(interp, eofchar_pair, (outEofChar == 0) ? TclString.newInstance("") : TclString.newInstance(outEofChar));

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

                // -translation

                TclList.append(interp, list, TclString.newInstance("-translation"));

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

                    TclList.append(interp, translation_pair, TclString.newInstance(TclIO.getTranslationString(chan.InputTranslation)));
                    TclList.append(interp, translation_pair, TclString.newInstance(TclIO.getTranslationString(chan.OutputTranslation)));

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

                interp.setResult(list);
            }

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

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

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

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

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

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

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

                        TclObject eofchar_pair = TclList.newInstance();

                        TclList.append(interp, eofchar_pair, (inEofChar == 0) ? TclString.newInstance("") : TclString.newInstance(inEofChar));

                        TclList.append(interp, eofchar_pair, (outEofChar == 0) ? TclString.newInstance("") : TclString.newInstance(outEofChar));

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

                    break;
                }

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

                        TclList.append(interp, translation_pair, TclString.newInstance(TclIO.getTranslationString(chan.InputTranslation)));
                        TclList.append(interp, translation_pair, TclString.newInstance(TclIO.getTranslationString(chan.OutputTranslation)));

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

                    break;
                }

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

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

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

                case OPT_BUFFERING:
                {
                    // -buffering

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

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

                    chan.Buffering = id;
                    break;
                }

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

                case OPT_ENCODING:
                {
                    // -encoding

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

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

                    break;
                }

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

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

                    char   inputEofChar, outputEofChar;
                    string s;

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


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

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

                    break;
                }

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

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

                    string inputTranslationArg, outputTranslationArg;
                    int    inputTranslation, outputTranslation;

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

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

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

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

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

                    break;
                }

                default:
                {
                    throw new TclRuntimeError("Fconfigure.cmdProc() error: " + "incorrect index returned from TclIndex.get()");
                }
                }
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #16
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            bool nocase  = false;
            bool indices = false;

            try
            {
                int i = 1;

                while (argv[i].ToString().StartsWith("-"))
                {
                    int index = TclIndex.get(interp, argv[i], validOpts, "switch", 0);
                    i++;
                    switch (index)
                    {
                    case OPT_INDICES:  {
                        indices = true;
                        break;
                    }

                    case OPT_NOCASE:  {
                        nocase = true;
                        break;
                    }

                    case OPT_LAST:  {
                        goto opts_brk;
                    }
                    }
                }

                opts_brk :;


                TclObject exp = TclString.newInstance(argv[i++].ToString().Replace("\\d", "[0-9]"));

                string inString = argv[i++].ToString();

                int matches = argv.Length - i;

                Regexp r = TclRegexp.compile(interp, exp, nocase);

                int[] args    = new int[matches * 2];
                bool  matched = r.match(inString, args);
                if (matched)
                {
                    for (int match = 0; i < argv.Length; i++)
                    {
                        TclObject obj;

                        int start = args[match++];
                        int end   = args[match++];
                        if (indices)
                        {
                            if (end >= 0)
                            {
                                end--;
                            }
                            obj = TclList.newInstance();
                            TclList.append(interp, obj, TclInteger.newInstance(start));
                            TclList.append(interp, obj, TclInteger.newInstance(end));
                        }
                        else
                        {
                            string range = (start >= 0)?inString.Substring(start, (end) - (start)):"";
                            obj = TclString.newInstance(range);
                        }
                        try
                        {
                            interp.setVar(argv[i].ToString(), obj, 0);
                        }
                        catch (TclException e)
                        {
                            throw new TclException(interp, "couldn't set variable \"" + argv[i] + "\"");
                        }
                    }
                }
                interp.setResult(matched);
            }
            catch (System.IndexOutOfRangeException e)
            {
                throw new TclNumArgsException(interp, 1, argv, "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #17
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);
        }
Пример #18
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "cmd ?arg ...?");
            }
            int cmd = TclIndex.get(interp, objv[1], options, "option", 0);

            switch (cmd)
            {
            case OPT_ALIAS:
                if (objv.Length == 3)
                {
                    InterpAliasCmd.describe(interp, slaveInterp, objv[2]);
                    return(TCL.CompletionCode.RETURN);
                }

                if ("".Equals(objv[3].ToString()))
                {
                    if (objv.Length == 4)
                    {
                        InterpAliasCmd.delete(interp, slaveInterp, objv[2]);
                        return(TCL.CompletionCode.RETURN);
                    }
                }
                else
                {
                    InterpAliasCmd.create(interp, slaveInterp, interp, objv[2], objv[3], 4, objv);
                    return(TCL.CompletionCode.RETURN);
                }
                throw new TclNumArgsException(interp, 2, objv, "aliasName ?targetName? ?args..?");

            case OPT_ALIASES:
                InterpAliasCmd.list(interp, slaveInterp);
                break;

            case OPT_EVAL:
                if (objv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "arg ?arg ...?");
                }
                eval(interp, slaveInterp, 2, objv);
                break;

            case OPT_EXPOSE:
                if (objv.Length < 3 || objv.Length > 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "hiddenCmdName ?cmdName?");
                }
                expose(interp, slaveInterp, 2, objv);
                break;

            case OPT_HIDE:
                if (objv.Length < 3 || objv.Length > 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "cmdName ?hiddenCmdName?");
                }
                hide(interp, slaveInterp, 2, objv);
                break;

            case OPT_HIDDEN:
                if (objv.Length != 2)
                {
                    throw new TclNumArgsException(interp, 2, objv, null);
                }
                InterpSlaveCmd.hidden(interp, slaveInterp);
                break;

            case OPT_ISSAFE:
                interp.setResult(slaveInterp.isSafe);
                break;

            case OPT_INVOKEHIDDEN:
                bool global = false;
                int  i;
                for (i = 2; i < objv.Length; i++)
                {
                    if (objv[i].ToString()[0] != '-')
                    {
                        break;
                    }
                    int index = TclIndex.get(interp, objv[i], hiddenOptions, "option", 0);
                    if (index == OPT_HIDDEN_GLOBAL)
                    {
                        global = true;
                    }
                    else
                    {
                        i++;
                        break;
                    }
                }
                if (objv.Length - i < 1)
                {
                    throw new TclNumArgsException(interp, 2, objv, "?-global? ?--? cmd ?arg ..?");
                }
                InterpSlaveCmd.invokeHidden(interp, slaveInterp, global, i, objv);
                break;

            case OPT_MARKTRUSTED:
                if (objv.Length != 2)
                {
                    throw new TclNumArgsException(interp, 2, objv, null);
                }
                markTrusted(interp, slaveInterp);
                break;
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #19
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            VersionSatisfiesResult vsres;
            Package  pkg;
            PkgAvail avail;
            PkgAvail prev;
            string   version;
            string   pkgName;
            string   key;
            string   cmd;
            string   ver1, ver2;

            System.Text.StringBuilder sbuf;
            IDictionaryEnumerator     enum_Renamed;
            int  i, opt, exact;
            bool once;

            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "option ?arg arg ...?");
            }
            opt = TclIndex.get(interp, objv[1], validCmds, "option", 0);
            switch (opt)
            {
            case OPT_FORGET:  {
                // Forget takes 0 or more arguments.

                for (i = 2; i < objv.Length; i++)
                {
                    // We do not need to check to make sure
                    // package name is "" because it would not
                    // be in the hash table so name will be ignored.


                    pkgName = objv[i].ToString();
                    pkg     = (Package)interp.packageTable[pkgName];

                    // If this package does not exist, go to next one.

                    if (pkg == null)
                    {
                        continue;
                    }
                    SupportClass.HashtableRemove(interp.packageTable, pkgName);
                    while (pkg.avail != null)
                    {
                        avail     = pkg.avail;
                        pkg.avail = avail.next;
                        avail     = null;
                    }
                    pkg = null;
                }
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_IFNEEDED:  {
                if ((objv.Length < 4) || (objv.Length > 5))
                {
                    throw new TclNumArgsException(interp, 1, objv, "ifneeded package version ?script?");
                }
                pkgName = objv[2].ToString();
                version = objv[3].ToString();

                // Verify that this version string is valid.

                checkVersion(interp, version);
                if (objv.Length == 4)
                {
                    pkg = (Package)interp.packageTable[pkgName];
                    if (pkg == null)
                    {
                        return(TCL.CompletionCode.RETURN);
                    }
                }
                else
                {
                    pkg = findPackage(interp, pkgName);
                }
                for (avail = pkg.avail, prev = null; avail != null; prev = avail, avail = avail.next)
                {
                    if (compareVersions(avail.version, version, null) == 0)
                    {
                        if (objv.Length == 4)
                        {
                            // If doing a query return current script.

                            interp.setResult(avail.script);
                            return(TCL.CompletionCode.RETURN);
                        }

                        // We matched so we must be setting the script.

                        break;
                    }
                }

                // When we do not match on a query return nothing.

                if (objv.Length == 4)
                {
                    return(TCL.CompletionCode.RETURN);
                }
                if (avail == null)
                {
                    avail         = new PkgAvail();
                    avail.version = version;
                    if (prev == null)
                    {
                        avail.next = pkg.avail;
                        pkg.avail  = avail;
                    }
                    else
                    {
                        avail.next = prev.next;
                        prev.next  = avail;
                    }
                }

                avail.script = objv[4].ToString();
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_NAMES:  {
                if (objv.Length != 2)
                {
                    throw new TclNumArgsException(interp, 1, objv, "names");
                }

                try
                {
                    sbuf         = new System.Text.StringBuilder();
                    enum_Renamed = interp.packageTable.GetEnumerator();
                    once         = false;
                    while (enum_Renamed.MoveNext())
                    {
                        once = true;
                        key  = ((string)enum_Renamed.Current);
                        pkg  = (Package)enum_Renamed.Value;
                        if (((System.Object)pkg.version != null) || (pkg.avail != null))
                        {
                            Util.appendElement(interp, sbuf, key);
                        }
                    }
                    if (once)
                    {
                        interp.setResult(sbuf.ToString());
                    }
                }
                catch (TclException e)
                {
                    throw new TclRuntimeError("unexpected TclException: " + e);
                }
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_PRESENT:  {
                if (objv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "?-exact? package ?version?");
                }

                if (objv[2].ToString().Equals("-exact"))
                {
                    exact = 1;
                }
                else
                {
                    exact = 0;
                }

                version = null;
                if (objv.Length == (4 + exact))
                {
                    version = objv[3 + exact].ToString();
                    checkVersion(interp, version);
                }
                else if ((objv.Length != 3) || (exact == 1))
                {
                    throw new TclNumArgsException(interp, 2, objv, "?-exact? package ?version?");
                }
                if (exact == 1)
                {
                    version = pkgPresent(interp, objv[3].ToString(), version, true);
                }
                else
                {
                    version = pkgPresent(interp, objv[2].ToString(), version, false);
                }
                interp.setResult(version);
                break;
            }

            case OPT_PROVIDE:  {
                if ((objv.Length < 3) || (objv.Length > 4))
                {
                    throw new TclNumArgsException(interp, 1, objv, "provide package ?version?");
                }
                if (objv.Length == 3)
                {
                    pkg = (Package)interp.packageTable[objv[2].ToString()];
                    if (pkg != null)
                    {
                        if ((System.Object)pkg.version != null)
                        {
                            interp.setResult(pkg.version);
                        }
                    }
                    return(TCL.CompletionCode.RETURN);
                }

                pkgProvide(interp, objv[2].ToString(), objv[3].ToString());
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_REQUIRE:  {
                if ((objv.Length < 3) || (objv.Length > 5))
                {
                    throw new TclNumArgsException(interp, 1, objv, "require ?-exact? package ?version?");
                }

                if (objv[2].ToString().Equals("-exact"))
                {
                    exact = 1;
                }
                else
                {
                    exact = 0;
                }
                version = null;
                if (objv.Length == (4 + exact))
                {
                    version = objv[3 + exact].ToString();
                    checkVersion(interp, version);
                }
                else if ((objv.Length != 3) || (exact == 1))
                {
                    throw new TclNumArgsException(interp, 1, objv, "require ?-exact? package ?version?");
                }
                if (exact == 1)
                {
                    version = pkgRequire(interp, objv[3].ToString(), version, true);
                }
                else
                {
                    version = pkgRequire(interp, objv[2].ToString(), version, false);
                }
                interp.setResult(version);
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_UNKNOWN:  {
                if (objv.Length > 3)
                {
                    throw new TclNumArgsException(interp, 1, objv, "unknown ?command?");
                }
                if (objv.Length == 2)
                {
                    if ((System.Object)interp.packageUnknown != null)
                    {
                        interp.setResult(interp.packageUnknown);
                    }
                }
                else if (objv.Length == 3)
                {
                    interp.packageUnknown = null;

                    cmd = objv[2].ToString();
                    if (cmd.Length > 0)
                    {
                        interp.packageUnknown = cmd;
                    }
                }
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_VCOMPARE:  {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 1, objv, "vcompare version1 version2");
                }

                ver1 = objv[2].ToString();

                ver2 = objv[3].ToString();
                checkVersion(interp, ver1);
                checkVersion(interp, ver2);
                interp.setResult(compareVersions(ver1, ver2, null));
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_VERSIONS:  {
                if (objv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 1, objv, "versions package");
                }

                pkg = (Package)interp.packageTable[objv[2].ToString()];
                if (pkg != null)
                {
                    try
                    {
                        sbuf = new System.Text.StringBuilder();
                        once = false;
                        for (avail = pkg.avail; avail != null; avail = avail.next)
                        {
                            once = true;
                            Util.appendElement(interp, sbuf, avail.version);
                        }
                        if (once)
                        {
                            interp.setResult(sbuf.ToString());
                        }
                    }
                    catch (TclException e)
                    {
                        throw new TclRuntimeError("unexpected TclException: " + e.Message, e);
                    }
                }
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_VSATISFIES:  {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 1, objv, "vsatisfies version1 version2");
                }


                ver1 = objv[2].ToString();

                ver2 = objv[3].ToString();
                checkVersion(interp, ver1);
                checkVersion(interp, ver2);
                vsres = new VersionSatisfiesResult();
                compareVersions(ver1, ver2, vsres);
                interp.setResult(vsres.satisfies);
                return(TCL.CompletionCode.RETURN);
            }

            default:  {
                throw new TclRuntimeError("TclIndex.get() error");
            }
            }             // end switch(opt)
            return(TCL.CompletionCode.RETURN);
        }
Пример #20
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            bool all    = false;
            bool nocase = false;

            try
            {
                int i = 1;

                while (argv[i].ToString().StartsWith("-"))
                {
                    int index = TclIndex.get(interp, argv[i], validOpts, "switch", 0);
                    i++;
                    switch (index)
                    {
                    case OPT_ALL:  {
                        all = true;
                        break;
                    }

                    case OPT_NOCASE:  {
                        nocase = true;
                        break;
                    }

                    case OPT_LAST:  {
                        goto opts_brk;
                    }
                    }
                }

                opts_brk :;


                TclObject exp = argv[i++];

                string inString = argv[i++].ToString();

                string subSpec = argv[i++].ToString();

                string varName = argv[i++].ToString();
                if (i != argv.Length)
                {
                    throw new System.IndexOutOfRangeException();
                }

                Regexp r = TclRegexp.compile(interp, exp, nocase);

                int    count = 0;
                string result;

                if (all == false)
                {
                    result = r.sub(inString, subSpec);
                    if ((System.Object)result == null)
                    {
                        result = inString;
                    }
                    else
                    {
                        count++;
                    }
                }
                else
                {
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    Regsub s = new Regsub(r, inString);
                    while (s.nextMatch())
                    {
                        count++;
                        sb.Append(s.skipped());
                        Regexp.applySubspec(s, subSpec, sb);
                    }
                    sb.Append(s.rest());
                    result = sb.ToString();
                }

                TclObject obj = TclString.newInstance(result);
                try
                {
                    interp.setVar(varName, obj, 0);
                }
                catch (TclException e)
                {
                    throw new TclException(interp, "couldn't set variable \"" + varName + "\"");
                }
                interp.setResult(count);
            }
            catch (System.IndexOutOfRangeException e)
            {
                throw new TclNumArgsException(interp, 1, argv, "?switches? exp string subSpec varName");
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #21
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);
        }
Пример #22
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "cmd ?arg ...?");
            }
            int cmd = TclIndex.get(interp, objv[1], options, "option", 0);

            switch (cmd)
            {
            case OPT_ALIAS:
            {
                if (objv.Length >= 4)
                {
                    Interp slaveInterp = getInterp(interp, objv[2]);

                    if (objv.Length == 4)
                    {
                        InterpAliasCmd.describe(interp, slaveInterp, objv[3]);
                        return(TCL.CompletionCode.RETURN);
                    }

                    if ((objv.Length == 5) && ("".Equals(objv[4].ToString())))
                    {
                        InterpAliasCmd.delete(interp, slaveInterp, objv[3]);
                        return(TCL.CompletionCode.RETURN);
                    }
                    if (objv.Length > 5)
                    {
                        Interp masterInterp = getInterp(interp, objv[4]);

                        if ("".Equals(objv[5].ToString()))
                        {
                            if (objv.Length == 6)
                            {
                                InterpAliasCmd.delete(interp, slaveInterp, objv[3]);
                                return(TCL.CompletionCode.RETURN);
                            }
                        }
                        else
                        {
                            InterpAliasCmd.create(interp, slaveInterp, masterInterp, objv[3], objv[5], 6, objv);
                            return(TCL.CompletionCode.RETURN);
                        }
                    }
                }
                throw new TclNumArgsException(interp, 2, objv, "slavePath slaveCmd ?masterPath masterCmd? ?args ..?");
            }

            case OPT_ALIASES:
            {
                Interp slaveInterp = getInterp(interp, objv);
                InterpAliasCmd.list(interp, slaveInterp);
                break;
            }

            case OPT_CREATE:
            {
                // Weird historical rules: "-safe" is accepted at the end, too.

                bool safe = interp.isSafe;

                TclObject slaveNameObj = null;
                bool      last         = false;
                for (int i = 2; i < objv.Length; i++)
                {
                    if ((!last) && (objv[i].ToString()[0] == '-'))
                    {
                        int index = TclIndex.get(interp, objv[i], createOptions, "option", 0);
                        if (index == OPT_CREATE_SAFE)
                        {
                            safe = true;
                            continue;
                        }
                        i++;
                        last = true;
                    }
                    if (slaveNameObj != null)
                    {
                        throw new TclNumArgsException(interp, 2, objv, "?-safe? ?--? ?path?");
                    }
                    slaveNameObj = objv[i];
                }
                if (slaveNameObj == null)
                {
                    // Create an anonymous interpreter -- we choose its name and
                    // the name of the command. We check that the command name
                    // that we use for the interpreter does not collide with an
                    // existing command in the master interpreter.

                    int i = 0;
                    while (interp.getCommand("interp" + i) != null)
                    {
                        i++;
                    }
                    slaveNameObj = TclString.newInstance("interp" + i);
                }
                InterpSlaveCmd.create(interp, slaveNameObj, safe);
                interp.setResult(slaveNameObj);
                break;
            }

            case OPT_DELETE:
            {
                for (int i = 2; i < objv.Length; i++)
                {
                    Interp slaveInterp = getInterp(interp, objv[i]);

                    if (slaveInterp == interp)
                    {
                        throw new TclException(interp, "cannot delete the current interpreter");
                    }
                    InterpSlaveCmd slave = slaveInterp.slave;
                    slave.masterInterp.deleteCommandFromToken(slave.interpCmd);
                }
                break;
            }

            case OPT_EVAL:
            {
                if (objv.Length < 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path arg ?arg ...?");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.eval(interp, slaveInterp, 3, objv);
                break;
            }

            case OPT_EXISTS:
            {
                bool exists = true;

                try
                {
                    getInterp(interp, objv);
                }
                catch (TclException e)
                {
                    if (objv.Length > 3)
                    {
                        throw;
                    }
                    exists = false;
                }
                interp.setResult(exists);
                break;
            }

            case OPT_EXPOSE:
            {
                if (objv.Length < 4 || objv.Length > 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path hiddenCmdName ?cmdName?");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.expose(interp, slaveInterp, 3, objv);
                break;
            }

            case OPT_HIDE:
            {
                if (objv.Length < 4 || objv.Length > 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path cmdName ?hiddenCmdName?");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.hide(interp, slaveInterp, 3, objv);
                break;
            }

            case OPT_HIDDEN:
            {
                Interp slaveInterp = getInterp(interp, objv);
                InterpSlaveCmd.hidden(interp, slaveInterp);
                break;
            }

            case OPT_ISSAFE:
            {
                Interp slaveInterp = getInterp(interp, objv);
                interp.setResult(slaveInterp.isSafe);
                break;
            }

            case OPT_INVOKEHIDDEN:
            {
                bool global = false;
                int  i;
                for (i = 3; i < objv.Length; i++)
                {
                    if (objv[i].ToString()[0] != '-')
                    {
                        break;
                    }
                    int index = TclIndex.get(interp, objv[i], hiddenOptions, "option", 0);
                    if (index == OPT_HIDDEN_GLOBAL)
                    {
                        global = true;
                    }
                    else
                    {
                        i++;
                        break;
                    }
                }
                if (objv.Length - i < 1)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path ?-global? ?--? cmd ?arg ..?");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.invokeHidden(interp, slaveInterp, global, i, objv);
                break;
            }

            case OPT_MARKTRUSTED:
            {
                if (objv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.markTrusted(interp, slaveInterp);
                break;
            }

            case OPT_SLAVES:
            {
                Interp slaveInterp = getInterp(interp, objv);

                TclObject result = TclList.newInstance();
                interp.setResult(result);

                IEnumerator keys = slaveInterp.slaveTable.Keys.GetEnumerator();
                while (keys.MoveNext())
                {
                    string inString = (string)keys.Current;
                    TclList.append(interp, result, TclString.newInstance(inString));
                }

                break;
            }

            case OPT_SHARE:
            {
                if (objv.Length != 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "srcPath channelId destPath");
                }
                Interp masterInterp = getInterp(interp, objv[2]);


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

                Interp slaveInterp = getInterp(interp, objv[4]);
                TclIO.registerChannel(slaveInterp, chan);
                break;
            }

            case OPT_TARGET:
            {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path alias");
                }

                Interp slaveInterp = getInterp(interp, objv[2]);

                string aliasName    = objv[3].ToString();
                Interp targetInterp = InterpAliasCmd.getTargetInterp(slaveInterp, aliasName);
                if (targetInterp == null)
                {
                    throw new TclException(interp, "alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" not found");
                }
                if (!getInterpPath(interp, targetInterp))
                {
                    throw new TclException(interp, "target interpreter for alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" is not my descendant");
                }
                break;
            }

            case OPT_TRANSFER:
            {
                if (objv.Length != 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "srcPath channelId destPath");
                }
                Interp masterInterp = getInterp(interp, objv[2]);


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

                Interp slaveInterp = getInterp(interp, objv[4]);
                TclIO.registerChannel(slaveInterp, chan);
                TclIO.unregisterChannel(masterInterp, chan);
                break;
            }
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #23
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            int    i, mode, body;
            bool   matched;
            string inString;

            TclObject[] switchArgv = null;

            mode = EXACT;
            for (i = 1; i < argv.Length; i++)
            {
                if (!argv[i].ToString().StartsWith("-"))
                {
                    break;
                }
                int opt = TclIndex.get(interp, argv[i], validCmds, "option", 1);
                if (opt == LAST)
                {
                    i++;
                    break;
                }
                else if (opt > LAST)
                {
                    throw new TclException(interp, "SwitchCmd.cmdProc: bad option " + opt + " index to validCmds");
                }
                else
                {
                    mode = opt;
                }
            }

            if (argv.Length - i < 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "?switches? string pattern body ... ?default body?");
            }

            inString = argv[i].ToString();
            i++;

            // If all of the pattern/command pairs are lumped into a single
            // argument, split them out again.

            if (argv.Length - i == 1)
            {
                switchArgv = TclList.getElements(interp, argv[i]);
                i          = 0;
            }
            else
            {
                switchArgv = argv;
            }

            for ( ; i < switchArgv.Length; i += 2)
            {
                if (i == (switchArgv.Length - 1))
                {
                    throw new TclException(interp, "extra switch pattern with no body");
                }

                // See if the pattern matches the string.

                matched = false;

                string pattern = switchArgv[i].ToString();

                if ((i == switchArgv.Length - 2) && pattern.Equals("default"))
                {
                    matched = true;
                }
                else
                {
                    switch (mode)
                    {
                    case EXACT:
                        matched = inString.Equals(pattern);
                        break;

                    case GLOB:
                        matched = Util.stringMatch(inString, pattern);
                        break;

                    case REGEXP:
                        matched = Util.regExpMatch(interp, inString, switchArgv[i]);
                        break;
                    }
                }
                if (!matched)
                {
                    continue;
                }

                // We've got a match.  Find a body to execute, skipping bodies
                // that are "-".

                for (body = i + 1; ; body += 2)
                {
                    if (body >= switchArgv.Length)
                    {
                        throw new TclException(interp, "no body specified for pattern \"" + switchArgv[i] + "\"");
                    }

                    if (!switchArgv[body].ToString().Equals("-"))
                    {
                        break;
                    }
                }

                try
                {
                    interp.eval(switchArgv[body], 0);
                    return(TCL.CompletionCode.RETURN);
                }
                catch (TclException e)
                {
                    if (e.getCompletionCode() == TCL.CompletionCode.ERROR)
                    {
                        interp.addErrorInfo("\n    (\"" + switchArgv[i] + "\" arm line " + interp.errorLine + ")");
                    }
                    throw;
                }
            }

            // Nothing matched:  return nothing.
            return(TCL.CompletionCode.RETURN);
        }
Пример #24
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            bool noComplain = false; // If false, error msg will be returned
            int  index;              // index of the char just after the end
            //   of the user name
            int       firstArg = 1;  // index of the first non-switch arg
            int       i;             // generic index
            string    arg;           // generic arg string
            string    head = "";     // abs path of user name if provided
            string    tail = "";     // the remaining file path and pattern
            TclObject resultList;    // list of files that match the pattern

            for (bool last = false; (firstArg < argv.Length) && (!last); firstArg++)
            {
                if (!argv[firstArg].ToString().StartsWith("-"))
                {
                    break;
                }
                int opt = TclIndex.get(interp, argv[firstArg], validOptions, "switch", 1);
                switch (opt)
                {
                case OPT_NOCOMPLAIN:
                    noComplain = true;
                    break;

                case OPT_LAST:
                    last = true;
                    break;

                default:
                    throw new TclException(interp, "GlobCmd.cmdProc: bad option " + opt + " index to validOptions");
                }
            }

            if (firstArg >= argv.Length)
            {
                throw new TclNumArgsException(interp, 1, argv, "?switches? name ?name ...?");
            }

            resultList = TclList.newInstance();
            resultList.preserve();

            for (i = firstArg; i < argv.Length; i++)
            {
                arg = argv[i].ToString();

                string separators; // The system-specific file separators
                switch (JACL.PLATFORM)
                {
                case JACL.PLATFORM_WINDOWS:
                    separators = "/\\:";
                    break;

                case JACL.PLATFORM_MAC:
                    if (arg.IndexOf((System.Char) ':') == -1)
                    {
                        separators = "/";
                    }
                    else
                    {
                        separators = ":";
                    }
                    break;

                default:
                    separators = "/";
                    break;
                }

                // Perform tilde substitution, if needed.

                index = 0;
                if (arg.StartsWith("~"))
                {
                    // Find the first path separator after the tilde.

                    for ( ; index < arg.Length; index++)
                    {
                        char c = arg[index];
                        if (c == '\\')
                        {
                            if (separators.IndexOf((System.Char)arg[index + 1]) != -1)
                            {
                                break;
                            }
                        }
                        else if (separators.IndexOf((System.Char)c) != -1)
                        {
                            break;
                        }
                    }

                    // Determine the home directory for the specified user.  Note
                    // that we don't allow special characters in the user name.

                    if (strpbrk(arg.Substring(1, (index) - (1)).ToCharArray(), specCharArr) < 0)
                    {
                        try
                        {
                            head = FileUtil.doTildeSubst(interp, arg.Substring(1, (index) - (1)));
                        }
                        catch (TclException e)
                        {
                            if (noComplain)
                            {
                                head = null;
                            }
                            else
                            {
                                throw new TclException(interp, e.Message);
                            }
                        }
                    }
                    else
                    {
                        if (!noComplain)
                        {
                            throw new TclException(interp, "globbing characters not supported in user names");
                        }
                        head = null;
                    }

                    if ((System.Object)head == null)
                    {
                        if (noComplain)
                        {
                            interp.setResult("");
                            return(TCL.CompletionCode.RETURN);
                        }
                        else
                        {
                            return(TCL.CompletionCode.RETURN);
                        }
                    }
                    if (index != arg.Length)
                    {
                        index++;
                    }
                }

                tail = arg.Substring(index);

                try
                {
                    doGlob(interp, separators, new StringBuilder(head), tail, resultList);
                }
                catch (TclException e)
                {
                    if (noComplain)
                    {
                        continue;
                    }
                    else
                    {
                        throw new TclException(interp, e.Message);
                    }
                }
            }

            // If the list is empty and the nocomplain switch was not set then
            // generate and throw an exception.  Always release the TclList upon
            // completion.

            try
            {
                if ((TclList.getLength(interp, resultList) == 0) && !noComplain)
                {
                    string        sep = "";
                    StringBuilder ret = new StringBuilder();

                    ret.Append("no files matched glob pattern");
                    ret.Append((argv.Length == 2) ? " \"" : "s \"");

                    for (i = firstArg; i < argv.Length; i++)
                    {
                        ret.Append(sep + argv[i].ToString());
                        if (i == firstArg)
                        {
                            sep = " ";
                        }
                    }
                    ret.Append("\"");
                    throw new TclException(interp, ret.ToString());
                }
                else if (TclList.getLength(interp, resultList) > 0)
                {
                    interp.setResult(resultList);
                }
            }
            finally
            {
                resultList.release();
            }
            return(TCL.CompletionCode.RETURN);
        }