Beispiel #1
0
        public void PointerSizeReturnValueNotLarge()
        {
            var config = new ConfigFile
            {
                Id        = nameof(PointerSizeReturnValueNotLarge),
                Namespace = nameof(PointerSizeReturnValueNotLarge),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "pointerSize.h",
                        Attach    = true,
                        Namespace = nameof(PointerSizeReturnValueNotLarge)
                    }
                },
                Extension =
                {
                    new DefineExtensionRule
                    {
                        Struct            = "SharpGen.Runtime.PointerSize",
                        SizeOf            = 8,
                        IsNativePrimitive = true,
                    }
                },
                Bindings =
                {
                    new BindRule("int", "SharpGen.Runtime.PointerSize")
                }
            };

            var iface = new CppInterface("Interface")
            {
                TotalMethodCount = 1
            };

            iface.Add(new CppMethod("method")
            {
                ReturnValue = new CppReturnValue
                {
                    TypeName = "int"
                }
            });

            var include = new CppInclude("pointerSize");

            include.Add(iface);

            var module = new CppModule("SharpGenTestModule");

            module.Add(include);

            var(solution, _) = MapModel(module, config);

            Assert.Single(solution.EnumerateDescendants().OfType <CsInterface>());

            var csIface = solution.EnumerateDescendants().OfType <CsInterface>().First();

            Assert.Single(csIface.Methods);

            var method = csIface.Methods.First();

            Assert.False(method.IsReturnStructLarge);
        }
Beispiel #2
0
        public void ContextRuleLimitsWhereMappingRuleExecutes()
        {
            var config = new Config.ConfigFile
            {
                Id        = nameof(ContextRuleLimitsWhereMappingRuleExecutes),
                Namespace = nameof(ContextRuleLimitsWhereMappingRuleExecutes),
                Includes  =
                {
                    new Config.IncludeRule
                    {
                        Attach    = true,
                        File      = "cppEnum.h",
                        Namespace = nameof(ContextRuleLimitsWhereMappingRuleExecutes)
                    },
                    new Config.IncludeRule
                    {
                        Attach    = true,
                        File      = "secondFile.h",
                        Namespace = nameof(ContextRuleLimitsWhereMappingRuleExecutes)
                    }
                },
                Mappings =
                {
                    new Config.ContextRule("cppEnum"),
                    new Config.MappingRule
                    {
                        Enum             = "AnotherEnum",
                        MappingNameFinal = "NewEnum"
                    },
                    new Config.ClearContextRule()
                }
            };

            var cppModel = new CppModule();

            var cppInclude = new CppInclude
            {
                Name = "cppEnum"
            };

            var cppEnum = new CppEnum
            {
                Name = "TestEnum"
            };

            var secondInclude = new CppInclude
            {
                Name = "secondFile"
            };

            var cppEnum2 = new CppEnum
            {
                Name = "AnotherEnum"
            };

            cppEnum.AddEnumItem("Element1", "0");
            cppEnum.AddEnumItem("Element2", "1");
            cppInclude.Add(cppEnum);
            cppModel.Add(cppInclude);


            var(solution, _) = MapModel(cppModel, config);

            Assert.Empty(solution.EnumerateDescendants().OfType <CsEnum>().Where(csEnum => csEnum.Name == "AnotherEnum"));
        }
Beispiel #3
0
        public void NonPortableLayoutDoesNotErrorWhenMarkedForCustomMarshalling()
        {
            var config = new ConfigFile
            {
                Id        = nameof(NonPortableLayoutDoesNotErrorWhenMarkedForCustomMarshalling),
                Namespace = nameof(NonPortableLayoutDoesNotErrorWhenMarkedForCustomMarshalling),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "test.h",
                        Attach    = true,
                        Namespace = nameof(NonPortableLayoutDoesNotErrorWhenMarkedForCustomMarshalling)
                    }
                },
                Bindings =
                {
                    new BindRule("int", "System.Int32")
                },
                Mappings =
                {
                    new MappingRule
                    {
                        Struct = "Test",
                        StructCustomMarshal = true
                    }
                }
            };


            var structure = new CppStruct("Test");

            structure.Add(new CppField("bitfield1")
            {
                TypeName   = "int",
                IsBitField = true,
                BitOffset  = 16,
                Offset     = 0,
            });
            structure.Add(new CppField("bitfield2")
            {
                TypeName   = "int",
                IsBitField = true,
                BitOffset  = 16,
                Offset     = 0
            });

            structure.Add(new CppField("pointer")
            {
                TypeName = "int",
                Pointer  = "*",
                Offset   = 1
            });

            structure.Add(new CppField("field")
            {
                TypeName = "int",
                Offset   = 2,
            });

            var include = new CppInclude("test");

            include.Add(structure);

            var module = new CppModule("SharpGenTestModule");

            module.Add(include);

            var(solution, _) = MapModel(module, config);

            Assert.False(Logger.HasErrors);
        }
Beispiel #4
0
        public void Basic()
        {
            var config = new ConfigFile
            {
                Id        = nameof(Basic),
                Namespace = nameof(Basic),
                Includes  =
                {
                    new IncludeRule
                    {
                        Attach    = true,
                        File      = "func.h",
                        Namespace = nameof(Basic)
                    }
                },
                Extension =
                {
                    new CreateExtensionRule
                    {
                        NewClass = $"{nameof(Basic)}.Functions",
                    }
                },
                Bindings =
                {
                    new BindRule("int", "System.Int32")
                },
                Mappings =
                {
                    new MappingRule
                    {
                        Function        = "Test",
                        FunctionDllName = "\"Test.dll\"",
                        Group           = $"{nameof(Basic)}.Functions"
                    }
                }
            };

            var function = new CppFunction("Test")
            {
                ReturnValue = new CppReturnValue
                {
                    TypeName = "int",
                }
            };

            var include = new CppInclude("func");

            var module = new CppModule("SharpGenTestModule");

            include.Add(function);
            module.Add(include);

            var(solution, _) = MapModel(module, config);

            Assert.Single(solution.EnumerateDescendants().OfType <CsGroup>());

            var group = solution.EnumerateDescendants().OfType <CsGroup>().First();

            Assert.Equal("Functions", group.Name);

            Assert.Single(group.Functions);

            var csFunc = group.Functions.First();

            Assert.Equal(TypeRegistry.Int32, csFunc.ReturnValue.PublicType);
            Assert.Empty(csFunc.Parameters);
            Assert.Equal(Visibility.Static, csFunc.Visibility & Visibility.Static);
        }
Beispiel #5
0
        public void MultipleBitfieldOffsetsGeneratedCorrectly()
        {
            var config = new ConfigFile
            {
                Id        = nameof(MultipleBitfieldOffsetsGeneratedCorrectly),
                Namespace = nameof(MultipleBitfieldOffsetsGeneratedCorrectly),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "test.h",
                        Attach    = true,
                        Namespace = nameof(MultipleBitfieldOffsetsGeneratedCorrectly)
                    }
                },
                Bindings =
                {
                    new BindRule("int", "System.Int32")
                }
            };


            var structure = new CppStruct("Test");

            structure.Add(new CppField("bitfield1")
            {
                TypeName   = "int",
                IsBitField = true,
                BitOffset  = 16,
                Offset     = 0,
            });
            structure.Add(new CppField("field")
            {
                TypeName = "int",
                Offset   = 1,
            });
            structure.Add(new CppField("bitfield2")
            {
                TypeName   = "int",
                IsBitField = true,
                BitOffset  = 16,
                Offset     = 2
            });

            var include = new CppInclude("test");

            include.Add(structure);

            var module = new CppModule("SharpGenTestModule");

            module.Add(include);

            var(solution, _) = MapModel(module, config);

            var csStruct = solution.EnumerateDescendants().OfType <CsStruct>().First();

            var bitField1 = csStruct.Fields.First(field => field.Name == "Bitfield1");

            Assert.Equal(0, bitField1.BitOffset);
            Assert.Equal(0u, bitField1.Offset);
            Assert.Equal((1 << 16) - 1, bitField1.BitMask);
            Assert.True(bitField1.IsBitField);

            var csField = csStruct.Fields.First(field => field.Name == "Field");

            Assert.Equal(4u, csField.Offset);
            Assert.False(csField.IsBitField);

            var bitField2 = csStruct.Fields.First(field => field.Name == "Bitfield2");

            Assert.Equal(0, bitField2.BitOffset);
            Assert.Equal(8u, bitField2.Offset);
            Assert.Equal((1 << 16) - 1, bitField2.BitMask);
            Assert.True(bitField2.IsBitField);
        }
Beispiel #6
0
        public void NonPortableStructAlignmentRaisesError()
        {
            var config = new ConfigFile
            {
                Id        = nameof(NonPortableStructAlignmentRaisesError),
                Namespace = nameof(NonPortableStructAlignmentRaisesError),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "test.h",
                        Attach    = true,
                        Namespace = nameof(NonPortableStructAlignmentRaisesError)
                    }
                },
                Bindings =
                {
                    new BindRule("int", "System.Int32")
                }
            };


            var structure = new CppStruct("Test");

            structure.Add(new CppField("bitfield1")
            {
                TypeName   = "int",
                IsBitField = true,
                BitOffset  = 16,
                Offset     = 0,
            });
            structure.Add(new CppField("bitfield2")
            {
                TypeName   = "int",
                IsBitField = true,
                BitOffset  = 16,
                Offset     = 0
            });

            structure.Add(new CppField("pointer")
            {
                TypeName = "int",
                Pointer  = "*",
                Offset   = 1
            });

            structure.Add(new CppField("field")
            {
                TypeName = "int",
                Offset   = 2,
            });

            var include = new CppInclude("test");

            include.Add(structure);

            var module = new CppModule("SharpGenTestModule");

            module.Add(include);

            using (LoggerMessageCountEnvironment(1, LogLevel.Error))
                using (LoggerCodeRequiredEnvironment(LoggingCodes.NonPortableAlignment))
                {
                    MapModel(module, config);
                }
        }
        public void DualCallbackFlowsNativeImplementation()
        {
            var config = new ConfigFile
            {
                Id        = nameof(Simple),
                Namespace = nameof(Simple),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "interface.h",
                        Attach    = true,
                        Namespace = nameof(Simple)
                    }
                },
                Bindings =
                {
                    new BindRule("int", "System.Int32")
                },
                Mappings =
                {
                    new MappingRule
                    {
                        Interface               = "Interface",
                        IsCallbackInterface     = true,
                        IsDualCallbackInterface = true
                    }
                }
            };

            var iface = new CppInterface
            {
                Name             = "Interface",
                TotalMethodCount = 1
            };

            iface.Add(new CppMethod
            {
                Name        = "method",
                ReturnValue = new CppReturnValue
                {
                    TypeName = "int"
                }
            });

            var include = new CppInclude
            {
                Name = "interface"
            };

            include.Add(iface);

            var module = new CppModule();

            module.Add(include);

            var(_, defines) = GetConsumerBindings(module, config);

            var interfaceDefine = defines.First(define => define.Interface == "Simple.Interface");

            Assert.Equal("Simple.InterfaceNative", interfaceDefine.NativeImplementation);
        }
Beispiel #8
0
        public void NativePrimitiveTypeNotLarge()
        {
            var config = new ConfigFile
            {
                Id        = nameof(NativePrimitiveTypeNotLarge),
                Namespace = nameof(NativePrimitiveTypeNotLarge),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "pointerSize.h",
                        Attach    = true,
                        Namespace = nameof(NativePrimitiveTypeNotLarge)
                    }
                },
                Extension =
                {
                    new DefineExtensionRule
                    {
                        Struct            = "NativePrimitiveType",
                        SizeOf            = 16,
                        IsNativePrimitive = true,
                    }
                },
                Bindings =
                {
                    new BindRule("NativePrimitive", "NativePrimitiveType")
                }
            };

            var iface = new CppInterface
            {
                Name             = "Interface",
                TotalMethodCount = 1
            };

            iface.Add(new CppMethod
            {
                Name        = "method",
                ReturnValue = new CppReturnValue
                {
                    TypeName = "NativePrimitive"
                }
            });

            var include = new CppInclude
            {
                Name = "pointerSize"
            };

            include.Add(iface);

            var module = new CppModule();

            module.Add(include);

            var(solution, _) = MapModel(module, config);

            Assert.Single(solution.EnumerateDescendants().OfType <CsInterface>());

            var csIface = solution.EnumerateDescendants().OfType <CsInterface>().First();

            Assert.Single(csIface.Methods);

            var method = csIface.Methods.First();

            Assert.False(method.IsReturnStructLarge);

            Assert.False(Logger.HasErrors);
        }
        public void DefineWithNativeImplementationDefinesNativeImplementationType()
        {
            var config = new ConfigFile
            {
                Id        = nameof(Simple),
                Namespace = nameof(Simple),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "interface.h",
                        Attach    = true,
                        Namespace = nameof(Simple)
                    }
                },
                Extension =
                {
                    new DefineExtensionRule
                    {
                        Interface            = "Imported.Param",
                        NativeImplementation = "Imported.ParamNative"
                    }
                },
                Bindings =
                {
                    new BindRule("int",   "System.Int32"),
                    new BindRule("Param", "Imported.Param")
                }
            };

            var iface = new CppInterface
            {
                Name             = "Interface",
                TotalMethodCount = 1
            };

            var method = new CppMethod
            {
                Name        = "method",
                ReturnValue = new CppReturnValue
                {
                    TypeName = "int"
                }
            };

            method.Add(new CppParameter
            {
                Name     = "param",
                TypeName = "Param",
                Pointer  = "*"
            });

            iface.Add(method);

            var include = new CppInclude
            {
                Name = "interface"
            };

            include.Add(iface);

            var module = new CppModule();

            module.Add(include);

            var(solution, _) = MapModel(module, config);

            Assert.Single(solution.EnumerateDescendants().OfType <CsParameter>());

            var param = solution.EnumerateDescendants().OfType <CsParameter>().First();

            Assert.IsType <CsInterface>(param.PublicType);

            Assert.NotNull(((CsInterface)param.PublicType).NativeImplementation);

            Assert.False(Logger.HasErrors);
        }
Beispiel #10
0
        public void Simple()
        {
            var config = new ConfigFile
            {
                Id        = nameof(Simple),
                Namespace = nameof(Simple),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "interface.h",
                        Attach    = true,
                        Namespace = nameof(Simple)
                    }
                },
                Bindings =
                {
                    new BindRule("int", "System.Int32")
                }
            };

            var iface = new CppInterface
            {
                Name             = "Interface",
                TotalMethodCount = 1
            };

            iface.Add(new CppMethod
            {
                Name        = "method",
                ReturnValue = new CppReturnValue
                {
                    TypeName = "int"
                }
            });

            var include = new CppInclude
            {
                Name = "interface"
            };

            include.Add(iface);

            var module = new CppModule();

            module.Add(include);

            var(solution, _) = MapModel(module, config);

            Assert.Single(solution.EnumerateDescendants().OfType <CsInterface>());

            var csIface = solution.EnumerateDescendants().OfType <CsInterface>().First();

            Assert.Single(csIface.Methods);

            var method = csIface.Methods.First();

            Assert.Equal(0, method.Offset);

            Assert.IsType <CsFundamentalType>(method.ReturnValue.PublicType);

            Assert.Equal(typeof(int), ((CsFundamentalType)method.ReturnValue.PublicType).Type);
        }
Beispiel #11
0
        public void NonPortableStructAlignmentRaisesError()
        {
            var config = new Config.ConfigFile
            {
                Id        = nameof(NonPortableStructAlignmentRaisesError),
                Namespace = nameof(NonPortableStructAlignmentRaisesError),
                Includes  =
                {
                    new Config.IncludeRule
                    {
                        File      = "test.h",
                        Attach    = true,
                        Namespace = nameof(NonPortableStructAlignmentRaisesError)
                    }
                },
                Bindings =
                {
                    new Config.BindRule("int", "System.Int32")
                }
            };


            var structure = new CppStruct
            {
                Name = "Test"
            };

            structure.Add(new CppField
            {
                Name       = "bitfield1",
                TypeName   = "int",
                IsBitField = true,
                BitOffset  = 16,
                Offset     = 0,
            });
            structure.Add(new CppField
            {
                Name       = "bitfield2",
                TypeName   = "int",
                IsBitField = true,
                BitOffset  = 16,
                Offset     = 0
            });

            structure.Add(new CppField
            {
                Name     = "pointer",
                TypeName = "int",
                Pointer  = "*",
                Offset   = 1
            });

            structure.Add(new CppField
            {
                Name     = "field",
                TypeName = "int",
                Offset   = 2,
            });

            var include = new CppInclude
            {
                Name = "test"
            };

            include.Add(structure);

            var module = new CppModule();

            module.Add(include);

            var(solution, _) = MapModel(module, config);

            AssertLoggingCodeLogged(LoggingCodes.NonPortableAlignment);
        }
Beispiel #12
0
        public void UnionsWithPointersGeneratesStructure()
        {
            var config = new Config.ConfigFile
            {
                Id        = nameof(UnionsWithPointersGeneratesStructure),
                Namespace = nameof(UnionsWithPointersGeneratesStructure),
                Includes  =
                {
                    new Config.IncludeRule
                    {
                        File      = "test.h",
                        Attach    = true,
                        Namespace = nameof(UnionsWithPointersGeneratesStructure)
                    }
                },
                Bindings =
                {
                    new Config.BindRule("int", "System.Int32")
                }
            };


            var structure = new CppStruct
            {
                Name    = "Test",
                IsUnion = true
            };

            structure.Add(new CppField
            {
                Name     = "pointer",
                TypeName = "int",
                Pointer  = "*"
            });

            structure.Add(new CppField
            {
                Name     = "scalar",
                TypeName = "int"
            });

            var include = new CppInclude
            {
                Name = "test"
            };

            include.Add(structure);

            var module = new CppModule();

            module.Add(include);

            var(solution, _) = MapModel(module, config);

            var csStruct = solution.EnumerateDescendants().OfType <CsStruct>().First();

            foreach (var field in csStruct.Fields)
            {
                Assert.Equal(0, field.Offset);
            }

            Assert.False(Logger.HasErrors);
        }
Beispiel #13
0
        public void IntFieldMappedToBoolIsMarkedAsBoolToInt()
        {
            var structName = "BoolToInt";
            var config     = new Config.ConfigFile
            {
                Id        = nameof(IntFieldMappedToBoolIsMarkedAsBoolToInt),
                Namespace = nameof(IntFieldMappedToBoolIsMarkedAsBoolToInt),
                Includes  =
                {
                    new Config.IncludeRule
                    {
                        File      = "test.h",
                        Attach    = true,
                        Namespace = nameof(IntFieldMappedToBoolIsMarkedAsBoolToInt)
                    }
                },
                Bindings =
                {
                    new Config.BindRule("int",  "System.Int32"),
                    new Config.BindRule("bool", "System.Boolean")
                },
                Mappings =
                {
                    new Config.MappingRule
                    {
                        Field       = $"{structName}::field",
                        MappingType = "bool",
                    },
                }
            };

            var structure = new CppStruct
            {
                Name = structName
            };

            structure.Add(new CppField
            {
                Name     = "field",
                TypeName = "int"
            });

            var include = new CppInclude
            {
                Name = "test"
            };

            include.Add(structure);

            var module = new CppModule();

            module.Add(include);

            var(solution, _) = MapModel(module, config);

            Assert.Single(solution.EnumerateDescendants().OfType <CsStruct>().Where(csStruct => csStruct.Name == structName));

            var generatedStruct = solution.EnumerateDescendants().OfType <CsStruct>().First(csStruct => csStruct.Name == structName);

            Assert.Single(generatedStruct.Fields);

            var field = generatedStruct.Fields.First();

            Assert.True(field.IsBoolToInt);
        }
Beispiel #14
0
        public void InheritingStructs()
        {
            var config = new Config.ConfigFile
            {
                Id        = nameof(InheritingStructs),
                Namespace = nameof(InheritingStructs),
                Includes  =
                {
                    new Config.IncludeRule
                    {
                        File      = "struct.h",
                        Attach    = true,
                        Namespace = nameof(SequentialOffsets)
                    }
                },
                Bindings =
                {
                    new Config.BindRule("int", "System.Int32")
                }
            };

            var baseStruct = new CppStruct
            {
                Name = "base"
            };

            baseStruct.Add(new CppField
            {
                Name     = "field",
                TypeName = "int"
            });

            var inheritingStruct = new CppStruct
            {
                Name = "inheriting",
                Base = "base"
            };

            inheritingStruct.Add(new CppField
            {
                Name     = "field2",
                TypeName = "int",
                Offset   = 1
            });

            var cppInclude = new CppInclude
            {
                Name = "struct"
            };

            var cppModule = new CppModule();

            cppModule.Add(cppInclude);
            cppInclude.Add(baseStruct);
            cppInclude.Add(inheritingStruct);

            var(solution, _) = MapModel(cppModule, config);

            var csStruct = solution.EnumerateDescendants().OfType <CsStruct>().First(@struct => @struct.Name == "Inheriting");

            var field  = csStruct.Fields.First(fld => fld.Name == "Field");
            var field2 = csStruct.Fields.First(fld => fld.Name == "Field2");

            Assert.Equal(0, field.Offset);

            Assert.Equal(4, field2.Offset);
        }
Beispiel #15
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();
                }
            }
        }