Exemple #1
0
        internal static ParseResult parseBraces(Interp interp, string str, int index, int length)
        {
            char[] arr   = str.ToCharArray();
            int    level = 1;

            for (int i = index; i < length;)
            {
                if (Parser.charType(arr[i]) == Parser.TYPE_NORMAL)
                {
                    i++;
                }
                else if (arr[i] == '}')
                {
                    level--;
                    if (level == 0)
                    {
                        str = new string(arr, index, i - index);
                        return(new ParseResult(str, i + 1));
                    }
                    i++;
                }
                else if (arr[i] == '{')
                {
                    level++;
                    i++;
                }
                else if (arr[i] == '\\')
                {
                    BackSlashResult bs = Parser.backslash(arr, i);
                    i = bs.NextIndex;
                }
                else
                {
                    i++;
                }
            }

            //if you run off the end of the string you went too far
            throw new TclException(interp, "missing close-brace");
        }
Exemple #2
0
        /// <summary> This procedure is invoked to process the "subst" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException if wrong # of args or invalid argument(s).
        /// </exception>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            int           currentObjIndex, len, i;
            int           objc          = argv.Length - 1;
            bool          doBackslashes = true;
            bool          doCmds        = true;
            bool          doVars        = true;
            StringBuilder result        = new StringBuilder();
            string        s;
            char          c;

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

                case OPT_NOCOMMANDS:
                    doCmds = false;
                    break;

                case OPT_NOVARS:
                    doVars = false;
                    break;

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

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


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

                if ((c == '[') && doCmds)
                {
                    ParseResult res;
                    try
                    {
                        interp._evalFlags = Parser.TCL_BRACKET_TERM;
                        interp.Eval(s.Substring(i + 1, (len) - (i + 1)));
                        TclObject interp_result = interp.GetResult();
                        interp_result.Preserve();
                        res = new ParseResult(interp_result, i + interp._termOffset);
                    }
                    catch (TclException e)
                    {
                        i = e.errIndex + 1;
                        throw;
                    }
                    i = res.nextIndex + 2;

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

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

                    result.Append(vres.Value.ToString());
                    vres.Release();
                }
                else if ((c == '\\') && doBackslashes)
                {
                    BackSlashResult bs = Tcl.Lang.Interp.backslash(s, i, len);
                    i = bs.NextIndex;
                    if (bs.IsWordSep)
                    {
                        break;
                    }
                    else
                    {
                        result.Append(bs.C);
                    }
                }
                else
                {
                    result.Append(c);
                    i++;
                }
            }

            interp.SetResult(result.ToString());
            return(TCL.CompletionCode.RETURN);
        }
Exemple #3
0
        internal static FindElemResult findElement(Interp interp, string s, int i, int len)
        {
            int  openBraces = 0;
            bool inQuotes   = false;

            for (; i < len && System.Char.IsWhiteSpace(s[i]); i++)
            {
                ;
            }
            if (i >= len)
            {
                return(null);
            }
            char c = s[i];

            if (c == '{')
            {
                openBraces = 1;
                i++;
            }
            else if (c == '"')
            {
                inQuotes = true;
                i++;
            }
            StringBuilder sbuf = new StringBuilder();

            while (true)
            {
                if (i >= len)
                {
                    if (openBraces != 0)
                    {
                        throw new TclException(interp, "unmatched open brace in list");
                    }
                    else if (inQuotes)
                    {
                        throw new TclException(interp, "unmatched open quote in list");
                    }
                    return(new FindElemResult(i, sbuf.ToString(), openBraces));
                }

                c = s[i];
                switch (c)
                {
                // Open brace: don't treat specially unless the element is
                // in braces.  In this case, keep a nesting count.
                case '{':
                    if (openBraces != 0)
                    {
                        openBraces++;
                    }
                    sbuf.Append(c);
                    i++;
                    break;

                // Close brace: if element is in braces, keep nesting
                // count and quit when the last close brace is seen.


                case '}':
                    if (openBraces == 1)
                    {
                        if (i == len - 1 || System.Char.IsWhiteSpace(s[i + 1]))
                        {
                            return(new FindElemResult(i + 1, sbuf.ToString(), openBraces));
                        }
                        else
                        {
                            int errEnd;
                            for (errEnd = i + 1; errEnd < len; errEnd++)
                            {
                                if (System.Char.IsWhiteSpace(s[errEnd]))
                                {
                                    break;
                                }
                            }
                            throw new TclException(interp, "list element in braces followed by \"" + s.Substring(i + 1, (errEnd) - (i + 1)) + "\" instead of space");
                        }
                    }
                    else if (openBraces != 0)
                    {
                        openBraces--;
                    }
                    sbuf.Append(c);
                    i++;
                    break;

                // Backslash:  skip over everything up to the end of the
                // backslash sequence.


                case '\\':
                    BackSlashResult bs = Interp.backslash(s, i, len);
                    if (openBraces > 0)
                    {
                        // Quotes are ignored in brace-quoted stuff

                        sbuf.Append(s.Substring(i, (bs.NextIndex) - (i)));
                    }
                    else
                    {
                        sbuf.Append(bs.C);
                    }
                    i = bs.NextIndex;

                    break;

                // Space: ignore if element is in braces or quotes;  otherwise
                // terminate element.


                case ' ':
                case '\f':
                case '\n':
                case '\r':
                case '\t':
                    if ((openBraces == 0) && !inQuotes)
                    {
                        return(new FindElemResult(i + 1, sbuf.ToString(), openBraces));
                    }
                    else
                    {
                        sbuf.Append(c);
                        i++;
                    }
                    break;

                // Double-quote:  if element is in quotes then terminate it.


                case '"':
                    if (inQuotes)
                    {
                        if (i == len - 1 || System.Char.IsWhiteSpace(s[i + 1]))
                        {
                            return(new FindElemResult(i + 1, sbuf.ToString(), openBraces));
                        }
                        else
                        {
                            int errEnd;
                            for (errEnd = i + 1; errEnd < len; errEnd++)
                            {
                                if (System.Char.IsWhiteSpace(s[errEnd]))
                                {
                                    break;
                                }
                            }
                            throw new TclException(interp, "list element in quotes followed by \"" + s.Substring(i + 1, (errEnd) - (i + 1)) + "\" instead of space");
                        }
                    }
                    else
                    {
                        sbuf.Append(c);
                        i++;
                    }
                    break;


                default:
                    sbuf.Append(c);
                    i++;
                    break;
                }
            }
        }
Exemple #4
0
        internal static int scanElement(Interp interp, string inString)
        {
            int  flags, nestingLevel;
            char c;
            int  len;
            int  i;

            // This procedure and Tcl_ConvertElement together do two things:
            //
            // 1. They produce a proper list, one that will yield back the
            // argument strings when evaluated or when disassembled with
            // Tcl_SplitList.  This is the most important thing.
            //
            // 2. They try to produce legible output, which means minimizing the
            // use of backslashes (using braces instead).  However, there are
            // some situations where backslashes must be used (e.g. an element
            // like "{abc": the leading brace will have to be backslashed.  For
            // each element, one of three things must be done:
            //
            // (a) Use the element as-is (it doesn't contain anything special
            // characters).  This is the most desirable option.
            //
            // (b) Enclose the element in braces, but leave the contents alone.
            // This happens if the element contains embedded space, or if it
            // contains characters with special interpretation ($, [, ;, or \),
            // or if it starts with a brace or double-quote, or if there are
            // no characters in the element.
            //
            // (c) Don't enclose the element in braces, but add backslashes to
            // prevent special interpretation of special characters.  This is a
            // last resort used when the argument would normally fall under case
            // (b) but contains unmatched braces.  It also occurs if the last
            // character of the argument is a backslash or if the element contains
            // a backslash followed by newline.
            //
            // The procedure figures out how many bytes will be needed to store
            // the result (actually, it overestimates).  It also collects
            // information about the element in the form of a flags word.

            nestingLevel = 0;
            flags        = 0;

            i   = 0;
            len = (inString != null ? inString.Length : 0);
            if (len == 0)
            {
                inString = '\x0000'.ToString();

                // FIXME : pizza compiler workaround
                // We really should be able to use the "\0" form but there
                // is a nasty bug in the pizza compiler shipped with kaffe
                // that causes "\0" to be read as the empty string.

                //string = "\0";
            }

            System.Diagnostics.Debug.WriteLine("scanElement string is \"" + inString + "\"");

            c = inString[i];
            if ((c == '{') || (c == '"') || (c == '\x0000'))
            {
                flags |= USE_BRACES;
            }
            for (; i < len; i++)
            {
                System.Diagnostics.Debug.WriteLine("getting char at index " + i);
                System.Diagnostics.Debug.WriteLine("char is '" + inString[i] + "'");

                c = inString[i];
                switch (c)
                {
                case '{':
                    nestingLevel++;
                    break;

                case '}':
                    nestingLevel--;
                    if (nestingLevel < 0)
                    {
                        flags |= TCL_DONT_USE_BRACES | BRACES_UNMATCHED;
                    }
                    break;

                case '[':
                case '$':
                case ';':
                case ' ':
                case '\f':
                case '\n':
                case '\r':
                case '\t':
                case (char)(0x0b):

                    flags |= USE_BRACES;
                    break;

                case '\\':
                    if ((i >= len - 1) || (inString[i + 1] == '\n'))
                    {
                        flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;
                    }
                    else
                    {
                        BackSlashResult bs = Interp.backslash(inString, i, len);

                        // Subtract 1 because the for loop will automatically
                        // add one on the next iteration.

                        i      = (bs.NextIndex - 1);
                        flags |= USE_BRACES;
                    }
                    break;
                }
            }
            if (nestingLevel != 0)
            {
                flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;
            }

            return(flags);
        }