/* Copyright (c) 2006 Stephen Apostolopoulos * See license.txt for license info */ using System; using System.Collections.Generic; using System.Text; using System.IO; /* There are several errors in the spec files. * enum.spec: * A missing "#" to comment out a constant for a commented-out SGI extension (inoffensive, but erroneous nonetheless). * Uses LightProperty instead of the correct LightParameter. * References the commented out SGIX_icc_texture enum. * * enumext.spec * The renaming scheme for the 2.0 version (e.g. SRC_ALPHA2 instead of SOURCE_ALPHA2) references the GL_* versions * instead of the * which will break when a generator does not add the GL_ prefix. Moreover these reside in different enums * so the reference will only work for the C preprocessor. As a workaround I added the missing constants outside of any enum. */ namespace OpenTK.OpenGL.Bind { public partial class Process { void ReadSpecs(string specfile) { string path = Path.Combine(Properties.Bind.Default.InputPath, specfile); StreamReader sr; try { sr = new StreamReader(path); } catch (Exception) { Console.WriteLine("Error opening spec file: {0}", path); return; } Console.WriteLine("Reading specs from: {0}", specfile); do { string line = sr.ReadLine().Trim(); if (String.IsNullOrEmpty(line) || line.StartsWith("#") || // Disregard comments. line.StartsWith("passthru") || // Disregard passthru statements. line.StartsWith("required-props:") || line.StartsWith("param:") || line.StartsWith("dlflags:") || line.StartsWith("glxflags:") || line.StartsWith("vectorequiv:") || line.StartsWith("category:") || line.StartsWith("version:") || line.StartsWith("glxsingle:") || line.StartsWith("glxropcode:") || line.StartsWith("glxvendorpriv:") || line.StartsWith("glsflags:") || line.StartsWith("glsopcode:") || line.StartsWith("glsalias:") || line.StartsWith("wglflags:") || line.StartsWith("extension:") || line.StartsWith("alias:") || line.StartsWith("offset:")) continue; while (line.Contains("(") && !sr.EndOfStream) //complete_block.Functions.Add(ReadFunction(sr, line)); FunctionCollection.Add(ReadFunction(sr, ref line)); while (line.Contains("enum") && !sr.EndOfStream) { Enum e = ReadEnum(sr, ref line); if (EnumCollection.ContainsKey(e.Name)) { //Merge keys: foreach (Constant c in e.ConstantCollection.Values) { if (!((Enum)EnumCollection[e.Name]).ConstantCollection.ContainsKey(c.Name)) ((Enum)EnumCollection[e.Name]).ConstantCollection.Add(c.Name, c); } } else EnumCollection.Add(e.Name, e); } // EnumCollection.Add(ReadEnum(sr, ref line)); } while (!sr.EndOfStream); } #region Read enumeration function private Enum ReadEnum(StreamReader sr, ref string line) { Enum e = new Enum(); e.Name = line.Split(Translation.Separators, StringSplitOptions.RemoveEmptyEntries)[0]; do { line = sr.ReadLine(); if (String.IsNullOrEmpty(line) || line.StartsWith("#")) continue; if (line.Contains("enum:") || sr.EndOfStream) break; line = line.Replace('\t', ' '); string[] words = line.Split(Translation.Separators, StringSplitOptions.RemoveEmptyEntries); if (words.Length == 0) continue; Constant c = new Constant(); if (words[0] == "use") { c.Name = words[2]; c.Value = words[1] + "." + words[2]; } if (line.Contains("=")) { c.Name = words[0]; c.Value = words[2]; } if (!String.IsNullOrEmpty(c.Name) && !e.ConstantCollection.ContainsKey(c.Name)) e.ConstantCollection.Add(c.Name, c); } while (!sr.EndOfStream); return e; } #endregion #region Read function function Function ReadFunction(StreamReader sr, ref string line) { Function f = new Function(); //string line = sr.ReadLine(); f.Name = line.Split(Translation.Separators, StringSplitOptions.RemoveEmptyEntries)[0]; if (f.Name.EndsWith("ARB") || f.Name.EndsWith("EXT") || f.Name.EndsWith("ATI") || f.Name.EndsWith("NV") || f.Name.EndsWith("SUN") || f.Name.EndsWith("SUNX") || f.Name.EndsWith("SGI") || f.Name.EndsWith("SGIS") || f.Name.EndsWith("SGIX") || f.Name.EndsWith("MESA") || f.Name.EndsWith("3DFX") || f.Name.EndsWith("IBM") || f.Name.EndsWith("GREMEDY") || f.Name.EndsWith("HP") || f.Name.EndsWith("INTEL") || f.Name.EndsWith("PGI") || f.Name.EndsWith("INGR") || f.Name.EndsWith("APPLE")) f.Extension = true; do { line = sr.ReadLine(); line = line.Replace('\t', ' '); string[] words = line.Split(Translation.Separators, StringSplitOptions.RemoveEmptyEntries); if (String.IsNullOrEmpty(line) || words.Length == 0) break; switch (words[0]) { case "return": f.ReturnValue = words[1]; break; case "param": Parameter p = new Parameter(); p.Name = words[1]; p.Flow = words[3] == "in" ? Parameter.FlowDirection.In : Parameter.FlowDirection.Out; p.Type = words[2]; if (words[4] == "array") p.Array = true; f.Parameters.Add(p); break; case "version": f.Version = words[1]; break; } } while (!sr.EndOfStream); return f; } #endregion } }