Example #1
0
        /// <summary>
        /// Recurses through the given file and all of its includes, attempting to identify cycles.
        /// </summary>
        /// <param name="File">The file to search through</param>
        /// <param name="Includes">Current include stack of the preprocessor</param>
        /// <param name="VisitedFiles">Set of files that have already been checked for cycles</param>
        /// <param name="Cycles">List which receives any cycles that are found</param>
        static void FindCyclesRecursive(SourceFile File, List <SourceFile> Includes, HashSet <SourceFile> VisitedFiles, List <IncludeCycle> Cycles)
        {
            // Check if this include forms a cycle
            int IncludeIdx = Includes.IndexOf(File);

            if (IncludeIdx != -1)
            {
                IncludeCycle NewCycle = new IncludeCycle(Includes.Skip(IncludeIdx));
                for (int Idx = 0;; Idx++)
                {
                    if (Idx == Cycles.Count)
                    {
                        Cycles.Add(NewCycle);
                        break;
                    }
                    else if (Cycles[Idx].Matches(NewCycle))
                    {
                        Cycles[Idx].AddStartingPoint(NewCycle.Files[0]);
                        break;
                    }
                }
            }

            // If we haven't already looked from cycles from this include, search now
            if (!VisitedFiles.Contains(File))
            {
                VisitedFiles.Add(File);

                Includes.Add(File);
                foreach (PreprocessorMarkup Markup in File.Markup)
                {
                    if (Markup.Type == PreprocessorMarkupType.Include && Markup.IncludedFile != null)
                    {
                        SourceFile IncludedFile = Markup.IncludedFile;
                        if (!IncludedFile.Flags.HasFlag(SourceFileFlags.External))
                        {
                            FindCyclesRecursive(Markup.IncludedFile, Includes, VisitedFiles, Cycles);
                        }
                    }
                }
                Includes.RemoveAt(Includes.Count - 1);
            }
        }
Example #2
0
        /// <summary>
        /// Checks whether an include cycle matches another include cycle, ignoring the start location.
        /// </summary>
        /// <param name="Other">The cycle to compare against</param>
        /// <returns>True if the cycles are identical, false otherwise</returns>
        public bool Matches(IncludeCycle Other)
        {
            if (Other.Files.Length != Files.Length)
            {
                return(false);
            }

            int Offset = Array.IndexOf(Other.Files, Files[0]);

            if (Offset == -1)
            {
                return(false);
            }

            for (int Idx = 0; Idx < Files.Length; Idx++)
            {
                if (Files[Idx] != Other.Files[(Offset + Idx) % Files.Length])
                {
                    return(false);
                }
            }

            return(true);
        }