/// <summary>
        /// Parse the first include directive from a source file
        /// </summary>
        /// <param name="SourceFile">The source file to parse</param>
        /// <returns>The first include directive</returns>
        static string ParseFirstInclude(FileReference SourceFile)
        {
            bool bMatchImport = SourceFile.HasExtension(".m") || SourceFile.HasExtension(".mm");

            using (StreamReader Reader = new StreamReader(SourceFile.FullName, true))
            {
                for (;;)
                {
                    string Line = Reader.ReadLine();
                    if (Line == null)
                    {
                        return(null);
                    }

                    Match IncludeMatch = IncludeRegex.Match(Line);
                    if (IncludeMatch.Success)
                    {
                        return(IncludeMatch.Groups[1].Value);
                    }

                    if (bMatchImport)
                    {
                        Match ImportMatch = ImportRegex.Match(Line);
                        if (ImportMatch.Success)
                        {
                            return(IncludeMatch.Groups[1].Value);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Generates documentation files for the available settings, by merging the XML documentation from the compiler.
        /// </summary>
        /// <param name="OutputFile">The documentation file to write</param>
        public static void WriteDocumentation(FileReference OutputFile)
        {
            // Find all the configurable types
            List <Type> ConfigTypes = FindConfigurableTypes();

            // Find all the configurable fields from the given types
            Dictionary <string, Dictionary <string, FieldInfo> > CategoryToFields = new Dictionary <string, Dictionary <string, FieldInfo> >();

            FindConfigurableFields(ConfigTypes, CategoryToFields);
            CategoryToFields = CategoryToFields.Where(x => x.Value.Count > 0).ToDictionary(x => x.Key, x => x.Value);

            // Get the path to the XML documentation
            FileReference InputDocumentationFile = new FileReference(Assembly.GetExecutingAssembly().Location).ChangeExtension(".xml");

            if (!FileReference.Exists(InputDocumentationFile))
            {
                throw new BuildException("Generated assembly documentation not found at {0}.", InputDocumentationFile);
            }

            // Read the documentation
            XmlDocument InputDocumentation = new XmlDocument();

            InputDocumentation.Load(InputDocumentationFile.FullName);

            // Make sure we can write to the output file
            if (FileReference.Exists(OutputFile))
            {
                FileReference.MakeWriteable(OutputFile);
            }
            else
            {
                DirectoryReference.CreateDirectory(OutputFile.Directory);
            }

            // Generate the documentation file
            if (OutputFile.HasExtension(".udn"))
            {
                WriteDocumentationUDN(OutputFile, InputDocumentation, CategoryToFields);
            }
            else if (OutputFile.HasExtension(".html"))
            {
                WriteDocumentationHTML(OutputFile, InputDocumentation, CategoryToFields);
            }
            else
            {
                throw new BuildException("Unable to detect format from extension of output file ({0})", OutputFile);
            }

            // Success!
            Log.TraceInformation("Written documentation to {0}.", OutputFile);
        }
Beispiel #3
0
        /// <summary>
        /// Collects all header files included in a source file
        /// </summary>
        /// <param name="ProjectFile"></param>
        /// <param name="SourceFile"></param>
        /// <param name="FileToRead"></param>
        /// <param name="FileContents"></param>
        /// <param name="InstalledFolder"></param>
        /// <param name="StartIndex"></param>
        /// <param name="EndIndex"></param>
        private static List <DependencyInclude> CollectHeaders(FileReference ProjectFile, FileReference SourceFile, string FileToRead, string FileContents, string InstalledFolder, int StartIndex, int EndIndex)
        {
            List <DependencyInclude> Result = new List <DependencyInclude>();

            Match             M        = CPPHeaderRegex.Match(FileContents, StartIndex, EndIndex - StartIndex);
            CaptureCollection Captures = M.Groups["HeaderFile"].Captures;

            Result.Capacity = Result.Count;
            foreach (Capture C in Captures)
            {
                string HeaderValue = C.Value;

                if (HeaderValue.IndexOfAny(Path.GetInvalidPathChars()) != -1)
                {
                    throw new BuildException("In {0}: An #include statement contains invalid characters.  You might be missing a double-quote character. (\"{1}\")", FileToRead, C.Value);
                }

                //@TODO: The intermediate exclusion is to work around autogenerated absolute paths in Module.SomeGame.cpp style files
                bool bCheckForBackwardSlashes = FileToRead.StartsWith(InstalledFolder) || ((ProjectFile != null) && new FileReference(FileToRead).IsUnderDirectory(ProjectFile.Directory));
                if (bCheckForBackwardSlashes && !FileToRead.Contains("Intermediate") && !FileToRead.Contains("ThirdParty") && HeaderValue.IndexOf('\\', 0) >= 0)
                {
                    throw new BuildException("In {0}: #include \"{1}\" contains backslashes ('\\'), please use forward slashes ('/') instead.", FileToRead, C.Value);
                }
                HeaderValue = Utils.CleanDirectorySeparators(HeaderValue);
                Result.Add(new DependencyInclude(HeaderValue));
            }

            // also look for #import in objective C files
            if (SourceFile.HasExtension(".MM") || SourceFile.HasExtension(".M"))
            {
                M                = MMHeaderRegex.Match(FileContents, StartIndex, EndIndex - StartIndex);
                Captures         = M.Groups["HeaderFile"].Captures;
                Result.Capacity += Captures.Count;
                foreach (Capture C in Captures)
                {
                    Result.Add(new DependencyInclude(C.Value));
                }
            }

            return(Result);
        }
Beispiel #4
0
        /// <summary>
        /// Checks if the given file is part of the working set
        /// </summary>
        /// <param name="File">File to check</param>
        /// <returns>True if the file is part of the working set, false otherwise</returns>
        public bool Contains(FileReference File)
        {
            // Generated .cpp files should never be treated as part of the working set
            if (File.HasExtension(".gen.cpp"))
            {
                return(false);
            }

            // Check if the file is read-only
            try
            {
                return(!FileReference.GetAttributes(File).HasFlag(FileAttributes.ReadOnly));
            }
            catch (FileNotFoundException)
            {
                return(false);
            }
        }
        /// <summary>
        /// Reads dependencies from the given file.
        /// </summary>
        /// <param name="InputFile">The file to read from</param>
        /// <returns>List of included dependencies</returns>
        static List <FileItem> ReadDependenciesFile(FileReference InputFile)
        {
            if (InputFile.HasExtension(".txt"))
            {
                string[] Lines = FileReference.ReadAllLines(InputFile);

                HashSet <FileItem> DependencyItems = new HashSet <FileItem>();
                foreach (string Line in Lines)
                {
                    if (Line.Length > 0)
                    {
                        // Ignore *.tlh and *.tli files generated by the compiler from COM DLLs
                        if (!Line.EndsWith(".tlh", StringComparison.OrdinalIgnoreCase) && !Line.EndsWith(".tli", StringComparison.OrdinalIgnoreCase))
                        {
                            DependencyItems.Add(FileItem.GetItemByPath(Line));
                        }
                    }
                }
                return(DependencyItems.ToList());
            }
            else if (InputFile.HasExtension(".d"))
            {
                string Text = FileReference.ReadAllText(InputFile);

                List <string> Tokens = new List <string>();

                StringBuilder Token = new StringBuilder();
                for (int Idx = 0; TryReadMakefileToken(Text, ref Idx, Token);)
                {
                    Tokens.Add(Token.ToString());
                }

                int TokenIdx = 0;
                while (TokenIdx < Tokens.Count && Tokens[TokenIdx] == "\n")
                {
                    TokenIdx++;
                }

                if (TokenIdx + 1 >= Tokens.Count || Tokens[TokenIdx + 1] != ":")
                {
                    throw new BuildException("Unable to parse dependency file");
                }

                TokenIdx += 2;

                List <FileItem> NewDependencyFiles = new List <FileItem>();
                for (; TokenIdx < Tokens.Count && Tokens[TokenIdx] != "\n"; TokenIdx++)
                {
                    NewDependencyFiles.Add(FileItem.GetItemByPath(Tokens[TokenIdx]));
                }

                while (TokenIdx < Tokens.Count && Tokens[TokenIdx] == "\n")
                {
                    TokenIdx++;
                }

                if (TokenIdx != Tokens.Count)
                {
                    throw new BuildException("Unable to parse dependency file");
                }

                return(NewDependencyFiles);
            }
            else
            {
                throw new BuildException("Unknown dependency list file type: {0}", InputFile);
            }
        }
 /// <summary>
 /// Determines if the file has the given extension
 /// </summary>
 /// <param name="Extension">The extension to check for</param>
 /// <returns>True if the file has the given extension, false otherwise</returns>
 public bool HasExtension(string Extension)
 {
     return(Location.HasExtension(Extension));
 }
Beispiel #7
0
        public static void WriteDocumentation(Type RulesType, FileReference OutputFile)
        {
            // Get the path to the XML documentation
            FileReference InputDocumentationFile = new FileReference(Assembly.GetExecutingAssembly().Location).ChangeExtension(".xml");

            if (!FileReference.Exists(InputDocumentationFile))
            {
                throw new BuildException("Generated assembly documentation not found at {0}.", InputDocumentationFile);
            }

            // Read the documentation
            XmlDocument InputDocumentation = new XmlDocument();

            InputDocumentation.Load(InputDocumentationFile.FullName);

            // Filter the properties into read-only and read/write lists
            List <FieldInfo> ReadOnlyFields  = new List <FieldInfo>();
            List <FieldInfo> ReadWriteFields = new List <FieldInfo>();

            foreach (FieldInfo Field in RulesType.GetFields(BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.Public))
            {
                if (!Field.FieldType.IsClass || !Field.FieldType.Name.EndsWith("TargetRules"))
                {
                    if (Field.IsInitOnly)
                    {
                        ReadOnlyFields.Add(Field);
                    }
                    else
                    {
                        ReadWriteFields.Add(Field);
                    }
                }
            }

            // Make sure the output file is writable
            if (FileReference.Exists(OutputFile))
            {
                FileReference.MakeWriteable(OutputFile);
            }
            else
            {
                DirectoryReference.CreateDirectory(OutputFile.Directory);
            }

            // Generate the documentation file
            if (OutputFile.HasExtension(".udn"))
            {
                WriteDocumentationUDN(OutputFile, ReadOnlyFields, ReadWriteFields, InputDocumentation);
            }
            else if (OutputFile.HasExtension(".html"))
            {
                WriteDocumentationHTML(OutputFile, ReadOnlyFields, ReadWriteFields, InputDocumentation);
            }
            else
            {
                throw new BuildException("Unable to detect format from extension of output file ({0})", OutputFile);
            }

            // Success!
            Log.TraceInformation("Written documentation to {0}.", OutputFile);
        }