static void Main(string[] args) { if (args.Count() < 3) { Console.WriteLine("Usage: v1.bpl v2.bpl v1v2.config"); Console.WriteLine(" The source files are implicitly specified inside the bpl files"); Console.WriteLine(" v1v2.config: a mapping between entities in v1.bpl and v2.bpl (default generated by SymDiff.exe -inferConfig v1.bpl v2.bpl)"); return; } if (args.Any(x => x == "-break")) { Debugger.Launch(); } var CoarseDiff = args.Any(x => x.Contains("/coarseDiff")); BoogieUtils.InitializeBoogie(""); var v1 = args[0]; var v2 = args[1]; v1v2Config = new SDiff.Config(args[2]); Debug.Assert(v1v2Config != null); var v1Prog = BoogieUtils.ParseProgram(v1); var v2Prog = BoogieUtils.ParseProgram(v2); var v1srcInfo = new SourceInfoManager(v1Prog, Path.GetDirectoryName(v1)); v1srcInfo.ComputeSourceInfoForImplementations(); var v2srcInfo = new SourceInfoManager(v2Prog, Path.GetDirectoryName(v2)); v2srcInfo.ComputeSourceInfoForImplementations(); //remove any sourcefile/sourceline info before doing a syntactic diff new RemoveSrcInfoStmts().Visit(v1Prog); new RemoveSrcInfoStmts().Visit(v2Prog); var v1Changes = new List <string>(); var v2Changes = new List <string>(); //remove those implementations that are syntactically identical var diffImpls = GetImplementationPairs(v1Prog, v2Prog); if (CoarseDiff) { diffImpls = diffImpls.Where(pair => !IsEqualStringRepresentation(pair.Item1, pair.Item2)); foreach (var implPair in diffImpls) { if (implPair.Item1 != null) { v1Changes.AddRange(FormatChangedLinesForProcedure(implPair.Item1.Name, new List <int>() { 0 }, v1srcInfo.srcInfoPerImpl[implPair.Item1].Item1)); } if (implPair.Item2 != null) { v2Changes.AddRange(FormatChangedLinesForProcedure(implPair.Item2.Name, new List <int>() { 0 }, v2srcInfo.srcInfoPerImpl[implPair.Item2].Item1)); } } } else { //perform the diff on the source files in which the implemnation pair is present foreach (var i12 in diffImpls) { var d12 = FindDiffSourceLinesInImplementation(i12.Item1, v1srcInfo, i12.Item2, v2srcInfo); if (i12.Item1 != null) { v1Changes.AddRange(FormatChangedLinesForProcedure(i12.Item1.Name, d12.Item1, v1srcInfo.srcInfoPerImpl[i12.Item1].Item1)); } if (i12.Item2 != null) { v2Changes.AddRange(FormatChangedLinesForProcedure(i12.Item2.Name, d12.Item2, v2srcInfo.srcInfoPerImpl[i12.Item2].Item1)); } } } PrintChangedLinesToFile(v1Changes, Path.Combine(Path.GetDirectoryName(v1), v1 + "_changed_lines.txt")); PrintChangedLinesToFile(v2Changes, Path.Combine(Path.GetDirectoryName(v2), v2 + "_changed_lines.txt")); return; }
private static Tuple <List <int>, List <int> > FindDiffSourceLinesInImplementation(Implementation implementation1, SourceInfoManager v1srcInfo, Implementation implementation2, SourceInfoManager v2srcInfo) { if (implementation1 != null && implementation2 != null) { Console.WriteLine("----Diffing {0} and {1}-----", implementation1.Name, implementation2.Name); var v1Lines = v1srcInfo.GetSrcLinesForImpl(implementation1); var v2Lines = v2srcInfo.GetSrcLinesForImpl(implementation2); var diffLines = new DiffUsingTFS().DiffStrings(v1Lines, v2Lines); //add the offset to any difflines var i1StartLine = v1srcInfo.GetStartLineForImplInFile(implementation1); var i2StartLine = v2srcInfo.GetStartLineForImplInFile(implementation2); var d1 = diffLines.Item1.Select(x => x + i1StartLine).ToList(); var d2 = diffLines.Item2.Select(x => x + i2StartLine).ToList(); return(Tuple.Create(d1, d2)); } else { var d1 = new List <int>(); var d2 = new List <int>(); if (implementation1 != null) { var i1StartLine = v1srcInfo.GetStartLineForImplInFile(implementation1); var i1EndLine = v1srcInfo.GetEndLineForImplInFile(implementation1); d1.AddRange(Enumerable.Range(i1StartLine, i1EndLine - i1StartLine + 1)); } if (implementation2 != null) { var i2StartLine = v2srcInfo.GetStartLineForImplInFile(implementation2); var i2EndLine = v2srcInfo.GetEndLineForImplInFile(implementation2); d2.AddRange(Enumerable.Range(i2StartLine, i2EndLine - i2StartLine + 1)); } return(Tuple.Create(d1, d2)); } }