Esempio n. 1
0
        /// <summary> This procedure is invoked to process the "eof" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>

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

            if (argv.Length != 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId");
            }


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

            if (chan.eof())
            {
                interp.setResult(TclInteger.newInstance(1));
            }
            else
            {
                interp.setResult(TclInteger.newInstance(0));
            }
            return(TCL.CompletionCode.RETURN);
        }
Esempio n. 2
0
        /// <summary> This procedure is invoked to process the "tell" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>

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

            if (argv.Length != 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId");
            }


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

            try
            {
                interp.setResult(TclInteger.newInstance((int)chan.tell()));
            }
            catch (System.IO.IOException e)
            {
                throw new TclException(interp, "Error in TellCmd");
            }
            return(TCL.CompletionCode.RETURN);
        }
Esempio n. 3
0
        /// <summary> See Tcl user documentation for details.</summary>
        /// <exception cref=""> TclException If incorrect number of arguments.
        /// </exception>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length != 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "list");
            }
            interp.setResult(TclInteger.newInstance(TclList.getLength(interp, argv[1])));
            return(TCL.CompletionCode.RETURN);
        }
Esempio n. 4
0
        private static TclObject ScanNumber(byte[] src, int pos, int type)
        // Format character from "binary scan"
        {
            switch (type)
            {
            case 'c':
            {
                return(TclInteger.newInstance((sbyte)src[pos]));
            }

            case 's':
            {
                short value = (short)((src[pos] & 0xff) + ((src[pos + 1] & 0xff) << 8));
                return(TclInteger.newInstance((int)value));
            }

            case 'S':
            {
                short value = (short)((src[pos + 1] & 0xff) + ((src[pos] & 0xff) << 8));
                return(TclInteger.newInstance((int)value));
            }

            case 'i':
            {
                int value = (src[pos] & 0xff) + ((src[pos + 1] & 0xff) << 8) + ((src[pos + 2] & 0xff) << 16) + ((src[pos + 3] & 0xff) << 24);
                return(TclInteger.newInstance(value));
            }

            case 'I':
            {
                int value = (src[pos + 3] & 0xff) + ((src[pos + 2] & 0xff) << 8) + ((src[pos + 1] & 0xff) << 16) + ((src[pos] & 0xff) << 24);
                return(TclInteger.newInstance(value));
            }

            case 'f':
            {
                System.IO.MemoryStream ms     = new System.IO.MemoryStream(src, pos, 4, false);
                System.IO.BinaryReader reader = new System.IO.BinaryReader(ms);
                double fvalue = reader.ReadSingle();
                reader.Close();
                ms.Close();
                return(TclDouble.newInstance(fvalue));
            }

            case 'd':
            {
                System.IO.MemoryStream ms     = new System.IO.MemoryStream(src, pos, 8, false);
                System.IO.BinaryReader reader = new System.IO.BinaryReader(ms);
                double dvalue = reader.ReadDouble();
                reader.Close();
                ms.Close();
                return(TclDouble.newInstance(dvalue));
            }
            }
            return(null);
        }
Esempio n. 5
0
        /// <summary> This procedure is invoked to process the "catch" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException if wrong number of arguments.
        /// </exception>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length != 2 && argv.Length != 3)
            {
                throw new TclNumArgsException(interp, 1, argv, "command ?varName?");
            }

            TclObject result;

            TCL.CompletionCode code = TCL.CompletionCode.OK;

            try
            {
                interp.eval(argv[1], 0);
            }
            catch (TclException e)
            {
                code = e.getCompletionCode();
            }

            result = interp.getResult();

            if (argv.Length == 3)
            {
                try
                {
                    interp.setVar(argv[2], result, 0);
                }
                catch (TclException e)
                {
                    throw new TclException(interp, "couldn't save command result in variable");
                }
            }

            interp.resetResult();
            interp.setResult(TclInteger.newInstance((int)code));
            return(TCL.CompletionCode.RETURN);
        }
Esempio n. 6
0
        private static void  getAndStoreStatData(Interp interp, string fileName, string varName)
        {
            System.IO.FileInfo fileObj = FileUtil.getNewFileObj(interp, fileName);

            bool tmpBool;

            if (System.IO.File.Exists(fileObj.FullName))
            {
                tmpBool = true;
            }
            else
            {
                tmpBool = System.IO.Directory.Exists(fileObj.FullName);
            }
            if (!tmpBool)
            {
                throw new TclPosixException(interp, TclPosixException.ENOENT, true, "could not read \"" + fileName + "\"");
            }

            try
            {
                int       mtime    = getMtime(interp, fileName, fileObj);
                TclObject mtimeObj = TclInteger.newInstance(mtime);
                TclObject atimeObj = TclInteger.newInstance(mtime);
                TclObject ctimeObj = TclInteger.newInstance(mtime);
                interp.setVar(varName, "atime", atimeObj, 0);
                interp.setVar(varName, "ctime", ctimeObj, 0);
                interp.setVar(varName, "mtime", mtimeObj, 0);
            }
            catch (System.Security.SecurityException e)
            {
                throw new TclException(interp, e.Message);
            }
            catch (TclException e)
            {
                throw new TclException(interp, "can't set \"" + varName + "(dev)\": variable isn't array");
            }

            try
            {
                TclObject sizeObj = TclInteger.newInstance((int)SupportClass.FileLength(fileObj));
                interp.setVar(varName, "size", sizeObj, 0);
            }
            catch (System.Exception e)
            {
                // Do nothing.
            }

            try
            {
                TclObject typeObj = TclString.newInstance(getType(interp, fileName, fileObj));
                interp.setVar(varName, "type", typeObj, 0);
            }
            catch (System.Exception e)
            {
            }

            try
            {
                TclObject uidObj = TclBoolean.newInstance(isOwner(interp, fileObj));
                interp.setVar(varName, "uid", uidObj, 0);
            }
            catch (TclException e)
            {
                // Do nothing.
            }
        }
Esempio n. 7
0
        /// <summary> This procedure is invoked to process the "scan" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// Each iteration of the cmdProc compares the scanArr's current index to
        /// the frmtArr's index.  If the chars are equal then the indicies are
        /// incremented.  If a '%' is found in the frmtArr, the formatSpecifier
        /// is parced from the frmtArr, the corresponding value is extracted from
        /// the scanArr, and that value is set in the Tcl Interp.
        ///
        /// If the chars are not equal, or the conversion fails, the boolean
        /// scanArrDone is set to true, indicating the scanArr is not to be
        /// parced and no new values are to be set.  However the frmtArr is still
        /// parced because of the priority of error messages.  In the C version
        /// of Tcl, bad format specifiers throw errors before incorrect argument
        /// input or other scan errors.  Thus we need to parce the entire frmtArr
        /// to verify correct formating.  This is dumb and inefficient but it is
        /// consistent w/ the current C-version of Tcl.
        /// </summary>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length < 3)
            {
                throw new TclNumArgsException(interp, 1, argv, "string format ?varName varName ...?");
            }
            ;

            StrtoulResult strul;             // Return value for parcing the scanArr when
            // extracting integers/longs
            StrtodResult strd;;              // Return value for parcing the scanArr when

            // extracting doubles
            char[] scanArr;    // Array containing parce info
            char[] frmtArr;    // Array containing info on how to
            // parse the scanArr
            int  scanIndex;    // Index into the scan array
            int  frmtIndex;    // Index into the frmt array
            int  tempIndex;    // Temporary index holder
            int  argIndex;     // Index into the current arg
            int  width;        // Stores the user specified result width
            int  base_;        // Base of the integer being converted
            int  numUnMatched; // Number of fields actually set.
            int  numMatched;   // Number of fields actually matched.
            int  negateScan;   // Mult by result, set to -1 if true
            int  i;            // Generic variable
            char ch;           // Generic variable
            bool cont;         // Used in loops to indicate when to stop
            bool scanOK;       // Set to false if strtoul/strtod fails
            bool scanArrDone;  // Set to false if strtoul/strtod fails
            bool widthFlag;    // True is width is specified
            bool discardFlag;  // If a "%*" is in the formatString dont

            // write output to arg


            scanArr = argv[1].ToString().ToCharArray();

            frmtArr     = argv[2].ToString().ToCharArray();
            width       = base_ = numMatched = numUnMatched = 0;
            scanIndex   = frmtIndex = 0;
            scanOK      = true;
            scanArrDone = false;
            argIndex    = 3;

            // Skip all (if any) of the white space before getting to a char

            frmtIndex = skipWhiteSpace(frmtArr, frmtIndex);

            // Search through the frmtArr.  If the next char is a '%' parse the
            // next chars and determine the type (if any) of the format specifier.
            // If the scanArr has been fully searched, do nothing but incerment
            // "numUnMatched".  The reason to continue the frmtArr search is for
            // consistency in output.  Previously scan format errors were reported
            // before arg input mismatch, so this maintains the same level of error
            // checking.

            while (frmtIndex < frmtArr.Length)
            {
                discardFlag = widthFlag = false;
                negateScan  = 1;
                cont        = true;

                // Parce the format array and read in the correct value from the
                // scan array.  When the correct value is retrieved, set the
                // variable (from argv) in the interp.

                if (frmtArr[frmtIndex] == '%')
                {
                    frmtIndex++;
                    checkOverFlow(interp, frmtArr, frmtIndex);

                    // Two '%'s in a row, do nothing...

                    if (frmtArr[frmtIndex] == '%')
                    {
                        frmtIndex++;
                        scanIndex++;
                        continue;
                    }

                    // Check for a discard field flag

                    if (frmtArr[frmtIndex] == '*')
                    {
                        discardFlag = true;
                        frmtIndex++;
                        checkOverFlow(interp, frmtArr, frmtIndex);
                    }

                    // Check for a width field and accept the 'h', 'l', 'L'
                    // characters, but do nothing with them.
                    //
                    // Note: The order of the width specifier and the other
                    // chars is unordered, so we need to iterate until all
                    // of the specifiers are identified.

                    while (cont)
                    {
                        cont = false;

                        switch (frmtArr[frmtIndex])
                        {
                        case 'h':
                        case 'l':
                        case 'L':  {
                            // Just ignore these values

                            frmtIndex++;
                            cont = true;
                            break;
                        }

                        default:  {
                            if (System.Char.IsDigit(frmtArr[frmtIndex]))
                            {
                                strul     = Util.strtoul(new string(frmtArr), frmtIndex, base_);
                                frmtIndex = strul.index;
                                width     = (int)strul.value;
                                widthFlag = true;
                                cont      = true;
                            }
                        }
                        break;
                        }
                        checkOverFlow(interp, frmtArr, frmtIndex);
                    }

                    // On all conversion specifiers except 'c', move the
                    // scanIndex to the next non-whitespace.

                    ch = frmtArr[frmtIndex];
                    if ((ch != 'c') && (ch != '[') && !scanArrDone)
                    {
                        scanIndex = skipWhiteSpace(scanArr, scanIndex);
                    }
                    if (scanIndex >= scanArr.Length)
                    {
                        scanArrDone = true;
                    }

                    if ((scanIndex < scanArr.Length) && (ch != 'c') && (ch != '['))
                    {
                        // Since strtoul dosent take signed numbers, make the
                        // value positive and store the sign.

                        if (scanArr[scanIndex] == '-')
                        {
                            negateScan = -1;
                            scanIndex++;
                            width--;
                        }
                        else if (scanArr[scanIndex] == '+')
                        {
                            scanIndex++;
                            width--;
                        }

                        // The width+scanIndex might be greater than
                        // the scanArr so we need to re-adjust when this
                        // happens.

                        if (widthFlag && (width + scanIndex > scanArr.Length))
                        {
                            width = scanArr.Length - scanIndex;
                        }
                    }

                    if (scanIndex >= scanArr.Length)
                    {
                        scanArrDone = true;
                    }

                    // Foreach iteration we want strul and strd to be
                    // null since we error check on this case.

                    strul = null;
                    strd  = null;

                    switch (ch)
                    {
                    case 'd':
                    case 'o':
                    case 'x':  {
                        if (!scanArrDone)
                        {
                            if (ch == 'd')
                            {
                                base_ = 10;
                            }
                            else if (ch == 'o')
                            {
                                base_ = 8;
                            }
                            else
                            {
                                base_ = 16;
                            }

                            // If the widthFlag is set then convert only
                            // "width" characters to an ascii representation,
                            // else read in until the end of the integer.  The
                            // scanIndex is moved to the point where we stop
                            // reading in.

                            if (widthFlag)
                            {
                                strul = Util.strtoul(new string(scanArr, 0, width + scanIndex), scanIndex, base_);
                            }
                            else
                            {
                                strul = Util.strtoul(new string(scanArr), scanIndex, base_);
                            }
                            if (strul.errno != 0)
                            {
                                scanOK = false;
                                break;
                            }
                            scanIndex = strul.index;

                            if (!discardFlag)
                            {
                                i = (int)strul.value * negateScan;
                                if (argIndex == argv.Length)
                                {
                                    numMatched--;
                                }
                                else
                                {
                                    testAndSetVar(interp, argv, argIndex++, TclInteger.newInstance(i));
                                }
                            }
                        }
                        break;
                    }

                    case 'c':  {
                        if (widthFlag)
                        {
                            errorCharFieldWidth(interp);
                        }
                        if (!discardFlag && !scanArrDone)
                        {
                            testAndSetVar(interp, argv, argIndex++, TclInteger.newInstance(scanArr[scanIndex++]));
                        }
                        break;
                    }

                    case 's':  {
                        if (!scanArrDone)
                        {
                            // If the widthFlag is set then read only "width"
                            // characters into the string, else read in until
                            // the first whitespace or endArr is found.  The
                            // scanIndex is moved to the point where we stop
                            // reading in.

                            tempIndex = scanIndex;
                            if (!widthFlag)
                            {
                                width = scanArr.Length;
                            }
                            for (i = 0; (scanIndex < scanArr.Length) && (i < width); i++)
                            {
                                ch = scanArr[scanIndex];
                                if ((ch == ' ') || (ch == '\n') || (ch == '\r') || (ch == '\t') || (ch == '\f'))
                                {
                                    break;
                                }
                                scanIndex++;
                            }

                            if (!discardFlag)
                            {
                                string str = new string(scanArr, tempIndex, scanIndex - tempIndex);
                                testAndSetVar(interp, argv, argIndex++, TclString.newInstance(str));
                            }
                        }
                        break;
                    }

                    case 'e':
                    case 'f':
                    case 'g':  {
                        if (!scanArrDone)
                        {
                            // If the wisthFlag is set then read only "width"
                            // characters into the string, else read in until
                            // the first whitespace or endArr is found.  The
                            // scanIndex is moved to the point where we stop
                            // reading in.

                            if (widthFlag)
                            {
                                strd = Util.strtod(new string(scanArr, 0, width + scanIndex), scanIndex);
                            }
                            else
                            {
                                strd = Util.strtod(new string(scanArr), scanIndex);
                            }
                            if (strd.errno != 0)
                            {
                                scanOK = false;
                                break;
                            }
                            scanIndex = strd.index;

                            if (!discardFlag)
                            {
                                double d = strd.value * negateScan;
                                testAndSetVar(interp, argv, argIndex++, TclDouble.newInstance(d));
                            }
                        }
                        break;
                    }

                    case '[':  {
                        bool   charMatchFound = false;
                        bool   charNotMatch   = false;
                        char[] tempArr;
                        int    startIndex;
                        int    endIndex;
                        string unmatched = "unmatched [ in format string";

                        if ((++frmtIndex) >= frmtArr.Length)
                        {
                            throw new TclException(interp, unmatched);
                        }

                        if (frmtArr[frmtIndex] == '^')
                        {
                            charNotMatch = true;
                            frmtIndex   += 2;
                        }
                        else
                        {
                            frmtIndex++;
                        }
                        tempIndex = frmtIndex - 1;

                        if (frmtIndex >= frmtArr.Length)
                        {
                            throw new TclException(interp, unmatched);
                        }

                        // Extract the list of chars for matching.

                        while (frmtArr[frmtIndex] != ']')
                        {
                            if ((++frmtIndex) >= frmtArr.Length)
                            {
                                throw new TclException(interp, unmatched);
                            }
                        }
                        tempArr = new string(frmtArr, tempIndex, frmtIndex - tempIndex).ToCharArray();

                        startIndex = scanIndex;
                        if (charNotMatch)
                        {
                            // Format specifier contained a '^' so interate
                            // until one of the chars in tempArr is found.

                            while (scanOK && !charMatchFound)
                            {
                                if (scanIndex >= scanArr.Length)
                                {
                                    scanOK = false;
                                    break;
                                }
                                for (i = 0; i < tempArr.Length; i++)
                                {
                                    if (tempArr[i] == scanArr[scanIndex])
                                    {
                                        charMatchFound = true;
                                        break;
                                    }
                                }
                                if (widthFlag && ((scanIndex - startIndex) >= width))
                                {
                                    break;
                                }
                                if (!charMatchFound)
                                {
                                    scanIndex++;
                                }
                            }
                        }
                        else
                        {
                            // Iterate until the char in the scanArr is not
                            // in the tempArr.

                            charMatchFound = true;
                            while (scanOK && charMatchFound)
                            {
                                if (scanIndex >= scanArr.Length)
                                {
                                    scanOK = false;
                                    break;
                                }
                                charMatchFound = false;
                                for (i = 0; i < tempArr.Length; i++)
                                {
                                    if (tempArr[i] == scanArr[scanIndex])
                                    {
                                        charMatchFound = true;
                                        break;
                                    }
                                }
                                if (widthFlag && (scanIndex - startIndex) >= width)
                                {
                                    break;
                                }
                                if (charMatchFound)
                                {
                                    scanIndex++;
                                }
                            }
                        }

                        // Indicates nothing was found.

                        endIndex = scanIndex - startIndex;
                        if (endIndex <= 0)
                        {
                            scanOK = false;
                            break;
                        }

                        if (!discardFlag)
                        {
                            string str = new string(scanArr, startIndex, endIndex);
                            testAndSetVar(interp, argv, argIndex++, TclString.newInstance(str));
                        }
                        break;
                    }

                    default:  {
                        errorBadField(interp, ch);
                    }
                    break;
                    }

                    // As long as the scan was successful (scanOK), the format
                    // specifier did not contain a '*' (discardFlag), and
                    // we are not at the end of the scanArr (scanArrDone);
                    // increment the num of vars set in the interp.  Otherwise
                    // increment the number of valid format specifiers.

                    if (scanOK && !discardFlag && !scanArrDone)
                    {
                        numMatched++;
                    }
                    else if ((scanArrDone || !scanOK) && !discardFlag)
                    {
                        numUnMatched++;
                    }
                    frmtIndex++;
                }
                else if (scanIndex < scanArr.Length && scanArr[scanIndex] == frmtArr[frmtIndex])
                {
                    // No '%' was found, but the characters matched

                    scanIndex++;
                    frmtIndex++;
                }
                else
                {
                    // No '%' found and the characters int frmtArr & scanArr
                    // did not match.

                    frmtIndex++;
                }
            }

            // The numMatched is the return value: a count of the num of vars set.
            // While the numUnMatched is the number of formatSpecifiers that
            // passed the parsing stage, but did not match anything in the scanArr.

            if ((numMatched + numUnMatched) != (argv.Length - 3))
            {
                errorDiffVars(interp);
            }
            interp.setResult(TclInteger.newInstance(numMatched));
            return(TCL.CompletionCode.RETURN);
        }
 public static void Tcl_BackgroundError(Interp interp)
 {
     interp.setErrorCode(TclInteger.newInstance(TCL_ERROR));
     interp.addErrorInfo("Background Error");
 }
 public static TclObject Tcl_NewIntObj(int value)
 {
     return(TclInteger.newInstance(value));
 }
Esempio n. 10
0
        public TclObject get()
        {
            TclObject obj;
            TclToken  token;
            string    typeString;
            int       nextIndex;
            string    cmd;
            int       i;


            System.Diagnostics.Debug.WriteLine("Entered TclParse.get()");
            System.Diagnostics.Debug.WriteLine("numTokens is " + numTokens);

            obj = TclList.newInstance();
            try
            {
                if (commentSize > 0)
                {
                    TclList.append(interp, obj, TclString.newInstance(new string( inString, commentStart, commentSize )));
                }
                else
                {
                    TclList.append(interp, obj, TclString.newInstance("-"));
                }

                if (commandStart >= (endIndex + 1))
                {
                    commandStart = endIndex;
                }
                cmd = new string( inString, commandStart, commandSize );
                TclList.append(interp, obj, TclString.newInstance(cmd));
                TclList.append(interp, obj, TclInteger.newInstance(numWords));

                for (i = 0; i < numTokens; i++)
                {
                    System.Diagnostics.Debug.WriteLine("processing token " + i);

                    token = tokenList[i];
                    switch (token.type)
                    {
                    case Parser.TCL_TOKEN_WORD:
                        typeString = "word";
                        break;

                    case Parser.TCL_TOKEN_SIMPLE_WORD:
                        typeString = "simple";
                        break;

                    case Parser.TCL_TOKEN_EXPAND_WORD:
                        typeString = "expand";
                        break;

                    case Parser.TCL_TOKEN_TEXT:
                        typeString = "text";
                        break;

                    case Parser.TCL_TOKEN_BS:
                        typeString = "backslash";
                        break;

                    case Parser.TCL_TOKEN_COMMAND:
                        typeString = "command";
                        break;

                    case Parser.TCL_TOKEN_VARIABLE:
                        typeString = "variable";
                        break;

                    default:
                        typeString = "??";
                        break;
                    }

                    System.Diagnostics.Debug.WriteLine("typeString is " + typeString);

                    TclList.append(interp, obj, TclString.newInstance(typeString));
                    TclList.append(interp, obj, TclString.newInstance(token.TokenString));
                    TclList.append(interp, obj, TclInteger.newInstance(token.numComponents));
                }
                nextIndex = commandStart + commandSize;
                TclList.append(interp, obj, TclString.newInstance(new string( inString, nextIndex, (endIndex - nextIndex))));
            }
            catch (TclException e)
            {
                // Do Nothing.
            }

            return(obj);
        }
Esempio n. 11
0
        /// <summary> This procedure is invoked to process the "fconfigure" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>

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

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


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

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

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

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

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

                // -encoding

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

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

                // -eofchar

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

                    TclObject eofchar_pair = TclList.newInstance();

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

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

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

                // -translation

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

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

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

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

                interp.setResult(list);
            }

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

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

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

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

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

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

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

                        TclObject eofchar_pair = TclList.newInstance();

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

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

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

                    break;
                }

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

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

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

                    break;
                }

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

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

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

                case OPT_BUFFERING:
                {
                    // -buffering

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

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

                    chan.Buffering = id;
                    break;
                }

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

                case OPT_ENCODING:
                {
                    // -encoding

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

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

                    break;
                }

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

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

                    char   inputEofChar, outputEofChar;
                    string s;

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


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

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

                    break;
                }

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

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

                    string inputTranslationArg, outputTranslationArg;
                    int    inputTranslation, outputTranslation;

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

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

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

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

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

                    break;
                }

                default:
                {
                    throw new TclRuntimeError("Fconfigure.cmdProc() error: " + "incorrect index returned from TclIndex.get()");
                }
                }
            }
            return(TCL.CompletionCode.RETURN);
        }
Esempio n. 12
0
        public void traceProc(Interp interp, string name1, string name2, TCL.VarFlag flags)
        {
            // If the variable is unset, then recreate the trace and restore
            // the default value of the format string.

            if ((flags & TCL.VarFlag.TRACE_UNSETS) != 0)
            {
                if (((flags & TCL.VarFlag.TRACE_DESTROYED) != 0) && ((flags & TCL.VarFlag.INTERP_DESTROYED) == 0))
                {
                    interp.traceVar(name1, name2, new PrecTraceProc(), TCL.VarFlag.GLOBAL_ONLY | TCL.VarFlag.TRACE_WRITES | TCL.VarFlag.TRACE_READS | TCL.VarFlag.TRACE_UNSETS);
                    Util.precision = Util.DEFAULT_PRECISION;
                }
                return;
            }

            // When the variable is read, reset its value from our shared
            // value. This is needed in case the variable was modified in
            // some other interpreter so that this interpreter's value is
            // out of date.

            if ((flags & TCL.VarFlag.TRACE_READS) != 0)
            {
                interp.setVar(name1, name2, TclInteger.newInstance(Util.precision), flags & TCL.VarFlag.GLOBAL_ONLY);
                return;
            }

            // The variable is being written. Check the new value and disallow
            // it if it isn't reasonable.
            //
            // (ToDo) Disallow it if this is a safe interpreter (we don't want
            // safe interpreters messing up the precision of other
            // interpreters).

            TclObject tobj = null;

            try
            {
                tobj = interp.getVar(name1, name2, (flags & TCL.VarFlag.GLOBAL_ONLY));
            }
            catch (TclException e)
            {
                // Do nothing when var does not exist.
            }

            string value;

            if (tobj != null)
            {
                value = tobj.ToString();
            }
            else
            {
                value = "";
            }

            StrtoulResult r = Util.strtoul(value, 0, 10);

            if ((r == null) || (r.value <= 0) || (r.value > TCL_MAX_PREC) || (r.value > 100) || (r.index == 0) || (r.index != value.Length))
            {
                interp.setVar(name1, name2, TclInteger.newInstance(Util.precision), TCL.VarFlag.GLOBAL_ONLY);
                throw new TclException(interp, "improper value for precision");
            }

            Util.precision = (int)r.value;
        }
Esempio n. 13
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            bool nocase  = false;
            bool indices = false;

            try
            {
                int i = 1;

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

                    case OPT_NOCASE:  {
                        nocase = true;
                        break;
                    }

                    case OPT_LAST:  {
                        goto opts_brk;
                    }
                    }
                }

                opts_brk :;


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

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

                int matches = argv.Length - i;

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

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

                        int start = args[match++];
                        int end   = args[match++];
                        if (indices)
                        {
                            if (end >= 0)
                            {
                                end--;
                            }
                            obj = TclList.newInstance();
                            TclList.append(interp, obj, TclInteger.newInstance(start));
                            TclList.append(interp, obj, TclInteger.newInstance(end));
                        }
                        else
                        {
                            string range = (start >= 0)?inString.Substring(start, (end) - (start)):"";
                            obj = TclString.newInstance(range);
                        }
                        try
                        {
                            interp.setVar(argv[i].ToString(), obj, 0);
                        }
                        catch (TclException e)
                        {
                            throw new TclException(interp, "couldn't set variable \"" + argv[i] + "\"");
                        }
                    }
                }
                interp.setResult(matched);
            }
            catch (System.IndexOutOfRangeException e)
            {
                throw new TclNumArgsException(interp, 1, argv, "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
            }
            return(TCL.CompletionCode.RETURN);
        }
Esempio n. 14
0
        /// <summary>----------------------------------------------------------------------
        ///
        /// Tcl_StringObjCmd -> StringCmd.cmdProc
        ///
        /// This procedure is invoked to process the "string" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// Results:
        /// None.
        ///
        /// Side effects:
        /// See the user documentation.
        ///
        /// ----------------------------------------------------------------------
        /// </summary>

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

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

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


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

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

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

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

                int match;

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

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

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

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

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

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

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


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

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

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

                int start = 0;

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

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

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


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


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

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

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


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

                bool      strict     = false;
                TclObject failVarObj = null;

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

                bool result = true;
                int  failat = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                            result = c < 0x80;
                            break;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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


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

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


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

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


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

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

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

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

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

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

                    break;
                }

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

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

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

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

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

                            // Adjust len to be full length of matched string

                            str1 = p - 1;

                            // Append the map value to the unicode string

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

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

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


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

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

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

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

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

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


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


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

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

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


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

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


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


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


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

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

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

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

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

                    interp.setResult(tstr);
                }
                break;
            }


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

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

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

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

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


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


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


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

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

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


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


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


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

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


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


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


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

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


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


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

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


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


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

                if (index > length1)
                {
                    index = length1 - 1;
                }
                if (index < 0)
                {
                    interp.setResult(0);
                    return(TCL.CompletionCode.RETURN);
                }
                for (cur = index; cur >= 0; cur--)
                {
                    char c = strArray[cur];
                    if (((1 << (int)System.Char.GetUnicodeCategory(c)) & WORD_BITS) == 0)
                    {
                        break;
                    }
                }
                if (cur != index)
                {
                    cur += 1;
                }
                interp.setResult(cur);
                break;
            }
            }
            return(TCL.CompletionCode.RETURN);
        }
Esempio n. 15
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            int firstWord;            /* Index to the first non-switch arg */
            int argLen = argv.Length; /* No of args to copy to argStrs     */
            int exit;                 /* denotes exit status of process    */
            int errorBytes = 0;       /* number of bytes of process stderr */

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

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

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

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


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


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

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

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


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


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


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

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

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

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

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

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



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

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

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

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

                    interp.setErrorCode(childstatus);
                }

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

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


                throw new TclException(interp, "couldn't execute \"" + argv[firstWord].ToString() + "\": no such file or directory");
            }
            catch (System.Threading.ThreadInterruptedException e)
            {
                /*
                 * Do Nothing...
                 */
            }
            return(TCL.CompletionCode.RETURN);
        }