Ejemplo n.º 1
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    */

            System.Text.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 System.Text.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 (System.IO.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);
        }
Ejemplo n.º 2
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            int      i;
            Notifier notifier = (Notifier)interp.getNotifier();
            Object   info;

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

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

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

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

            bool isNumber = false;
            int  ms       = 0;

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

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

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

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

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

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

                assocData.handlers.Add(timerInfo);

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

                return(TCL.CompletionCode.RETURN);
            }

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

            int index;

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

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

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

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

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

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

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

                /*
                 * Cancel the handler.
                 */

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

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


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

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

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

                assocData.handlers.Add(idleInfo);

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


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

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

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


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

                interp.resetResult();
                interp.setResult(list2);
                break;
            }
            return(TCL.CompletionCode.RETURN);
        }
Ejemplo n.º 3
0
        /// <summary> Tcl_WriteChars -> write
        ///
        /// Write string data to the Channel.
        ///
        /// </summary>
        /// <param name="interp">is used for TclExceptions.
        /// </param>
        /// <param name="outStr">the String object to write.
        /// </param>

        public void write(Interp interp, string outStr)
        {
            write(interp, TclString.newInstance(outStr));
        }
Ejemplo n.º 4
0
            public override int processEvent(int flags)
            {
                // See if the command is a complete Tcl command

                if (Interp.commandComplete(command))
                {
                    if (tcl.lang.ConsoleThread.debug)
                    {
                        WriteLine("line was a complete command");
                    }

                    bool      eval_exception = true;
                    TclObject commandObj     = TclString.newInstance(command);

                    try
                    {
                        commandObj.preserve();
                        Enclosing_Instance.interp.recordAndEval(commandObj, 0);
                        eval_exception = false;
                    }
                    catch (TclException e)
                    {
                        if (tcl.lang.ConsoleThread.debug)
                        {
                            WriteLine("eval returned exceptional condition");
                        }

                        TCL.CompletionCode code = e.getCompletionCode();
                        switch (code)
                        {
                        case TCL.CompletionCode.ERROR:

                            Enclosing_Instance.putLine(Enclosing_Instance.err, Enclosing_Instance.interp.getResult().ToString());
                            break;

                        case TCL.CompletionCode.BREAK:
                            Enclosing_Instance.putLine(Enclosing_Instance.err, "invoked \"break\" outside of a loop");
                            break;

                        case TCL.CompletionCode.CONTINUE:
                            Enclosing_Instance.putLine(Enclosing_Instance.err, "invoked \"continue\" outside of a loop");
                            break;

                        default:
                            Enclosing_Instance.putLine(Enclosing_Instance.err, "command returned bad code: " + code);
                            break;
                        }
                    }
                    finally
                    {
                        commandObj.release();
                    }

                    if (!eval_exception)
                    {
                        if (tcl.lang.ConsoleThread.debug)
                        {
                            WriteLine("eval returned normally");
                        }


                        string evalResult = Enclosing_Instance.interp.getResult().ToString();

                        if (tcl.lang.ConsoleThread.debug)
                        {
                            WriteLine("eval result was \"" + evalResult + "\"");
                        }

                        if (evalResult.Length > 0)
                        {
                            Enclosing_Instance.putLine(Enclosing_Instance.out_Renamed, evalResult);
                        }
                    }

                    // Empty out the incoming command buffer
                    Enclosing_Instance.sbuf.Length = 0;

                    // See if the user set a custom shell prompt for the next command

                    TclObject prompt;

                    try
                    {
                        prompt = Enclosing_Instance.interp.getVar("tcl_prompt1", TCL.VarFlag.GLOBAL_ONLY);
                    }
                    catch (TclException e)
                    {
                        prompt = null;
                    }
                    if (prompt != null)
                    {
                        try
                        {
                            Enclosing_Instance.interp.eval(prompt.ToString(), TCL.EVAL_GLOBAL);
                        }
                        catch (TclException e)
                        {
                            Enclosing_Instance.put(Enclosing_Instance.out_Renamed, "% ");
                        }
                    }
                    else
                    {
                        Enclosing_Instance.put(Enclosing_Instance.out_Renamed, "% ");
                    }

                    return(1);
                }
                else
                {
                    // Interp.commandComplete() returned false

                    if (tcl.lang.ConsoleThread.debug)
                    {
                        WriteLine("line was not a complete command");
                    }

                    // We don't have a complete command yet. Print out a level 2
                    // prompt message and wait for further inputs.

                    TclObject prompt;

                    try
                    {
                        prompt = Enclosing_Instance.interp.getVar("tcl_prompt2", TCL.VarFlag.GLOBAL_ONLY);
                    }
                    catch (TclException)
                    {
                        prompt = null;
                    }
                    if (prompt != null)
                    {
                        try
                        {
                            Enclosing_Instance.interp.eval(prompt.ToString(), TCL.EVAL_GLOBAL);
                        }
                        catch (TclException e)
                        {
                            Enclosing_Instance.put(Enclosing_Instance.out_Renamed, "");
                        }
                    }
                    else
                    {
                        Enclosing_Instance.put(Enclosing_Instance.out_Renamed, "");
                    }

                    return(1);
                }
            } // end processEvent method
Ejemplo n.º 5
0
        /// <summary>----------------------------------------------------------------------
        ///
        /// Tcl_StringObjCmd -> StringCmd.cmdProc
        ///
        /// This procedure is invoked to process the "string" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// Results:
        /// None.
        ///
        /// Side effects:
        /// See the user documentation.
        ///
        /// ----------------------------------------------------------------------
        /// </summary>

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

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

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


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

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

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

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

                int match;

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

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

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

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

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

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

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


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

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

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

                int start = 0;

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

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

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


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


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

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

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


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

                bool      strict     = false;
                TclObject failVarObj = null;

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

                bool result = true;
                int  failat = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                            result = c < 0x80;
                            break;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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


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

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


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

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


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

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

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

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

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

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

                    break;
                }

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

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

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

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

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

                            // Adjust len to be full length of matched string

                            str1 = p - 1;

                            // Append the map value to the unicode string

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

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

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


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

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

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

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

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

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


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


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

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

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


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

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


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


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


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

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

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

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

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

                    interp.setResult(tstr);
                }
                break;
            }


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

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

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

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

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


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


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


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

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

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


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


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


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

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


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


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


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

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


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


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

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


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


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

                if (index > length1)
                {
                    index = length1 - 1;
                }
                if (index < 0)
                {
                    interp.setResult(0);
                    return(TCL.CompletionCode.RETURN);
                }
                for (cur = index; cur >= 0; cur--)
                {
                    char c = strArray[cur];
                    if (((1 << (int)System.Char.GetUnicodeCategory(c)) & WORD_BITS) == 0)
                    {
                        break;
                    }
                }
                if (cur != index)
                {
                    cur += 1;
                }
                interp.setResult(cur);
                break;
            }
            }
            return(TCL.CompletionCode.RETURN);
        }
Ejemplo n.º 6
0
 internal ParseResult(string s, int ni)
 {
     value = TclString.newInstance(s);
     value.preserve();
     nextIndex = ni;
 }
Ejemplo n.º 7
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);
        }
 public static void Tcl_DStringAppendElement(TclObject str, string append)
 {
     TclString.append(str, append);
 }
Ejemplo n.º 9
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;
        }
Ejemplo n.º 10
0
 public static void Tcl_DStringInit(ref TclObject str)
 {
     str = TclString.newInstance("");
     str.preserve();
 }
Ejemplo n.º 11
0
 public static TclObject Tcl_NewObj()
 {
     return(TclString.newInstance(""));
 }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
        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('\\', '/');

                System.Text.StringBuilder absBuf = new System.Text.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);
        }
Ejemplo n.º 14
0
 internal ParseResult(StringBuilder sbuf, int ni)
 {
     value = TclString.newInstance(sbuf.ToString());
     value.preserve();
     nextIndex = ni;
 }
Ejemplo n.º 15
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            bool all    = false;
            bool nocase = false;

            try
            {
                int i = 1;

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

                    case OPT_NOCASE:
                    {
                        nocase = true;
                        break;
                    }

                    case OPT_LAST:
                    {
                        goto opts_brk;
                    }
                    }
                }

opts_brk:
                ;


                TclObject exp = argv[i++];

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

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

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

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

                int    count = 0;
                string result;

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

                TclObject obj = TclString.newInstance(result);
                if (varName == null)
                {
                    interp.setResult(result);
                }
                else
                {
                    try
                    {
                        interp.setVar(varName, obj, 0);
                    }
                    catch (TclException e)
                    {
                        throw new TclException(interp, "couldn't set variable \"" + varName + "\"");
                    }
                    interp.setResult(count);
                }
            }
            catch (System.IndexOutOfRangeException e)
            {
                throw new TclNumArgsException(interp, 1, argv, "?switches? exp string subSpec ?varName?");
            }
            return(TCL.CompletionCode.RETURN);
        }
Ejemplo n.º 16
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;
        }
Ejemplo n.º 17
0
		/// <summary> Creates a TclObject with the given InternalRep and stringRep.
		/// This constructor is used by the TclString class only. No other place
		/// should call this constructor.
		/// 
		/// </summary>
		/// <param name="rep">the initial InternalRep for this object.
		/// </param>
		/// <param name="s">the initial string rep for this object.
		/// </param>
		protected internal TclObject(TclString rep, string s)
		{
			if (rep == null)
			{
				throw new TclRuntimeError("null InternalRep");
			}
			internalRep = rep;
			stringRep = s;
			refCount = 0;
		}
Ejemplo n.º 18
0
 /// <summary> Create an empty parsed word.</summary>
 internal ParseResult()
 {
     value = TclString.newInstance("");
     value.preserve();
 }