Beispiel #1
0
        /// <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);
                    }
                }
            }
        }
Beispiel #2
0
    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));
                }
            }
        }
Beispiel #4
0
        /// <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();
                }
            }
        }