public static Interfaces GetInterfaceObjects(string path) { List <string> file = ValidationHelper.ReadAllLines(path); Interfaces interfaces = ParseInterfaceNames(file); ParseInterfaceBody(file, interfaces); return(interfaces); }
public void ValidateInterfaces() { List <string> files = GetFileList(); bool success = true; foreach (string file in files) { LogHelper.Log("File {0} :", file); string curPath = ExtractFilePath(file, string.Empty, false); Interfaces curInterfaces = ValidationHelper.GetInterfaceObjects(curPath); List <string> versions = GetVersionList(); foreach (string version in versions) { LogHelper.Log("Version {0} :", version); string prePath = ExtractFilePath(file, version, true); Interfaces preInterfaces = ValidationHelper.GetInterfaceObjects(prePath); LogHelper.Log("**************************************************************************"); LogHelper.Log("Comparing Interfaces:"); List <string> differences = preInterfaces.Compare(curInterfaces); success &= (differences == null || differences.Count == 0); LogHelper.Log("{0} interfaces are different.", (differences == null) ? 0 : differences.Count); LogHelper.Log("Comparing Guid:"); if (curInterfaces != null && curInterfaces.SameGuidInterfaces.Count > 0) { success &= false; foreach (KeyValuePair <Guid, List <string> > id in curInterfaces.SameGuidInterfaces) { LogHelper.Log("Guid id {0} is used in interfaces :", id.Key); foreach (string s in id.Value) { LogHelper.Log(s); } } } LogHelper.Log("{0} Guids are duplicated.", curInterfaces.SameGuidInterfaces.Count); LogHelper.Log("**************************************************************************"); } } Assert.IsTrue(success, "Comparison completed. No interface is changed. No Guid is duplicated."); }
/// <summary> /// Read "Forward Declarations" of .h file and parse interface names /// </summary> /// <param name="lines">Content of .h file</param> /// <returns>InterfaceObject collection which has names</returns> public static Interfaces ParseInterfaceNames(List <string> lines) { LogHelper.Log("Start getting interfaces:"); Interfaces interfaces = new Interfaces(); const string sFlag = "/* Forward Declarations */"; const string eFlag = "/* header files for imported files */"; const string match = "typedef interface"; const char space = ' '; int i = 0; // Read till "Forward Declarations" while (i < lines.Count && lines[i] != sFlag) { i++; continue; } // Get interface name if that line contains key words "typedef interface" // Skip duplicated ones while (i < lines.Count && lines[i] != eFlag) { if (lines[i].Contains(match)) { string name = lines[i].Split(space)[2]; if (!interfaces.ContainsName(name)) { interfaces.Add(name, null); } } i++; } LogHelper.Log("Completed getting interfaces: {0} interfaces.", interfaces.Count); return(interfaces); }
/// <summary> /// Compare interfaces which defined in previous release with current build /// If it is found, compare the interface /// If the content of same interface are differrent /// Compare and output the different methods /// </summary> /// <param name="target">Interfaces Object</param> /// <returns>Differences of interfaces</returns> public List <string> Compare(Interfaces target) { if (this.Count == 0 || target == null || target.Count == 0) { return(null); } List <string> differences = new List <string>(); // Search interfaces which defined in previous release from current build // If it is found, compare the interface // If the content of same interface are differrent // Compare and output the different methods foreach (KeyValuePair <string, InterfaceObject> pair in this.infos) { string name = pair.Key; if (target.infos.ContainsKey(name)) { InterfaceObject cur = target[name]; InterfaceObject pre = pair.Value; if (!pre.Equals(cur)) { Methods curMethods = ValidationHelper.ParseMethodInformation(cur.CplusplusContent); Methods preMethods = ValidationHelper.ParseMethodInformation(pre.CplusplusContent); string difference = preMethods.Compare(curMethods); LogHelper.Log("Differences of {0}:", name); LogHelper.Log(difference); differences.Add(difference); } } } return(differences); }
/// <summary> /// Read all content of .h and parse interface body /// </summary> /// <param name="lines">Content of .h file</param> /// <param name="interfaces">InterfaceObject collection</param> public static void ParseInterfaceBody(List <string> lines, Interfaces interfaces) { LogHelper.Log("Start parsing interface content:"); const string sFlag = "MIDL_INTERFACE"; const string cplusplusEFlag = "};"; const string cEnd = "Vtbl;"; const char space = ' '; // Parse Guid // MIDL_INTERFACE(" const int startIndex = 16; // skip to C++ interface body const int cppCursor = 2; // skip to C interface body const int cCursor = 4; Dictionary <Guid, string> ids = new Dictionary <Guid, string>(); int i = 0; while (i < lines.Count) { // Read till interface definition if (!lines[i].Contains(sFlag)) { i++; continue; } InterfaceObject ic = new InterfaceObject(); string line = lines[i++]; string guid = line.Substring(startIndex, line.Length - startIndex - 2); Guid id = new Guid(guid); ic.ID = id; StringBuilder sb = new StringBuilder(); // Parse interface name string name = lines[i].Split(space)[0]; ic.Name = name; // Save Guid and interfaces to dictionary if (!ids.ContainsKey(id)) { ids.Add(id, name); } else if (interfaces.SameGuidInterfaces.ContainsKey(id)) { interfaces.SameGuidInterfaces[id].Add(name); } else { interfaces.SameGuidInterfaces.Add(id, new List <string>() { ids[id] }); interfaces.SameGuidInterfaces[id].Add(name); } // skip to methods i += cppCursor; while (i < lines.Count && !lines[i].Contains(cplusplusEFlag)) { sb.AppendLine(lines[i++]); } ic.CplusplusContent = sb.ToString(); // skip to BEGIN_INTERFACE i += cCursor; sb.Clear(); while (i < lines.Count && !lines[i].Contains(cEnd)) { sb.AppendLine(lines[i]); i++; } ic.CContent = sb.ToString(); if (interfaces.ContainsName(name)) { interfaces[name] = ic; } i++; } LogHelper.Log("Complete parsing interface content."); }