Exemplo n.º 1
0
        public void SequentialOffsets()
        {
            var config = new Config.ConfigFile
            {
                Id        = nameof(SequentialOffsets),
                Namespace = nameof(SequentialOffsets),
                Includes  =
                {
                    new Config.IncludeRule
                    {
                        File      = "simple.h",
                        Attach    = true,
                        Namespace = nameof(SequentialOffsets)
                    }
                },
                Bindings =
                {
                    new Config.BindRule("int", "System.Int32")
                }
            };

            var cppStruct = new CppStruct
            {
                Name = "struct"
            };

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

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

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

            var cppModule = new CppModule();

            cppModule.Add(cppInclude);
            cppInclude.Add(cppStruct);

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

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

            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);
        }
Exemplo n.º 2
0
        public void UnionsWithPointersGeneratesStructure()
        {
            var config = new ConfigFile
            {
                Id        = nameof(UnionsWithPointersGeneratesStructure),
                Namespace = nameof(UnionsWithPointersGeneratesStructure),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "test.h",
                        Attach    = true,
                        Namespace = nameof(UnionsWithPointersGeneratesStructure)
                    }
                },
                Bindings =
                {
                    new BindRule("int", "System.Int32")
                }
            };


            var structure = new CppStruct("Test")
            {
                IsUnion = true
            };

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

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

            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();

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

            Assert.False(Logger.HasErrors);
        }
Exemplo n.º 3
0
        public void Simple()
        {
            var config = new Config.ConfigFile
            {
                Id        = nameof(Simple),
                Namespace = nameof(Simple),
                Assembly  = nameof(Simple),
                Includes  =
                {
                    new Config.IncludeRule
                    {
                        File      = "simple.h",
                        Attach    = true,
                        Namespace = nameof(Simple)
                    }
                },
                Bindings =
                {
                    new Config.BindRule("int", "System.Int32")
                }
            };

            var cppStruct = new CppStruct
            {
                Name = "struct"
            };

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

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

            var cppModule = new CppModule();

            cppModule.Add(cppInclude);
            cppInclude.Add(cppStruct);

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

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

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

            Assert.Single(csStruct.Fields.Where(fld => fld.Name == "Field"));

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

            Assert.IsType <CsFundamentalType>(field.PublicType);

            var fundamental = (CsFundamentalType)field.PublicType;

            Assert.Equal(typeof(int), fundamental.Type);
        }
Exemplo n.º 4
0
        public void IntFieldMappedToBoolIsMarkedAsBoolToInt()
        {
            var structName = "BoolToInt";
            var config     = new ConfigFile
            {
                Id        = nameof(IntFieldMappedToBoolIsMarkedAsBoolToInt),
                Namespace = nameof(IntFieldMappedToBoolIsMarkedAsBoolToInt),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "test.h",
                        Attach    = true,
                        Namespace = nameof(IntFieldMappedToBoolIsMarkedAsBoolToInt)
                    }
                },
                Bindings =
                {
                    new BindRule("int",  "System.Int32"),
                    new BindRule("bool", "System.Boolean")
                },
                Mappings =
                {
                    new MappingRule
                    {
                        Field       = $"{structName}::field",
                        MappingType = "bool",
                    },
                }
            };

            var structure = new CppStruct(structName);

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

            var include = new CppInclude("test");

            include.Add(structure);

            var module = new CppModule("SharpGenTestModule");

            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);
        }
Exemplo n.º 5
0
        public void InheritingStructs()
        {
            var config = new ConfigFile
            {
                Id        = nameof(InheritingStructs),
                Namespace = nameof(InheritingStructs),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "struct.h",
                        Attach    = true,
                        Namespace = nameof(SequentialOffsets)
                    }
                },
                Bindings =
                {
                    new BindRule("int", "System.Int32")
                }
            };

            var baseStruct = new CppStruct("base");

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

            var inheritingStruct = new CppStruct("inheriting")
            {
                Base = "base"
            };

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

            var cppInclude = new CppInclude("struct");

            var cppModule = new CppModule("SharpGenTestModule");

            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(0u, field.Offset);

            Assert.Equal(4u, field2.Offset);
        }
Exemplo n.º 6
0
        public void MappingNameRuleRenamesStructMember()
        {
            var config = new Config.ConfigFile
            {
                Id        = nameof(MappingNameRuleRenamesStructMember),
                Namespace = nameof(MappingNameRuleRenamesStructMember),
                Assembly  = nameof(MappingNameRuleRenamesStructMember),
                Includes  =
                {
                    new Config.IncludeRule
                    {
                        File      = "simpleStruct.h",
                        Attach    = true,
                        Namespace = nameof(MappingNameRuleRenamesStructMember)
                    }
                },
                Bindings =
                {
                    new Config.BindRule("int", "System.Int32")
                },
                Mappings =
                {
                    new Config.MappingRule
                    {
                        Field       = "Test::field",
                        MappingName = "MyField"
                    }
                }
            };

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

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

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

            include.Add(cppStruct);
            var module = new CppModule();

            module.Add(include);

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

            var csStruct = solution.EnumerateDescendants().OfType <CsStruct>().First(element => element.Name == "Test");

            Assert.Single(csStruct.Fields.Where(field => field.Name == "MyField"));
        }
Exemplo n.º 7
0
        public void Simple()
        {
            var config = new ConfigFile
            {
                Id        = nameof(Simple),
                Namespace = nameof(Simple),
                Includes  =
                {
                    new IncludeRule
                    {
                        File      = "simple.h",
                        Attach    = true,
                        Namespace = nameof(Simple)
                    }
                },
                Bindings =
                {
                    new BindRule("int", "System.Int32")
                }
            };

            var cppStruct = new CppStruct("struct");

            cppStruct.Add(new CppField("field")
            {
                TypeName = "int"
            });

            var cppInclude = new CppInclude("simple");

            var cppModule = new CppModule("SharpGenTestModule");

            cppModule.Add(cppInclude);
            cppInclude.Add(cppStruct);

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

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

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

            Assert.Single(csStruct.Fields.Where(fld => fld.Name == "Field"));

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

            Assert.IsType <CsFundamentalType>(field.PublicType);
            Assert.Equal(TypeRegistry.Int32, field.PublicType);
        }
Exemplo n.º 8
0
    public void MappingNameRuleRenamesStruct()
    {
        var config = new ConfigFile
        {
            Id        = nameof(MappingNameRuleRenamesStruct),
            Namespace = nameof(MappingNameRuleRenamesStruct),
            Includes  =
            {
                new IncludeRule
                {
                    File      = "simpleStruct.h",
                    Attach    = true,
                    Namespace = nameof(MappingNameRuleRenamesStruct)
                }
            },
            Bindings =
            {
                new BindRule("int", "System.Int32")
            },
            Mappings =
            {
                new MappingRule
                {
                    Struct      = "Test",
                    MappingName = "MyStruct"
                }
            }
        };

        var cppStruct = new CppStruct("Test");

        cppStruct.Add(new CppField("field")
        {
            TypeName = "int"
        });

        var include = new CppInclude("simpleStruct");

        include.Add(cppStruct);
        var module = new CppModule("SharpGenTestModule");

        module.Add(include);

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

        Assert.Single(solution.EnumerateDescendants <CsStruct>().Where(element => element.Name == "MyStruct"));
    }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
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);
                }
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Parses a C++ struct or union declaration.
        /// </summary>
        private CppStruct ParseStructOrUnion(XElement xElement, CppElement cppParent = null, int innerAnonymousIndex = 0)
        {
            CppStruct cppStruct = xElement.Annotation <CppStruct>();

            if (cppStruct != null)
            {
                return(cppStruct);
            }

            // Build struct name directly from the struct name or based on the parent
            string     structName          = String.Empty;
            XAttribute structNameAttribute = xElement.Attribute("name");

            if (structNameAttribute != null)
            {
                structName = structNameAttribute.Value;
            }

            if (cppParent != null)
            {
                if (string.IsNullOrEmpty(structName))
                {
                    structName = cppParent.Name + "_Inner_" + innerAnonymousIndex;
                }
                else
                {
                    structName = cppParent.Name + "_" + structName + "_Inner";
                }
            }

            // Create struct
            cppStruct = new CppStruct {
                Name = structName
            };
            xElement.AddAnnotation(cppStruct);
            bool isUnion = (xElement.Name.LocalName == StringEnum.GetStringValue(CastXMLTag.Union));

            // Get align from structure
            cppStruct.Align = xElement.Attribute("align") != null?int.Parse(xElement.Attribute("align").Value) / 8 : 0;

            // Enter struct/union description
            var basesValueAttribute    = xElement.Attribute("bases");
            IEnumerable <string> bases = basesValueAttribute != null?basesValueAttribute.Value.Split(' ') : Enumerable.Empty <string>();

            foreach (string xElementBaseId in bases)
            {
                if (string.IsNullOrEmpty(xElementBaseId))
                {
                    continue;
                }

                XElement xElementBase = mapIdToXElement[xElementBaseId];

                CppStruct cppStructBase = ParseStructOrUnion(xElementBase);
                if (string.IsNullOrEmpty(cppStructBase.ParentName))
                {
                    cppStruct.ParentName = cppStructBase.Name;
                }
            }

            // Parse all fields
            int fieldOffset      = 0;
            int innerStructCount = 0;

            foreach (XElement field in xElement.Elements())
            {
                if (field.Name.LocalName != StringEnum.GetStringValue(CastXMLTag.Field))
                {
                    continue;
                }

                // Parse the field
                var cppField = ParseField(field);
                cppField.Offset = fieldOffset;

                // Test if the field type is declared inside this struct or union
                string fieldName = field.Attribute("name") != null?field.Attribute("name").Value : String.Empty;

                string fieldTypeId = field.Attribute("type") != null?field.Attribute("type").Value : String.Empty;

                XElement fieldType        = mapIdToXElement[fieldTypeId];
                string   fieldTypeContext = fieldType.Attribute("context") != null?fieldType.Attribute("context").Value : String.Empty;

                string fieldId = field.Attribute("id") != null?field.Attribute("id").Value : String.Empty;

                if (fieldTypeContext == fieldId)
                {
                    var fieldSubStruct = ParseStructOrUnion(fieldType, cppStruct, innerStructCount++);

                    // If fieldName is empty, then we need to inline fields from the struct/union.
                    if (string.IsNullOrEmpty(fieldName))
                    {
                        // Make a copy in order to remove fields
                        List <CppField> listOfSubFields = new List <CppField>(fieldSubStruct.Fields);

                        // Copy the current field offset
                        int lastFieldOffset = fieldOffset;
                        foreach (CppField subField in listOfSubFields)
                        {
                            subField.Offset = subField.Offset + fieldOffset;
                            cppStruct.Add(subField);
                            lastFieldOffset = subField.Offset;
                        }

                        // Set the current field offset according to the inlined fields
                        if (!isUnion)
                        {
                            fieldOffset = lastFieldOffset;
                        }

                        // Don't add the current field, as it is actually an inline struct/union
                        cppField = null;
                    }
                    else
                    {
                        // Get the type name from the inner-struct and set it to the field
                        cppField.TypeName = fieldSubStruct.Name;
                        currentCppInclude.Add(fieldSubStruct);
                    }
                }

                // Go to next field offset if not in union
                bool goToNextFieldOffset = !isUnion;

                // Add the field if any
                if (cppField != null)
                {
                    cppStruct.Add(cppField);
                    // TODO managed multiple bitfield group
                    // Current implem is only working with a single set of consecutive bitfield in the same struct
                    goToNextFieldOffset = goToNextFieldOffset && !cppField.IsBitField;
                }

                if (goToNextFieldOffset)
                {
                    fieldOffset++;
                }
            }

            return(cppStruct);
        }