예제 #1
0
        /// <summary>
        /// Tcl_LappendObjCmd -> LappendCmd.cmdProc
        ///
        /// This procedure is invoked to process the "lappend" Tcl command.
        /// See the user documentation for details on what it does.
        /// </summary>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            TclObject varValue, newValue = null;
            int       i;//int numElems, i, j;
            bool      createdNewObj, createVar;

            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "varName ?value value ...?");
            }
            if (objv.Length == 2)
            {
                try
                {
                    newValue = interp.getVar(objv[1], 0);
                }
                catch (TclException e)
                {
                    // The variable doesn't exist yet. Just create it with an empty
                    // initial value.
                    varValue = TclList.newInstance();

                    try
                    {
                        newValue = interp.setVar(objv[1], varValue, 0);
                    }
                    finally
                    {
                        if (newValue == null)
                        {
                            varValue.release();                             // free unneeded object
                        }
                    }

                    interp.resetResult();
                    return(TCL.CompletionCode.RETURN);
                }
            }
            else
            {
                // We have arguments to append. We used to call Tcl_SetVar2 to
                // append each argument one at a time to ensure that traces were run
                // for each append step. We now append the arguments all at once
                // because it's faster. Note that a read trace and a write trace for
                // the variable will now each only be called once. Also, if the
                // variable's old value is unshared we modify it directly, otherwise
                // we create a new copy to modify: this is "copy on write".

                createdNewObj = false;
                createVar     = true;

                try
                {
                    varValue = interp.getVar(objv[1], 0);
                }
                catch (TclException e)
                {
                    // We couldn't read the old value: either the var doesn't yet
                    // exist or it's an array element. If it's new, we will try to
                    // create it with Tcl_ObjSetVar2 below.

                    // FIXME : not sure we even need this parse for anything!
                    // If we do not need to parse could we at least speed it up a bit

                    string varName;
                    int    nameBytes;


                    varName   = objv[1].ToString();
                    nameBytes = varName.Length;                     // Number of Unicode chars in string

                    for (i = 0; i < nameBytes; i++)
                    {
                        if (varName[i] == '(')
                        {
                            i = nameBytes - 1;
                            if (varName[i] == ')')
                            {
                                // last char is ')' => array ref
                                createVar = false;
                            }
                            break;
                        }
                    }
                    varValue      = TclList.newInstance();
                    createdNewObj = true;
                }

                // We only take this branch when the catch branch was not run
                if (createdNewObj == false && varValue.Shared)
                {
                    varValue      = varValue.duplicate();
                    createdNewObj = true;
                }

                // Insert the new elements at the end of the list.

                for (i = 2; i < objv.Length; i++)
                {
                    TclList.append(interp, varValue, objv[i]);
                }

                // No need to call varValue.invalidateStringRep() since it
                // is called during the TclList.append operation.

                // Now store the list object back into the variable. If there is an
                // error setting the new value, decrement its ref count if it
                // was new and we didn't create the variable.

                try
                {
                    newValue = interp.setVar(objv[1].ToString(), varValue, 0);
                }
                catch (TclException e)
                {
                    if (createdNewObj && !createVar)
                    {
                        varValue.release();                         // free unneeded obj
                    }
                    throw;
                }
            }

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

            interp.setResult(newValue);
            return(TCL.CompletionCode.RETURN);
        }
예제 #2
0
        /// <summary> This procedure is invoked to process the "split" Tcl
        /// command. See Tcl user documentation for details.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException If incorrect number of arguments.
        /// </exception>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            char[] splitChars = null;
            string inString;

            if (argv.Length == 2)
            {
                splitChars = defSplitChars;
            }
            else if (argv.Length == 3)
            {
                splitChars = argv[2].ToString().ToCharArray();
            }
            else
            {
                throw new TclNumArgsException(interp, 1, argv, "string ?splitChars?");
            }


            inString = argv[1].ToString();
            int len = inString.Length;
            int num = splitChars.Length;

            /*
             * Handle the special case of splitting on every character.
             */

            if (num == 0)
            {
                TclObject list = TclList.newInstance();

                list.preserve();
                try
                {
                    for (int i = 0; i < len; i++)
                    {
                        TclList.append(interp, list, TclString.newInstance(inString[i]));
                    }
                    interp.setResult(list);
                }
                finally
                {
                    list.release();
                }
                return(TCL.CompletionCode.RETURN);
            }

            /*
             * Normal case: split on any of a given set of characters.
             * Discard instances of the split characters.
             */
            TclObject list2     = TclList.newInstance();
            int       elemStart = 0;

            list2.preserve();
            try
            {
                int i, j;
                for (i = 0; i < len; i++)
                {
                    char c = inString[i];
                    for (j = 0; j < num; j++)
                    {
                        if (c == splitChars[j])
                        {
                            TclList.append(interp, list2, TclString.newInstance(inString.Substring(elemStart, (i) - (elemStart))));
                            elemStart = i + 1;
                            break;
                        }
                    }
                }
                if (i != 0)
                {
                    TclList.append(interp, list2, TclString.newInstance(inString.Substring(elemStart)));
                }
                interp.setResult(list2);
            }
            finally
            {
                list2.release();
            }
            return(TCL.CompletionCode.RETURN);
        }
예제 #3
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);
        }
        internal static Interp create(Interp interp, TclObject path, bool safe)
        {
            Interp masterInterp;
            string pathString;

            TclObject[] objv = TclList.getElements(interp, path);

            if (objv.Length < 2)
            {
                masterInterp = interp;

                pathString = path.ToString();
            }
            else
            {
                TclObject obj = TclList.newInstance();

                TclList.insert(interp, obj, 0, objv, 0, objv.Length - 2);
                masterInterp = InterpCmd.getInterp(interp, obj);

                pathString = objv[objv.Length - 1].ToString();
            }
            if (!safe)
            {
                safe = masterInterp.isSafe;
            }

            if (masterInterp.slaveTable.ContainsKey(pathString))
            {
                throw new TclException(interp, "interpreter named \"" + pathString + "\" already exists, cannot create");
            }

            Interp         slaveInterp = new Interp();
            InterpSlaveCmd slave       = new InterpSlaveCmd();

            slaveInterp.slave = slave;
            slaveInterp.setAssocData("InterpSlaveCmd", slave);

            slave.masterInterp = masterInterp;
            slave.path         = pathString;
            slave.slaveInterp  = slaveInterp;

            masterInterp.createCommand(pathString, slaveInterp.slave);
            slaveInterp.slave.interpCmd = NamespaceCmd.findCommand(masterInterp, pathString, null, 0);

            SupportClass.PutElement(masterInterp.slaveTable, pathString, slaveInterp.slave);

            slaveInterp.setVar("tcl_interactive", "0", TCL.VarFlag.GLOBAL_ONLY);

            // Inherit the recursion limit.

            slaveInterp.maxNestingDepth = masterInterp.maxNestingDepth;

            if (safe)
            {
                try
                {
                    makeSafe(slaveInterp);
                }
                catch (TclException e)
                {
                    SupportClass.WriteStackTrace(e, Console.Error);
                }
            }
            else
            {
                //Tcl_Init(slaveInterp);
            }

            return(slaveInterp);
        }
예제 #5
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));
                    }
                    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 (System.IO.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);
        }
예제 #6
0
파일: FileCmd.cs 프로젝트: ekicyou/pasta
        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;
            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 (File.Exists(fileObj.FullName))
                {
                    tmpBool = true;
                }
                else
                {
                    tmpBool = Directory.Exists(fileObj.FullName);
                }
                if (tmpBool)
                {
                    isExe = 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 (File.Exists(fileObj.FullName))
                {
                    tmpBool2 = true;
                }
                else
                {
                    tmpBool2 = 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(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(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 (File.Exists(fileObj.FullName))
                {
                    tmpBool3 = true;
                }
                else
                {
                    tmpBool3 = 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
                {
                    FileInfo[] roots = (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");
            }
        }
예제 #7
0
파일: FileUtil.cs 프로젝트: ekicyou/pasta
        internal static TclObject splitPath(Interp interp, string path)
        {
            TclObject resultListObj = TclList.newInstance();
            TclObject componentObj;
            string    component = "";
            string    tmpPath;
            bool      foundComponent    = false;
            bool      convertDotToColon = false;
            bool      isColonSeparator  = false;
            bool      appendColon       = false;
            bool      prependColon      = false;
            string    thisDir           = "./";

            // If the path is the empty string, returnan empty result list.

            if (path.Length == 0)
            {
                return(resultListObj);
            }

            // Handling the 1st component is file system dependent.

            switch (JACL.PLATFORM)
            {
            case JACL.PLATFORM_WINDOWS:
                tmpPath = path.Replace('\\', '/');

                StringBuilder absBuf   = new StringBuilder(0);
                int           absIndex = getWinAbsPath(tmpPath, absBuf);
                if (absIndex > 0)
                {
                    componentObj = TclString.newInstance(absBuf.ToString());
                    TclList.append(interp, resultListObj, componentObj);
                    tmpPath        = tmpPath.Substring(absIndex);
                    foundComponent = true;
                }
                break;


            case JACL.PLATFORM_MAC:

                tmpPath = "";
                thisDir = ":";

                switch (path.IndexOf((System.Char) ':'))
                {
                case -1:

                    if (path[0] != '/')
                    {
                        tmpPath           = path;
                        convertDotToColon = true;
                        if (path[0] == '~')
                        {
                            // If '~' is the first char, then append a colon to end
                            // of the 1st component.

                            appendColon = true;
                        }
                        break;
                    }
                    int degenIndex = getDegenerateUnixPath(path);
                    if (degenIndex < path.Length)
                    {
                        // First component of absolute unix path is followed by a ':',
                        // instead of being preceded by a degenerate unix-style
                        // pattern.


                        tmpPath           = path.Substring(degenIndex);
                        convertDotToColon = true;
                        appendColon       = true;
                        break;
                    }

                    // Degenerate unix path can't be split.  Return a list with one
                    // element:  ":" prepended to "path".

                    componentObj = TclString.newInstance(":" + path);
                    TclList.append(interp, resultListObj, componentObj);
                    return(resultListObj);

                case 0:

                    if (path.Length == 1)
                    {
                        // If path == ":", then return a list with ":" as its only
                        // element.

                        componentObj = TclString.newInstance(":");
                        TclList.append(interp, resultListObj, componentObj);
                        return(resultListObj);
                    }


                    // For each component, if slashes exist in the remaining filename,
                    // prepend a colon to the component.  Since this path is relative,
                    // pretend that we have already processed 1 components so a
                    // tilde-prefixed 1st component will have ":" prepended to it.


                    tmpPath          = path.Substring(1);
                    foundComponent   = true;
                    prependColon     = true;
                    isColonSeparator = true;
                    break;


                default:

                    tmpPath          = path;
                    appendColon      = true;
                    prependColon     = true;
                    isColonSeparator = true;
                    break;
                }
                break;


            default:

                if (path[0] == '/')
                {
                    componentObj = TclString.newInstance("/");
                    TclList.append(interp, resultListObj, componentObj);
                    tmpPath        = path.Substring(1);
                    foundComponent = true;
                }
                else
                {
                    tmpPath = path;
                }
                break;
            }

            // Iterate over all of the components of the path.

            int sIndex = 0;

            while (sIndex != -1)
            {
                if (isColonSeparator)
                {
                    sIndex = tmpPath.IndexOf(":");
                    // process adjacent ':'

                    if (sIndex == 0)
                    {
                        componentObj = TclString.newInstance("::");
                        TclList.append(interp, resultListObj, componentObj);
                        foundComponent = true;
                        tmpPath        = tmpPath.Substring(sIndex + 1);
                        continue;
                    }
                }
                else
                {
                    sIndex = tmpPath.IndexOf("/");
                    // Ignore a redundant '/'

                    if (sIndex == 0)
                    {
                        tmpPath = tmpPath.Substring(sIndex + 1);
                        continue;
                    }
                }
                if (sIndex == -1)
                {
                    // Processing the last component.  If it is empty, exit loop.

                    if (tmpPath.Length == 0)
                    {
                        break;
                    }
                    component = tmpPath;
                }
                else
                {
                    component = tmpPath.Substring(0, (sIndex) - (0));
                }

                if (convertDotToColon && (component.Equals(".") || component.Equals("..")))
                {
                    // If platform = MAC, convert .. to :: or . to :

                    component = component.Replace('.', ':');
                }
                if (foundComponent)
                {
                    if (component[0] == '~')
                    {
                        // If a '~' preceeds a component (other than the 1st one), then
                        // prepend "./" or ":" to the component.

                        component = thisDir + component;
                    }
                    else if (prependColon)
                    {
                        // If the prependColon flag is set, either unset it or prepend
                        // ":" to the component, depending on whether any '/'s remain
                        // in tmpPath.

                        if (tmpPath.IndexOf((System.Char) '/') == -1)
                        {
                            prependColon = false;
                        }
                        else
                        {
                            component = ":" + component;
                        }
                    }
                }
                else if (appendColon)
                {
                    //If platform = MAC, append a ':' to the first component.

                    component = component + ":";
                }
                componentObj = TclString.newInstance(component);
                TclList.append(interp, resultListObj, componentObj);
                foundComponent = true;
                tmpPath        = tmpPath.Substring(sIndex + 1);
            }
            return(resultListObj);
        }
예제 #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)var.value;
                    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
        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);
        }
예제 #10
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);
        }
예제 #11
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            int firstWord;            /* Index to the first non-switch arg */
            int argLen = argv.Length; /* No of args to copy to argStrs     */
            int exit;                 /* denotes exit status of process    */
            int errorBytes = 0;       /* number of bytes of process stderr */

            //bool background; /* Indicates a bg process            */
            //bool keepNewline; /* Retains newline in pipline output */
            System.Diagnostics.Process p; /* The exec-ed process               */
            string        argStr;         /* Conversion of argv to a string    */
            StringBuilder sbuf;

            /*
             * Check for a leading "-keepnewline" argument.
             */

            for (firstWord = 1; firstWord < argLen; firstWord++)
            {
                argStr = argv[firstWord].ToString();
                if ((argStr.Length > 0) && (argStr[0] == '-'))
                {
                    //if (argStr.Equals("-keepnewline"))
                    //{
                    //  keepNewline = true;
                    //}
                    //else
                    if (argStr.Equals("--"))
                    {
                        firstWord++;
                        break;
                    }
                    else
                    {
                        throw new TclException(interp, "bad switch \"" + argStr + "\": must be -keepnewline or --");
                    }
                }
            }

            if (argLen <= firstWord)
            {
                throw new TclNumArgsException(interp, 1, argv, "?switches? arg ?arg ...?");
            }


            /*
             * See if the command is to be run in background.
             * Currently this does nothing, it is just for compatibility
             */


            //if (argv[argLen - 1].ToString().Equals("&"))
            //{
            //  argLen--;
            //  background = true;
            //}

            try
            {
                /*
                 * It is necessary to perform system specific
                 * operations before calling exec.  For now Solaris
                 * and Windows execs are somewhat supported, in all other cases
                 * we simply call exec and give it our "best shot"
                 */

                if (execMethod != null)
                {
                    p = execReflection(interp, argv, firstWord, argLen);
                }
                else if (Util.Unix)
                {
                    p = execUnix(interp, argv, firstWord, argLen);
                }
                else if (Util.Windows)
                {
                    p = execWin(interp, argv, firstWord, argLen);
                }
                else
                {
                    p = execDefault(interp, argv, firstWord, argLen);
                }


                //note to self : buffer reading should be done in
                //a separate thread and not by calling waitFor()
                //because a process that is waited for can block


                //Wait for the process to finish running,
                try
                {
                    p.Start();
                    p.WaitForExit();
                    exit = p.ExitCode;
                }
                catch (Exception e)
                {
                    throw new TclException(interp, "exception in exec process: " + e.Message);
                }


                //Make buffer for the results of the subprocess execution
                sbuf = new StringBuilder();

                //read data on stdout stream into  result buffer
                readStreamIntoBuffer(p.StandardOutput.BaseStream, sbuf);

                //if there is data on the stderr stream then append
                //this data onto the result StringBuffer
                //check for the special case where there is no error
                //data but the process returns an error result

                errorBytes = readStreamIntoBuffer(p.StandardError.BaseStream, sbuf);

                if ((errorBytes == 0) && (exit != 0))
                {
                    sbuf.Append("child process exited abnormally");
                }

                //If the last character of the result buffer is a newline, then
                //remove the newline character (the newline would just confuse
                //things).  Finally, we set pass the result to the interpreter.



                // Tcl supports lots of child status conditions.
                // Unfortunately, we can only find the child's
                // exit status using the Java API

                if (exit != 0)
                {
                    TclObject childstatus = TclList.newInstance();
                    TclList.append(interp, childstatus, TclString.newInstance("CHILDSTATUS"));

                    // We don't know how to find the child's pid
                    TclList.append(interp, childstatus, TclString.newInstance("?PID?"));

                    TclList.append(interp, childstatus, TclInteger.newInstance(exit));

                    interp.setErrorCode(childstatus);
                }

                //when the subprocess writes to its stderr stream or returns
                //a non zero result we generate an error
                if ((exit != 0) || (errorBytes != 0))
                {
                    throw new TclException(interp, sbuf.ToString());
                }

                //otherwise things went well so set the result
                interp.setResult(sbuf.ToString());
            }
            catch (IOException e)
            {
                //if exec fails we end up catching the exception here


                throw new TclException(interp, "couldn't execute \"" + argv[firstWord].ToString() + "\": no such file or directory");
            }
            catch (System.Threading.ThreadInterruptedException e)
            {
                /*
                 * Do Nothing...
                 */
            }
            return(TCL.CompletionCode.RETURN);
        }
예제 #12
0
파일: GlobCmd.cs 프로젝트: ekicyou/pasta
        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);
        }
예제 #13
0
파일: AfterCmd.cs 프로젝트: ekicyou/pasta
        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);
        }
예제 #14
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);
        }
예제 #15
0
        /*
         *----------------------------------------------------------------------
         *
         * InfoCommandsCmd --
         *
         *	Called to implement the "info commands" command that returns the
         *	list of commands in the interpreter that match an optional pattern.
         *	The pattern, if any, consists of an optional sequence of namespace
         *	names separated by "::" qualifiers, which is followed by a
         *	glob-style pattern that restricts which commands are returned.
         *	Handles the following syntax:
         *
         *          info commands ?pattern?
         *
         * Results:
         *      Returns if successful, raises TclException otherwise.
         *
         * Side effects:
         *      Returns a result in the interpreter's result object.
         *
         *----------------------------------------------------------------------
         */

        private static void  InfoCommandsCmd(Interp interp, TclObject[] objv)
        {
            string cmdName, pattern, simplePattern;
            IDictionaryEnumerator search;

            NamespaceCmd.Namespace ns;
            NamespaceCmd.Namespace globalNs = NamespaceCmd.getGlobalNamespace(interp);
            NamespaceCmd.Namespace currNs = NamespaceCmd.getCurrentNamespace(interp);
            TclObject      list, elemObj;
            bool           specificNsInPattern = false;   // Init. to avoid compiler warning.
            WrappedCommand cmd;

            // Get the pattern and find the "effective namespace" in which to
            // list commands.

            if (objv.Length == 2)
            {
                simplePattern       = null;
                ns                  = currNs;
                specificNsInPattern = false;
            }
            else if (objv.Length == 3)
            {
                // From the pattern, get the effective namespace and the simple
                // pattern (no namespace qualifiers or ::'s) at the end. If an
                // error was found while parsing the pattern, return it. Otherwise,
                // if the namespace wasn't found, just leave ns NULL: we will
                // return an empty list since no commands there can be found.


                pattern = objv[2].ToString();

                // Java does not support passing an address so we pass
                // an array of size 1 and then assign arr[0] to the value
                NamespaceCmd.Namespace[] nsArr     = new NamespaceCmd.Namespace[1];
                NamespaceCmd.Namespace[] dummy1Arr = new NamespaceCmd.Namespace[1];
                NamespaceCmd.Namespace[] dummy2Arr = new NamespaceCmd.Namespace[1];
                string[] simplePatternArr          = new string[1];

                NamespaceCmd.getNamespaceForQualName(interp, pattern, null, 0, nsArr, dummy1Arr, dummy2Arr, simplePatternArr);

                // Get the values out of the arrays!
                ns            = nsArr[0];
                simplePattern = simplePatternArr[0];

                if (ns != null)
                {
                    // we successfully found the pattern's ns
                    specificNsInPattern = (simplePattern.CompareTo(pattern) != 0);
                }
            }
            else
            {
                throw new TclNumArgsException(interp, 2, objv, "?pattern?");
            }

            // Scan through the effective namespace's command table and create a
            // list with all commands that match the pattern. If a specific
            // namespace was requested in the pattern, qualify the command names
            // with the namespace name.

            list = TclList.newInstance();

            if (ns != null)
            {
                search = ns.cmdTable.GetEnumerator();
                while (search.MoveNext())
                {
                    cmdName = ((string)search.Key);
                    if (((System.Object)simplePattern == null) || Util.stringMatch(cmdName, simplePattern))
                    {
                        if (specificNsInPattern)
                        {
                            cmd     = (WrappedCommand)search.Value;
                            elemObj = TclString.newInstance(interp.getCommandFullName(cmd));
                        }
                        else
                        {
                            elemObj = TclString.newInstance(cmdName);
                        }
                        TclList.append(interp, list, elemObj);
                    }
                }

                // If the effective namespace isn't the global :: namespace, and a
                // specific namespace wasn't requested in the pattern, then add in
                // all global :: commands that match the simple pattern. Of course,
                // we add in only those commands that aren't hidden by a command in
                // the effective namespace.

                if ((ns != globalNs) && !specificNsInPattern)
                {
                    search = globalNs.cmdTable.GetEnumerator();
                    while (search.MoveNext())
                    {
                        cmdName = ((string)search.Key);
                        if (((System.Object)simplePattern == null) || Util.stringMatch(cmdName, simplePattern))
                        {
                            if (ns.cmdTable[cmdName] == null)
                            {
                                TclList.append(interp, list, TclString.newInstance(cmdName));
                            }
                        }
                    }
                }
            }

            interp.setResult(list);
            return;
        }
예제 #16
0
        /*
         *----------------------------------------------------------------------
         *
         * InfoVarsCmd --
         *
         *	Called to implement the "info vars" command that returns the
         *	list of variables in the interpreter that match an optional pattern.
         *	The pattern, if any, consists of an optional sequence of namespace
         *	names separated by "::" qualifiers, which is followed by a
         *	glob-style pattern that restricts which variables are returned.
         *	Handles the following syntax:
         *
         *          info vars ?pattern?
         *
         * Results:
         *      Returns if successful, raises TclException otherwise.
         *
         * Side effects:
         *      Returns a result in the interpreter's result object.
         *
         *----------------------------------------------------------------------
         */

        private static void  InfoVarsCmd(Interp interp, TclObject[] objv)
        {
            string varName, pattern, simplePattern;
            IDictionaryEnumerator search;
            Var var;

            NamespaceCmd.Namespace ns;
            NamespaceCmd.Namespace globalNs = NamespaceCmd.getGlobalNamespace(interp);
            NamespaceCmd.Namespace currNs = NamespaceCmd.getCurrentNamespace(interp);
            TclObject list, elemObj;
            bool      specificNsInPattern = false;        // Init. to avoid compiler warning.

            // Get the pattern and find the "effective namespace" in which to
            // list variables. We only use this effective namespace if there's
            // no active Tcl procedure frame.

            if (objv.Length == 2)
            {
                simplePattern       = null;
                ns                  = currNs;
                specificNsInPattern = false;
            }
            else if (objv.Length == 3)
            {
                // From the pattern, get the effective namespace and the simple
                // pattern (no namespace qualifiers or ::'s) at the end. If an
                // error was found while parsing the pattern, return it. Otherwise,
                // if the namespace wasn't found, just leave ns = null: we will
                // return an empty list since no variables there can be found.


                pattern = objv[2].ToString();

                // Java does not support passing an address so we pass
                // an array of size 1 and then assign arr[0] to the value
                NamespaceCmd.Namespace[] nsArr     = new NamespaceCmd.Namespace[1];
                NamespaceCmd.Namespace[] dummy1Arr = new NamespaceCmd.Namespace[1];
                NamespaceCmd.Namespace[] dummy2Arr = new NamespaceCmd.Namespace[1];
                string[] simplePatternArr          = new string[1];

                NamespaceCmd.getNamespaceForQualName(interp, pattern, null, 0, nsArr, dummy1Arr, dummy2Arr, simplePatternArr);

                // Get the values out of the arrays!
                ns            = nsArr[0];
                simplePattern = simplePatternArr[0];

                if (ns != null)
                {
                    // we successfully found the pattern's ns
                    specificNsInPattern = (simplePattern.CompareTo(pattern) != 0);
                }
            }
            else
            {
                throw new TclNumArgsException(interp, 2, objv, "?pattern?");
            }

            // If the namespace specified in the pattern wasn't found, just return.

            if (ns == null)
            {
                return;
            }

            list = TclList.newInstance();

            if ((interp.varFrame == null) || !interp.varFrame.isProcCallFrame || specificNsInPattern)
            {
                // There is no frame pointer, the frame pointer was pushed only
                // to activate a namespace, or we are in a procedure call frame
                // but a specific namespace was specified. Create a list containing
                // only the variables in the effective namespace's variable table.

                search = ns.varTable.GetEnumerator();
                while (search.MoveNext())
                {
                    varName = ((string)search.Key);
                    var     = (Var)search.Value;
                    if (!var.isVarUndefined() || ((var.flags & VarFlags.NAMESPACE_VAR) != 0))
                    {
                        if (((System.Object)simplePattern == null) || Util.stringMatch(varName, simplePattern))
                        {
                            if (specificNsInPattern)
                            {
                                elemObj = TclString.newInstance(Var.getVariableFullName(interp, var));
                            }
                            else
                            {
                                elemObj = TclString.newInstance(varName);
                            }
                            TclList.append(interp, list, elemObj);
                        }
                    }
                }

                // If the effective namespace isn't the global :: namespace, and a
                // specific namespace wasn't requested in the pattern (i.e., the
                // pattern only specifies variable names), then add in all global ::
                // variables that match the simple pattern. Of course, add in only
                // those variables that aren't hidden by a variable in the effective
                // namespace.

                if ((ns != globalNs) && !specificNsInPattern)
                {
                    search = globalNs.varTable.GetEnumerator();
                    while (search.MoveNext())
                    {
                        varName = ((string)search.Key);
                        var     = (Var)search.Value;
                        if (!var.isVarUndefined() || ((var.flags & VarFlags.NAMESPACE_VAR) != 0))
                        {
                            if (((System.Object)simplePattern == null) || Util.stringMatch(varName, simplePattern))
                            {
                                // Skip vars defined in current namespace
                                if (ns.varTable[varName] == null)
                                {
                                    TclList.append(interp, list, TclString.newInstance(varName));
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                AppendLocals(interp, list, simplePattern, true);
            }

            interp.setResult(list);
            return;
        }