Beispiel #1
0
        // filename (line,col) | tool :
        static bool ParseOrigin(string line, int start, int end, CodeCompilerError result)
        {
            // no line/col
            if (line [end] != ')')
            {
                result.Origin = line.Substring(start, end - start + 1);
                return(true);
            }

            //scan back for matching (, assuming at least one char between them
            int posStart = line.LastIndexOf('(', end - 2, end - start - 1);

            if (posStart < 0)
            {
                return(false);
            }

            if (!ParsePosition(line, posStart + 1, end, result))
            {
                result.Origin = line.Substring(start, end - start + 1);
                return(true);
            }

            end = posStart - 1;
            MovePrevNonSpace(line, ref end, start);

            //if there's an origin, capture it
            if (end >= start)
            {
                result.Origin = line.Substring(start, end - start + 1);
            }
            return(true);
        }
Beispiel #2
0
        static bool ParseCategory(string line, int start, int end, CodeCompilerError result)
        {
            int idx = end;

            MovePrevWordStart(line, ref idx, start);
            if (idx < start + 1)
            {
                return(false);
            }

            string code = line.Substring(idx, end - idx + 1);

            idx--;
            MovePrevNonSpace(line, ref idx, start);
            end = idx;
            MovePrevWordStart(line, ref idx, start);
            if (idx < start)
            {
                return(false);
            }

            string category = line.Substring(idx, end - idx + 1);

            if (string.Equals(category, "error", StringComparison.OrdinalIgnoreCase))
            {
                result.IsError = true;
            }
            else if (!string.Equals(category, "warning", StringComparison.OrdinalIgnoreCase))
            {
                return(false);
            }

            result.Code = code;

            idx--;
            if (idx > start)
            {
                MovePrevNonSpace(line, ref idx, start);
                result.Subcategory = line.Substring(start, idx - start + 1);
            }
            else
            {
                result.Subcategory = "";
            }

            return(true);
        }
Beispiel #3
0
        // Parses single-line error message in the standard MSBuild error format:
        //
        // [origin[(position)]:][subcategory] category code: [message]
        //
        // Components in [] square brackets are optional.
        // Components are as follows:
        //  origin: tool name or filename, may contain whitespace, no colons except the drive letter
        //  position: line/col position or range in the file, with one of the following forms:
        //      (l), (l,c), (l,c-c), (l,c,l,c)
        //  subcategory: arbitrary text, may contain whitepsace
        //  code: error code, no whietspace or punctuation
        //  message: arbitrary text, no restrictions
        //
        public static CodeCompilerError TryParseLine(string line)
        {
            int originEnd, originStart = 0;
            var result = new CodeCompilerError();

            MoveNextNonSpace(line, ref originStart);

            if (originStart >= line.Length)
            {
                return(null);
            }

            //find the origin section
            //the filename may include a colon for Windows drive e.g. C:\foo, so ignore colon in first 2 chars
            if (line [originStart] != ':')
            {
                if (originStart + 2 >= line.Length)
                {
                    return(null);
                }

                if ((originEnd = line.IndexOf(':', originStart + 2) - 1) < 0)
                {
                    return(null);
                }
            }
            else
            {
                originEnd = originStart;
            }

            int categoryStart = originEnd + 2;

            if (categoryStart > line.Length)
            {
                return(null);
            }

            MovePrevNonSpace(line, ref originEnd);

            //if there is no origin section, then we can't parse the message
            if (originEnd < 0 || originEnd < originStart)
            {
                return(null);
            }

            //find the category section, if there is one
            MoveNextNonSpace(line, ref categoryStart);

            int categoryEnd  = line.IndexOf(':', categoryStart) - 1;
            int messageStart = categoryEnd + 2;

            if (categoryEnd >= 0)
            {
                MovePrevNonSpace(line, ref categoryEnd);
                if (categoryEnd <= categoryStart)
                {
                    categoryEnd = -1;
                }
            }

            //if there is a category section and it parses
            if (categoryEnd > 0 && ParseCategory(line, categoryStart, categoryEnd, result))
            {
                //then parse the origin section
                if (originEnd > originStart && !ParseOrigin(line, originStart, originEnd, result))
                {
                    return(null);
                }
            }
            else
            {
                //there is no origin, parse the origin section as if it were the category
                if (!ParseCategory(line, originStart, originEnd, result))
                {
                    return(null);
                }
                messageStart = categoryStart;
            }

            //read the remaining message
            MoveNextNonSpace(line, ref messageStart);
            int messageEnd = line.Length - 1;

            MovePrevNonSpace(line, ref messageEnd, messageStart);
            if (messageEnd > messageStart)
            {
                result.Message = line.Substring(messageStart, messageEnd - messageStart + 1);
            }
            else
            {
                result.Message = "";
            }

            return(result);
        }
Beispiel #4
0
        // Supported combos:
        //
        // (SL,SC,EL,EC)
        // (SL,SC-EC)
        // (SL-EL)
        // (SL,SC)
        // (SL)
        //
        // Unexpected patterns of commas/dashes abort parsing, discarding all values.
        // Any other characters abort parsing and the (...) gets treated as pert of the filename.
        // Overflows are silently treated as zeroes.
        //
        static bool ParsePosition(string str, int start, int end, CodeCompilerError result)
        {
            int line = 0, col = 0, endLine = 0, endCol = 0;

            var a = str.Substring(start, end - start).Split(',');

            if (a.Length > 4 || a.Length == 3)
            {
                return(true);
            }

            if (a.Length == 4)
            {
                bool valid =
                    ParseLineColVal(a [0], out line) &&
                    ParseLineColVal(a [1], out col) &&
                    ParseLineColVal(a [2], out endLine) &&
                    ParseLineColVal(a [3], out endCol);
                if (!valid)
                {
                    return(false);
                }
            }
            else
            {
                var b = a [0].Split('-');
                if (b.Length > 2)
                {
                    return(true);
                }
                if (!ParseLineColVal(b [0], out line))
                {
                    return(false);
                }
                if (b.Length == 2)
                {
                    if (a.Length == 2)
                    {
                        return(true);
                    }
                    if (!ParseLineColVal(b [1], out endLine))
                    {
                        return(false);
                    }
                }
                if (a.Length == 2)
                {
                    var c = a [1].Split('-');
                    if (c.Length > 2)
                    {
                        return(true);
                    }
                    if (!ParseLineColVal(c [0], out col))
                    {
                        return(false);
                    }
                    if (c.Length == 2)
                    {
                        if (!ParseLineColVal(c [1], out endCol))
                        {
                            return(false);
                        }
                    }
                }
            }

            result.Line      = line;
            result.Column    = col;
            result.EndLine   = endLine;
            result.EndColumn = endCol;
            return(true);
        }