/// <summary> /// Parses all C++ elements. This is the main method that iterates on all types. /// </summary> private void ParseAllElements() { foreach (string includeCastXmlId in mapFileToXElement.Keys) { // Process only files listed inside the config files string includeId = GetIncludeIdFromFileId(includeCastXmlId); if (!includeToProcess.ContainsKey(includeId)) { continue; } // Log current include being processed log.Info("Process include: " + includeId + ".h"); // Try to find CppInclude instance currentCppInclude = masterCppModule.FindInclude(includeId); if (currentCppInclude == null) { currentCppInclude = new CppInclude() { Name = includeId }; masterCppModule.Add(currentCppInclude); } foreach (XElement xElement in mapFileToXElement[includeCastXmlId]) { // If incomplete flag, than element cannot be parsed if (xElement.Attribute("incomplete") != null) { continue; } // Parse current element CppElement cppElement = ParseElement(xElement); // Check if cppElement was parsed if (cppElement != null) { // Parse complete namespace XAttribute contextAttribute = xElement.Attribute("context"); if ((contextAttribute != null) && string.IsNullOrEmpty(cppElement.Namespace)) { XElement parentContext = mapIdToXElement[contextAttribute.Value]; if (parentContext != null) { cppElement.Namespace = ParseNamespace(parentContext); } } currentCppInclude.Add(cppElement); } } } }
public static CppModule CreateSkeletonModule(this ConfigFile config) { var module = new CppModule(config.Id); foreach (var includeRule in config.ConfigFilesLoaded.SelectMany(cfg => cfg.Includes)) { var cppInclude = module.FindInclude(includeRule.Id); if (cppInclude != null) { continue; } module.Add(new CppInclude(includeRule.Id)); } return(module); }
/// <summary> /// Parses the specified C++ header file and fills the <see cref="CppModule"/> with defined macros. /// </summary> /// <param name="file">The C++ header file to parse.</param> /// <param name="group">The CppIncludse object to fill with macro definitions.</param> public void Parse(string file, CppModule group) { _gccxml.Preprocess(file, ParseLine); foreach (var includeName in _mapIncludeToMacros.Keys) { var includeId = Path.GetFileNameWithoutExtension(includeName); var include = group.FindInclude(includeId); if (include == null) { include = new CppInclude { Name = includeId }; group.Add(include); } foreach (var macroDefinition in _mapIncludeToMacros[includeName]) { include.Add(new CppDefine(macroDefinition.Key, macroDefinition.Value)); } } }
/// <summary> /// Initialize this Parser from a config file. /// </summary> public void Initialize(ConfigMapping config) { masterConfig = config; masterHeaderFile = masterConfig.Id + ".hpp"; // Config is updated if ForceParsing is true masterConfigHasChanged = ForceParsing; // Create CppModule instance masterCppModule = new CppModule(); // Create CastXml instance castXML = new CastXML(); castXML.ExecutablePath = CastXmlExecutablePath; castXML.VcToolsPath = VcToolsPath; // Add current directory for gccxml castXML.IncludeDirs.Add(new IncludeDirMapping(Environment.CurrentDirectory)); // Configure gccxml with include directory foreach (ConfigMapping configFile in masterConfig.ConfigFilesLoaded) { // Add all include directories foreach (IncludeDirMapping includeDir in configFile.IncludeDirs) { castXML.IncludeDirs.Add(includeDir); } } // Check if the file has any includes related config List <string> filesWithIncludes = new List <string>(); foreach (ConfigMapping configFile in masterConfig.ConfigFilesLoaded) { bool isWithInclude = false; // Add this config file as an include to process includeToProcess.Add(configFile.Id, true); if (configFile.IncludeDirs.Count > 0) { isWithInclude = true; } if (configFile.Includes.Count > 0) { isWithInclude = true; } if (configFile.References.Count > 0) { isWithInclude = true; } // If this config file has any include rules if (isWithInclude) { filesWithIncludes.Add(configFile.Id); } } // Write include files foreach (ConfigMapping configFile in masterConfig.ConfigFilesLoaded) { // Check if config have includes if (!filesWithIncludes.Contains(configFile.Id)) { // Skip, process next config continue; } var outputConfig = new StringWriter(); outputConfig.WriteLine("// pylon-node include config for {0} - Version {1}", configFile.Id, Version); outputConfig.WriteLine("// Do not edit this file, is generated by pylon-node-gen"); outputConfig.WriteLine("//"); outputConfig.WriteLine(); // Write includes foreach (IncludeMapping includeMapping in configFile.Includes) { CppInclude cppInclude = masterCppModule.FindInclude(includeMapping.Id); if (cppInclude == null) { includeToProcess.Add(includeMapping.Id, true); cppInclude = new CppInclude(); cppInclude.Name = includeMapping.Id; masterCppModule.Add(cppInclude); } outputConfig.WriteLine("#include <{0}>", includeMapping.File); } // Write includes to references foreach (ConfigMapping reference in configFile.References) { if (filesWithIncludes.Contains(reference.Id)) { outputConfig.WriteLine("#include \"{0}\"", reference.Id + ".hpp"); } } outputConfig.Close(); string outputConfigString = outputConfig.ToString(); string outputConfigFile = configFile.Id + ".hpp"; // Test if Last config file was generated. If not, then we need to generate it // If it exists, then we need to test if it is the same than previous run configFile.IsConfigUpdated = ForceParsing; if (File.Exists(outputConfigFile) && !ForceParsing) { configFile.IsConfigUpdated = outputConfigString != File.ReadAllText(outputConfigFile); } else { configFile.IsConfigUpdated = true; } // Just write the header file when the file is updated or new if (configFile.IsConfigUpdated) { log.Info("Config file changed for C++ headers (module: " + configFile.Id + ", config: " + configFile.FilePath + ")"); masterConfigHasChanged = true; var fileWriter = new StreamWriter(outputConfigFile); fileWriter.Write(outputConfigString); fileWriter.Close(); } } }