private static void OnBuildConfigFinished(vsBuildScope Scope, vsBuildAction Action) { ThreadHelper.ThrowIfNotOnUIThread(); // Sometimes we get this message several times. if (!CompilationOngoing) { return; } // Parsing maybe successful for an unsuccessful build! bool successfulParsing = true; try { string outputText = VSUtils.GetOutputText(); if (string.IsNullOrEmpty(outputText)) { successfulParsing = false; return; } // What we're building right now is a tree. // However, combined with the existing data it might be a wide graph. var includeTreeItemStack = new Stack <IncludeGraph.GraphItem>(); includeTreeItemStack.Push(graphBeingExtended.CreateOrGetItem(documentBeingCompiled.FullName, out _)); var includeDirectories = VSUtils.GetProjectIncludeDirectories(documentBeingCompiled.ProjectItem.ContainingProject); includeDirectories.Insert(0, PathUtil.Normalize(documentBeingCompiled.Path) + Path.DirectorySeparatorChar); const string includeNoteString = "Note: including file: "; string[] outputLines = System.Text.RegularExpressions.Regex.Split(outputText, "\r\n|\r|\n"); // yes there are actually \r\n in there in some VS versions. foreach (string line in outputLines) { int startIndex = line.IndexOf(includeNoteString); if (startIndex < 0) { continue; } startIndex += includeNoteString.Length; int includeStartIndex = startIndex; while (includeStartIndex < line.Length && line[includeStartIndex] == ' ') { ++includeStartIndex; } int depth = includeStartIndex - startIndex; if (depth >= includeTreeItemStack.Count) { includeTreeItemStack.Push(includeTreeItemStack.Peek().Includes.Last().IncludedFile); } while (depth < includeTreeItemStack.Count - 1) { includeTreeItemStack.Pop(); } string fullIncludePath = line.Substring(includeStartIndex); IncludeGraph.GraphItem includedItem = graphBeingExtended.CreateOrGetItem(fullIncludePath, out _); includeTreeItemStack.Peek().Includes.Add(new IncludeGraph.Include() { IncludedFile = includedItem }); } } catch (Exception e) { _ = Output.Instance.ErrorMsg("Failed to parse output from /showInclude compilation of file '{0}': {1}", documentBeingCompiled.FullName, e); successfulParsing = false; return; } finally { _ = onCompleted(graphBeingExtended, documentBeingCompiled, successfulParsing); _ = ResetPendingCompilationInfo(); } }
private static void OnBuildConfigFinished(vsBuildScope Scope, vsBuildAction Action) { // Sometimes we get this message several times. if (!CompilationOngoing) { return; } // Parsing maybe successful for an unsuccessful build! bool successfulParsing = true; try { string outputText = VSUtils.GetOutputText(); if (string.IsNullOrEmpty(outputText)) { successfulParsing = false; return; } // What we're building right now is a tree. // However, combined with the existing data it might be a wide graph. var includeTreeItemStack = new Stack <IncludeGraph.GraphItem>(); includeTreeItemStack.Push(graphBeingExtended.CreateOrGetItem(documentBeingCompiled.FullName, 0.0, out _)); var includeDirectories = VSUtils.GetProjectIncludeDirectories(documentBeingCompiled.ProjectItem.ContainingProject); includeDirectories.Insert(0, PathUtil.Normalize(documentBeingCompiled.Path) + Path.DirectorySeparatorChar); const string includeHeadersString = "Include Headers:"; string[] outputLines = System.Text.RegularExpressions.Regex.Split(outputText, "\r\n|\r|\n"); // yes there are actually \r\n in there in some VS versions. /* * mode: * - 0 means not in a parsing mode * - 1 means parsing 'Include Headers:' section */ int mode = 0; for (int line_index = 0; line_index < outputLines.Count(); line_index++) { string line = outputLines[line_index]; // keeping track parsing state if (mode == 0) { if (line.IndexOf(includeHeadersString) >= 0) { mode = 1; continue; } // hack we do not support other states yet continue; } line = CleanString(line); int count = ParseInt(line, "Count:"); for (int include_line_index = 0; include_line_index < count; include_line_index++) { line_index++; string include_line = outputLines[line_index]; include_line = CleanString(include_line); int depth = include_line.Count(f => f == '\t') - 1; if (depth >= includeTreeItemStack.Count) { includeTreeItemStack.Push(includeTreeItemStack.Peek().Includes.Last().IncludedFile); } while (depth < includeTreeItemStack.Count - 1) { includeTreeItemStack.Pop(); } var filename_and_time = GetFilenameAndTime(include_line); IncludeGraph.GraphItem includedItem = graphBeingExtended.CreateOrGetItem(filename_and_time.filename, filename_and_time.time, out _); includeTreeItemStack.Peek().Includes.Add(new IncludeGraph.Include() { IncludedFile = includedItem }); } mode = 0; } } catch (Exception e) { Output.Instance.ErrorMsg("Failed to parse output from -d1reportTime compilation of file '{0}': {1}", documentBeingCompiled.FullName, e); successfulParsing = false; return; } finally { try { onCompleted(graphBeingExtended, successfulParsing); } finally { ResetPendingCompilationInfo(); } } }