/// <summary> /// Analyzes the defines in the given file. Information is saved in the report. /// </summary> /// <param name="report">The report to save the results in.</param> /// <param name="file">The file to analyze.</param> private void AnalyzeDefines(ScanReport report, ScannedFile file) { string[] fileContents; Match m; int lineNumber = 0; fileContents = File.ReadAllLines(file.FullName); foreach (string line in fileContents) { lineNumber++; #region Search For define directives m = Regex.Match(line, @"^\s*#\s*define\s+(\w+)\s+(.*)$", RegexOptions.IgnoreCase); if (m.Success) { string identifier = m.Groups[1].ToString(); string value = m.Groups[2].ToString(); value = StripComments(value); if (Verbose) Console.WriteLine(" Line {0,-7}: Found {3,-18}: {1} as {2}", lineNumber, identifier, value, "define"); report.AddDefineValue(identifier, value, file.ID); } #endregion #region Search for ifdef, ifndef, and undef foreach (string pattern in new string[] { @"^\s*#\s*ifdef\s+(\w+)", @"^\s*#\s*ifndef\s+(\w+)", @"^\s*#\s*undef\s+(\w+)" }) { m = Regex.Match(line, pattern, RegexOptions.IgnoreCase); if (m.Success) { string identifier = m.Groups[1].ToString(); if (Verbose) Console.WriteLine(" Line {0,-7}: Found {2,-18}: {1}", lineNumber, identifier, "ifdef/ifnef/undef"); report.AddDefine(identifier, file.ID); } } #endregion #region Search for if and elif foreach (string pattern in new string[] { @"^\s*#\s*if\s+(.*)", @"^\s*#\s*elif\s+(.*)" }) { m = Regex.Match(line, pattern, RegexOptions.IgnoreCase); if (m.Success) { string text = m.Groups[1].ToString(); text = StripComments(text); foreach (Match definedMatch in Regex.Matches(text, @"defined\((\w+)\)", RegexOptions.IgnoreCase)) { string identifier = definedMatch.Groups[1].ToString(); if (Verbose) Console.WriteLine(" Line {0,-7}: Found {2,-18}: {1}", lineNumber, identifier, "if/elif"); report.AddDefine(identifier, file.ID); } } } #endregion } }
/// <summary> /// Recursively scans the project source directory for all files. Each is classified /// and written to the report structure. /// </summary> /// <param name="report">The report to save the results in.</param> /// <param name="rootDirectory">The root directory of the project.</param> /// <param name="currentSearchDirectory">The current search directory.</param> private void ScanDirectory(ScanReport report, string rootDirectory, string currentSearchDirectory) { FileSystemInfo[] files = null; DirectoryInfo dirInfo = null; if (Directory.Exists(currentSearchDirectory) == false) return; dirInfo = new DirectoryInfo(currentSearchDirectory); files = dirInfo.GetFileSystemInfos(); foreach (FileSystemInfo item in files) { FileInfo fileInfo = item as FileInfo; if (fileInfo != null) { ScannedFile file = new ScannedFile(); file.Directory = ShortenPath(rootDirectory, fileInfo.DirectoryName); file.FullName = fileInfo.FullName; file.Name = fileInfo.Name; file.Type = ScannedFile.DetermineFileType(fileInfo.Name); if (Verbose) Console.WriteLine("Adding {0}", file); report.AddFile(file); } } foreach (FileSystemInfo item in files) { DirectoryInfo dir = item as DirectoryInfo; if (dir != null) { if (dir.Name == "." || dir.Name == "..") continue; ScanDirectory(report, rootDirectory, dir.FullName); } } }
/// <summary> /// Analyzes the files for include statements. Information is saved in the report. /// </summary> /// <param name="report">The report to save the results in.</param> /// <param name="file">The file to analyze.</param> private void AnalyzeIncludes(ScanReport report, ScannedFile file) { }
/// <summary> /// Analyzes the given file for clues as to its purpose (looks for main(), etc) /// </summary> /// <param name="report"></param> /// <param name="file"></param> private void AnalyzeSourceClues(ScanReport report, ScannedFile file) { string fileContents; fileContents = File.ReadAllText(file.FullName); if(Regex.IsMatch(fileContents, @"int\s*main\s*\(", RegexOptions.Singleline) || Regex.IsMatch(fileContents, @"void\s*main\s*\(", RegexOptions.Singleline)) file.HasMain = true; }
/// <summary> /// Adds the given ScanFile instance to the Files dictionary. This method should /// be used because it assigns the numeric ID to the file if not present. /// </summary> /// <param name="file">The file.</param> public void AddFile(ScannedFile file) { if (file.ID == 0) file.ID = _fileHash.Count + 1; _fileHash[file.ID] = file; }