Ejemplo n.º 1
0
        private static void WriteGL(XmlSpecData glSpec, DotNetTranslator translator, DotNetFileWriter writer)
        {
            Console.WriteLine("GLDotNet.GL");

            var glCommands = glSpec.Features.Where(x => x.Api == "gl" && (x.VersionMajor <= 3 || (x.VersionMajor == 4 && x.VersionMinor <= 5))).SelectMany(x => x.AddedCommands);

            var glApi = translator.Translate(glSpec, new DotNetTranslator.Options()
            {
                Prefix = "gl",
                CommandFilter = x => glCommands.Contains(x.Name),
                EnumGroupFilter = ShouldOutputEnumGroup,
                EnumFilter = ShouldOutputEnum
            });
            //XmlSerializer.WriteToFile(glApi, "glDotNetData.xml");

            writer.WriteFiles(glApi, new DotNetFileWriter.Options()
            {
                Prefix = "GL",
                OutputPath = @"..\..\..\GLDotNet.GL\",
                Namespace = "GLDotNet.GL",
                ConstantsFileName = "GLConstants.Generated.cs",
                ConstantsClassName = "GLConstants",
                EnumsFileName = "GLEnums.Generated.cs",
                CommandsFileName = "GLCommands.Generated.cs",
                CommandsClassName = "GLCommands",
                ContextFileName = "GLContext.Generated.cs",
                ContextClassName = "GLContext",
                ContextInitializeDelegatesByVersionNumber = true
            });
        }
Ejemplo n.º 2
0
        private void TranslateEnumGroups(XmlSpecData spec, DotNetApiData api, Options options)
        {
            foreach (var specEnumGroup in spec.EnumGroups.Where(x => options.EnumGroupFilter(x.Name)))
            {
                var enumGroupData = new DotNetEnumGroupData()
                {
                    Name = specEnumGroup.Name,
                };

                foreach (var enumName in specEnumGroup.Enums.Distinct())
                {
                    var xmlEnumData = spec.Enums.SingleOrDefault(x => x.Name == enumName);

                    if (xmlEnumData == null || !options.EnumFilter(xmlEnumData))
                        continue;

                    var enumData = api.Enums.SingleOrDefault(x => x.OriginalName == enumName);

                    if (enumData == null)
                        continue;

                    enumGroupData.Enums.Add(enumData);

                    if (spec.Enums.Single(x => x.Name == enumName).Type == "bitmask")
                        enumGroupData.IsFlags = true;
                }

                api.EnumGroups.Add(enumGroupData);
            }
        }
Ejemplo n.º 3
0
        public DotNetApiData Translate(XmlSpecData spec, Options options)
        {
            DotNetApiData api = new DotNetApiData();

            this.TranslateEnums(spec, api, options);
            this.TranslateEnumGroups(spec, api, options);
            this.TranslateFunctions(spec, api, options);

            return api;
        }
Ejemplo n.º 4
0
		private void TranslateEnums(XmlSpecData spec, DotNetApiData api, Options options)
		{			
			foreach (var specEnum in spec.Enums.Where(x => options.EnumFilter(x)))
			{
				var enumData = new DotNetEnumData()
				{
					OriginalName = specEnum.Name,
					Name = this.InflectEnumName(specEnum.Name, options),
					Value = specEnum.Value,
                    Type = specEnum.Value.Length <= 6 ? "uint" : "ulong"
				};

                if (enumData.Value.StartsWith("-"))
                    enumData.Value = string.Format("unchecked((uint){0})", enumData.Value);

				api.Enums.Add(enumData);
			}
		}
Ejemplo n.º 5
0
        private void ParseEnums(XDocument doc, XmlSpecData data, Options options)
		{
			foreach (var enumSetNode in doc.Root.Elements("enums"))
			{
				foreach (var enumNode in enumSetNode.Elements())
				{
					XmlEnumData enumData = new XmlEnumData()
					{
						Group = enumSetNode.GetAttributeValue("group"),
						Type = enumSetNode.GetAttributeValue("type"),
						Vendor = enumSetNode.GetAttributeValue("vendor"),
						Value = enumNode.GetAttributeValue("value"),
						Name = enumNode.GetAttributeValue("name")
					};

					if (enumData.Name != null && data.Enums.SingleOrDefault(x => x.Name == enumData.Name) == null)
						data.Enums.Add(enumData);
				}
			}
		}
Ejemplo n.º 6
0
        private void ParseEnumGroups(XDocument doc, XmlSpecData data, Options options)
        {
            var groupsNode = doc.Root.Element("groups");

            if (groupsNode == null)
                return;

            foreach (var enumGroupNode in groupsNode.Elements())
            {
                XmlEnumGroupData enumGroupData = new XmlEnumGroupData()
                {
                    Name = enumGroupNode.GetAttributeValue("name")
                };

                foreach (var enumNode in enumGroupNode.Elements())
                {
                    enumGroupData.Enums.Add(enumNode.GetAttributeValue("name"));
                }

                data.EnumGroups.Add(enumGroupData);
            }
        }
Ejemplo n.º 7
0
		public XmlSpecData Parse(string file, string overridesFile, Options options)
		{
			XmlSpecData data = new XmlSpecData();
            			
			XDocument doc = XDocument.Load(file);
            this.ParseEnumGroups(doc, data, options);
            this.ParseEnums(doc, data, options);
            this.ParseCommands(doc, data, options);
            this.ParseFeatures(doc, data, options);
            this.ParseExtensions(doc, data, options);

            if (overridesFile != null)
            {
                doc = XDocument.Load(overridesFile);
                this.ParseOverrides(doc, data);
            }

            data.EnumGroups.Sort((x, y) => x.Name != null && y.Name != null ? x.Name.CompareTo(y.Name) : 0);
            data.Enums.Sort((x, y) => x.Name != null && y.Name != null ? x.Name.CompareTo(y.Name) : 0);
            data.Commands.Sort((x, y) => x.Name != null && y.Name != null ? x.Name.CompareTo(y.Name) : 0);

			return data;
		}
Ejemplo n.º 8
0
        private void TranslateFunctions(XmlSpecData spec, DotNetApiData api, Options options)
        {
            foreach (var specCommand in spec.Commands.Where(x => options.CommandFilter(x)))
            {
                var specFeature = spec.Features.Where(x => x.Commands.Contains(specCommand.Name)).FirstOrDefault();

                var functionData = new DotNetFunctionData()
                {
                    IsNative = true,
                    OriginalName = specCommand.Name,
                    NativeName = this.InflectFunctionNativeName(specCommand.Name, options),
                    DotNetName = this.InflectFunctionDotNetName(specCommand.Name, options),
                    OriginalReturnType = specCommand.ReturnType,
                    NativeReturnType = this.InflectNativeReturnType(specCommand),
                    DotNetReturnType = this.InflectDotNetReturnType(specCommand)
                };

                if (specFeature != null)
                {
                    functionData.VersionMajor = specFeature.VersionMajor;
                    functionData.VersionMinor = specFeature.VersionMinor;
                    functionData.CanPInvoke = specFeature.VersionMajor == 1 && specFeature.VersionMinor <= 1;
                }

                if (functionData.NativeReturnType == "string")
                    functionData.IsUnsafe = true;

                foreach (var specCommandParam in specCommand.Params)
                {
                    var functionParamData = new DotNetFunctionParamData()
                    {
                        OriginalName = specCommandParam.Name,
                        Name = this.InflectFunctionParamName(specCommandParam.Name),
                        OriginalType = specCommandParam.Type,
                        NativeType = this.InflectFunctionParamNativeType(specCommandParam),
                        DotNetType = this.InflectFunctionParamDotNetType(specCommandParam),
                        IsPointer = this.IsTypePointer(specCommandParam.Type),
                        IsOutput = this.IsTypeOutput(specCommandParam.Type),
                        ShouldUseGenerics = this.ShouldUseGenericsForType(specCommandParam.Type),
                        ShouldUseFixed = this.ShouldUseFixedForParam(specCommandParam),
                        ShouldUseAddressOfOperator = this.ShouldUseAddressOfOperatorForParam(specCommandParam)
                    };

                    if (functionParamData.IsPointer)
                        functionData.IsUnsafe = true;

                    if (functionParamData.ShouldUseGenerics)
                        functionData.ShouldUseGenerics = true;

                    if (functionParamData.IsOutput && functionParamData.DotNetType == "IntPtr")
                    {
                        functionParamData.ShouldUseOut = true;
                    }

                    functionData.Params.Add(functionParamData);
                }

                api.Functions.Add(functionData);

                // Create overload which accepts the Enum variant.
                if (specCommand.Params.Any(x => this.IsTypeEnum(x, api)))
                {
                    api.Functions.Add(this.ChangeFunctionParamsToEnums(functionData, specCommand.Params.Where(x => this.IsTypeEnum(x, api))));
                }
            }

            foreach (var functionData in api.Functions.ToArray())
            {
                var specCommand = spec.Commands.Single(x => x.Name == functionData.OriginalName);

                // Commands which take a pointer and it could be a single element.
                if (specCommand.Params.Any(x => this.ShouldChangeFunctionParamToRefOrOut(x)))
                {
                    api.Functions.Add(this.ChangeFunctionParamsToRefOrOut(functionData, specCommand.Params.Where(x => this.ShouldChangeFunctionParamToRefOrOut(x)).Select(x => x.Name)));
                }

                // Commands which take a pointer and it could be a single element.
                if (specCommand.Params.Any(x => this.ShouldChangeFunctionParamToIntPtr(x)))
                {
                    api.Functions.Add(this.ChangeFunctionParamsToIntPtr(functionData, specCommand.Params.Where(x => this.ShouldChangeFunctionParamToIntPtr(x)).Select(x => x.Name)));
                }
            }

            api.Functions.Sort((x, y) => x.OriginalName != null && y.OriginalName != null ? x.OriginalName.CompareTo(y.OriginalName) : 0);
        }
Ejemplo n.º 9
0
        private void ParseCommands(XDocument doc, XmlSpecData data, Options options)
		{
			foreach (var commandSetNode in doc.Root.Elements("commands"))
			{
				foreach (var commandNode in commandSetNode.Elements())
				{
					XmlCommandData commandData = new XmlCommandData()
					{
                        Name = this.EnsureCommandNameHasPrefix(commandNode.GetElementValue("proto", "name"), options),
						ReturnType = commandNode.GetElementValue("proto", "ptype"),
						ReturnTypeGroup = commandNode.GetElementAttributeValue("proto", "group"),
						Alias = commandNode.GetElementAttributeValue("alias", "name")
					};
									
					if (commandData.ReturnType == null)
						commandData.ReturnType = commandNode.Element("proto").GetTexts().First().Trim();

					// "void *" => "void*"
					if (commandData.ReturnType.EndsWith(" *"))
						commandData.ReturnType = commandData.ReturnType.Substring(0, commandData.ReturnType.Length - 2) + "*";

					foreach (var commandParamNode in commandNode.Elements("param"))
					{
						XmlCommandParamData commandParamData = new XmlCommandParamData()
						{
							Name = commandParamNode.GetElementValue("name"),
							Type = commandParamNode.GetElementValue("ptype"),
							TypeGroup = commandParamNode.GetAttributeValue("group"),
							Length = commandParamNode.GetAttributeValue("len")
						};

						if (commandParamData.Type == null)
						{
							commandParamData.Type = commandParamNode.GetTexts().First().Trim();
						}
						else
						{
							var texts = commandParamNode.GetTexts();

							if (texts.Count() == 1 &&
								texts.First().Contains("*"))
							{
								commandParamData.Type = commandParamData.Type + new string('*', texts.First().Count(x => x == '*'));
							}
							else if (
								texts.Count() == 2 &&
								texts.First().Trim() == "const" &&
								texts.Last().Contains("*"))
							{
								commandParamData.Type = "const " + commandParamData.Type + new string('*', texts.Last().Count(x => x == '*'));
							}
						}

						// "const void *" => "const void*"
						if (commandParamData.Type.EndsWith(" *"))
							commandParamData.Type = commandParamData.Type.Substring(0, commandParamData.Type.Length - 2) + "*";

						commandData.Params.Add(commandParamData);
					}

					data.Commands.Add(commandData);
				}
			}
		}
Ejemplo n.º 10
0
        private void ParseOverrides(XDocument doc, XmlSpecData data)
        {
            foreach (var groupNode in doc.Root.Element("groups").Elements())
            {
                var enumGroup = data.EnumGroups.SingleOrDefault(x => x.Name == groupNode.GetAttributeValue("name"));

                if (enumGroup == null)
                {
                    enumGroup = new XmlEnumGroupData()
                    {
                        Name = groupNode.GetAttributeValue("name")
                    };

                    data.EnumGroups.Add(enumGroup);
                }

                if (groupNode.Element("enums") != null)
                {
                    foreach (string @enum in groupNode.Element("enums").Value.Split(',').Select(x => x.Trim()))
                    {
                        if (!enumGroup.Enums.Contains(@enum))
                        {
                            enumGroup.Enums.Add(@enum);
                        }
                    }
                }
            }

            foreach (var commandNode in doc.Root.Element("commands").Elements())
            {
                var command = data.Commands.Single(x => x.Name == commandNode.GetAttributeValue("name"));
                
                foreach (var commandParamNode in commandNode.Elements("param"))
                {
                    var param = command.Params.Single(x => x.Name == commandParamNode.GetAttributeValue("name"));

                    string typeGroup = commandParamNode.GetAttributeValue("group");

                    if (typeGroup != null)
                        param.TypeGroup = typeGroup;
                }
            }
        }
Ejemplo n.º 11
0
        private void ParseExtensions(XDocument doc, XmlSpecData data, Options options)
        {
            foreach (var extensionNode in doc.Root.Element("extensions").Elements("extension"))
            {                
                var extensionData = new XmlExtensionData()
                {
                    Name = extensionNode.GetAttributeValue("name"),                    
                };

                foreach (var enumNode in extensionNode.Descendants("require").Descendants("enum"))
                {
                    extensionData.Enums.Add(enumNode.GetAttributeValue("name"));
                }

                foreach (var commandNode in extensionNode.Descendants("require").Descendants("command"))
                {
                    extensionData.Commands.Add(commandNode.GetAttributeValue("name"));
                }

                data.Extensions.Add(extensionData);
            }
        }
Ejemplo n.º 12
0
        private void ParseFeatures(XDocument doc, XmlSpecData data, Options options)
		{
			foreach (var featureNode in doc.Root.Elements("feature"))
			{
				string[] versionParts = featureNode.GetAttributeValue("number").Split('.');
				int versionMajor = int.Parse(versionParts[0]);
				int versionMinor = int.Parse(versionParts[1]);

				var featureData = new XmlFeatureData()
				{
					Api = featureNode.GetAttributeValue("api"),
					Name = featureNode.GetAttributeValue("name"),
					VersionMajor = versionMajor,
					VersionMinor = versionMinor
				};

                foreach (var requireNode in featureNode.Elements("require"))
                {
                    foreach (var enumNode in requireNode.Elements("enum"))
                    {
                        featureData.AddedEnums.Add(enumNode.GetAttributeValue("name"));
                    }

                    foreach (var commandNode in requireNode.Elements("command"))
                    {
                        featureData.AddedCommands.Add(this.EnsureCommandNameHasPrefix(commandNode.GetAttributeValue("name"), options));
                    }
                }

                foreach (var removeNode in featureNode.Elements("remove"))
                {
                    foreach (var enumNode in removeNode.Elements("enum"))
                    {
                        featureData.RemovedEnums.Add(enumNode.GetAttributeValue("name"));
                    }

                    foreach (var commandNode in removeNode.Elements("command"))
                    {
                        featureData.RemovedCommands.Add(this.EnsureCommandNameHasPrefix(commandNode.GetAttributeValue("name"), options));
                    }
                }

                data.Features.Add(featureData);
			}
		}
Ejemplo n.º 13
0
        private static void WriteGLVersions(XmlSpecData glSpec, DotNetTranslator translator, DotNetFileWriter writer)
        {
            string basePath = Path.Combine("..", "..", "..", "GLDotNet.GL");

            var baseProjectFile = XDocument.Load(Path.Combine(basePath, "GLDotNet.GL.csproj"));
            var projectXmlNamespace = baseProjectFile.Root.GetDefaultNamespace();
            baseProjectFile.Root.Descendants(projectXmlNamespace + "Compile").First().Parent.Name = projectXmlNamespace + "CompileItemGroup";
            baseProjectFile.Root.Descendants(projectXmlNamespace + "Compile").Remove();

            var glVersions = glSpec.Features
                .Where(x => x.Api == "gl")
                .OrderBy(x => x.VersionMajor)
                .ThenBy(x => x.VersionMinor)
                .ToArray();

            // Start at 1 because GL version 1.0 seems to not work correctly...
            for (int i = 1; i < glVersions.Length; i++)
            {
                var path = basePath + glVersions[i].VersionMajor + glVersions[i].VersionMinor;
                var ns = "GLDotNet.GL" + glVersions[i].VersionMajor + glVersions[i].VersionMinor;
                var projectGuid = CalculateProjectGuid(ns);

                Console.WriteLine($"{ns} {projectGuid}");

                var glEnums = new List<string>();
                var glCommands = new List<string>();

                for (int j = 0; j <= i; j++)
                {
                    glEnums.AddRange(glVersions[j].AddedEnums);
                    glCommands.AddRange(glVersions[j].AddedCommands);

                    glEnums.RemoveAll(x => glVersions[j].RemovedEnums.Contains(x));
                    glCommands.RemoveAll(x => glVersions[j].RemovedCommands.Contains(x));
                }

                Directory.CreateDirectory(path);

                var glApi = translator.Translate(glSpec, new DotNetTranslator.Options()
                {
                    Prefix = "gl",
                    CommandFilter = x => glCommands.Contains(x.Name),
                    EnumGroupFilter = ShouldOutputEnumGroup,
                    EnumFilter = x => ShouldOutputEnum(x) && glEnums.Contains(x.Name),
                    DocsFolder = glVersions[i].VersionMajor >= 2 ? Path.Combine("docs", "man" + glVersions[i].VersionMajor.ToString()) : null
                });

                writer.WriteFiles(glApi, new DotNetFileWriter.Options()
                {
                    Prefix = "GL",
                    OutputPath = path,
                    Namespace = ns,
                    ConstantsFileName = "GLConstants.Generated.cs",
                    ConstantsClassName = "GLConstants",
                    EnumsFileName = "GLEnums.Generated.cs",
                    CommandsFileName = "GLCommands.Generated.cs",
                    CommandsClassName = "GLCommands",
                    ContextFileName = "GLContext.Methods.Generated.cs",
                    ContextClassName = "GLContext"
                });

                var projectFile = new XDocument(baseProjectFile);
                projectFile.Root.Descendants(projectXmlNamespace + "ProjectGuid").Single().Value = "{" + projectGuid.ToString().ToUpper() + "}";
                projectFile.Root.Descendants(projectXmlNamespace + "RootNamespace").Single().Value = ns;
                projectFile.Root.Descendants(projectXmlNamespace + "AssemblyName").Single().Value = ns;

                foreach (var documentationNode in projectFile.Root.Descendants(projectXmlNamespace + "DocumentationFile"))
                    documentationNode.Value = documentationNode.Value.Replace("GLDotNet.GL", ns);

                var compileItemGroup = projectFile.Root.Descendants(projectXmlNamespace + "CompileItemGroup").Single();

                foreach (var file in Directory.EnumerateFiles(path, "*.cs").Select(x => Path.GetFileName(x)))
                {
                    compileItemGroup.Add(new XElement(projectXmlNamespace + "Compile", new XAttribute("Include", file)));
                }

                compileItemGroup.Add(new XElement(projectXmlNamespace + "Compile", new XAttribute("Include", @"Properties\AssemblyInfo.cs")));

                compileItemGroup.Name = projectXmlNamespace + "ItemGroup";

                File.WriteAllText(Path.Combine(path, ns + ".csproj"), "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + Environment.NewLine + projectFile.ToString());

                Directory.CreateDirectory(Path.Combine(path, "Properties"));

                TemplateEngine.Run("AssemblyVersion", Path.Combine(path, "Properties", "AssemblyVersion.cs"), new Dictionary<string, string>()
                {
                    ["Namespace"] = ns,
                    ["ProjectGuid"] = projectGuid.ToString()
                });

                TemplateEngine.Run("GLContext", Path.Combine(path, "GLContext.Generated.cs"), new Dictionary<string, string>()
                {
                    ["Namespace"] = ns
                });
            }
        }