public static LineOfCode Parse(Codebase owner, string line)
        {
            line = line.Trim();
            var result = new LineOfCode();

            result.Owner = owner;
            result.ID    = line;

            result.CalledFrom = new List <LineOfCode>();
            result.CallsTo    = new List <LineOfCode>();
            result.Leaks      = new List <Backtrace>();

            var match      = Regex.Match(line, "(?<moduleName>.*)\\!(?<symbolName>.*)\\+(?<rest>(.*))?$|(?<moduleName>.*)$");
            var moduleName = match.Groups["moduleName"].Value;
            var symbolName = match.Groups["symbolName"].Value; if (String.IsNullOrEmpty(symbolName))
            {
                symbolName = moduleName;
            }
            var rest = match.Groups["rest"].Success ? match.Groups["rest"].Value : "";

            result.Module   = owner.Modules.FirstOrDefault(x => x.Name == moduleName);
            result.Scope    = owner.GetScope(symbolName);
            result.Function = owner.GetFunction(symbolName);

            result.Scope.Lines.Add(result);                    // Add line to scope
            result.Function.Lines.AddOrGet(result);            // Add line to function

            result.Module.Scopes.AddOrGet(result.Scope);       // Add scope to module
            result.Module.Functions.AddOrGet(result.Function); // Add function to module
            result.Module.Lines.AddOrGet(result);              // Add line to module

            match = Regex.Match(rest, ".* \\((?<fileName>.*), (?<lineNum>\\d*)\\)");
            if (match.Success) // Is file,line present?
            {
                var filename = match.Groups["fileName"].Value;
                var lineNum  = Convert.ToInt32(match.Groups["lineNum"].Value);

                result.LineNumber = lineNum;
                result.SourceFile = owner.GetFile(filename, result.Module);
                result.SourceFile.Lines.AddOrGet(result);        // Add line to file

                result.Module.Files.AddOrGet(result.SourceFile); // Add file to module

                result.GeneratePreview(filename, lineNum);
            }

            return(result);
        }
Example #2
0
        // Get line if it already exists inside the codebase,
        // or add new if not found
        public LineOfCode GetLine(string line)
        {
            line = line.Trim();

            var existingLine = Lines.FirstOrDefault(x => x.ID == line);

            if (existingLine != null)
            {
                return(existingLine);
            }
            else
            {
                var newLine = LineOfCode.Parse(this, line);
                Lines.Add(newLine);
                return(newLine);
            }
        }
Example #3
0
        public static Backtrace FromLines(Codebase owner, List <string> lines, int startLine, int endLine)
        {
            var header    = lines[0];
            var subHeader = lines[1];

            var headerNumbers = Regex.Matches(header, "(?<number>^-\\s*\\d+)|(?<number>\\d+)( |\\))")   // first number must capture negative sign if exists.
                                .Cast <Match>()
                                .Select(x => x.Groups["number"].Value.Replace(" ", ""))
                                .Select(x => Convert.ToInt32(x))
                                .ToList();


            var subHeaderNumberMatches = Regex.Matches(subHeader, "(?<number>^-\\s*\\d+)|(?<number>\\d+)( |\\))");
            //var subHeaderNumbers = Regex.Matches(subHeader, "(?<number>^-\\s*\\d+)|(?<number>\\d+)( |\\))")  // first number must capture negative sign if exists.
            var subHeaderNumbers = subHeaderNumberMatches
                                   .Cast <Match>()
                                   .Select(x => x.Groups["number"].Value.Replace(" ", ""))
                                   .Select(x => Convert.ToInt32(x))
                                   .ToList();

            var bytesDelta = headerNumbers[0];
            var newBytes   = headerNumbers[1];
            var oldBytes   = headerNumbers[2];
            var countDelta = subHeaderNumbers[0];
            var newCount   = subHeaderNumbers[1];
            var oldCount   = subHeaderNumbers[2];

            var result = new Backtrace
            {
                TotalLeak = bytesDelta,
                Count     = countDelta,
                Owner     = owner,
                Lines     = new List <LineOfCode>(),
                StartLine = startLine,
                EndLine   = endLine
            };

            var        justLines = lines.Skip(2).Where(x => x.Trim() != string.Empty).ToList();
            LineOfCode prevLine  = null;

            foreach (var lineStr in justLines)
            {
                var line = owner.GetLine(lineStr);

                line.Leaks.AddOrGet(result);          // Add leak to line's leaks
                line.Function.Leaks.AddOrGet(result); // Add leak to line's function's leak
                line.Scope.Leaks.AddOrGet(result);    // Add leak to line's scope's leak
                if (line.SourceFile != null)
                {
                    line.SourceFile.Leaks.AddOrGet(result); // Add leak to line's file's leaks
                }
                line.Module.Leaks.AddOrGet(result);         // Add leak to line's module's leaks

                result.Lines.Add(line);                     // Add line to leak

                // Connect and update calls to and called from
                if (prevLine != null)
                {
                    line.CallsTo.AddOrGet(prevLine);                   // Line calls prevLine
                    line.Function.CallsTo.AddOrGet(prevLine.Function); // Line's function calls prevLine's function
                    line.Module.CallsTo.AddOrGet(prevLine.Module);     // Line's module calls prevLine's module

                    if (line.SourceFile != null && prevLine.SourceFile != null)
                    {
                        line.SourceFile.CallsTo.AddOrGet(prevLine.SourceFile);    // Line's file calls prevLine's file
                        prevLine.SourceFile.CalledFrom.AddOrGet(line.SourceFile); // PrevLine's file is called from line's file
                    }

                    prevLine.CalledFrom.AddOrGet(line);                   // PrevLine is called from line
                    prevLine.Function.CalledFrom.AddOrGet(line.Function); // PrevLine's function is called from line's function
                    prevLine.Module.CalledFrom.AddOrGet(line.Module);     // PrevLine's module is called from line's module
                }

                prevLine = line;
            }

            return(result);
        }