public override IEnumerable<XElement> Parse(string[] lines) { XElement current = null; foreach (string l in lines) { // Clean up line for further processing and skip invalid lines. string line = l.Replace('\t', ' ').Trim(); if (!IsValid(line)) continue; string[] words = SplitWords(line); if (line.Contains("enum:")) { // This is a new enum definition if (current != null) yield return current; current = new XElement("enum", new XAttribute("name", words[0])); CurrentMode = ParserModes.Enum; CurrentEntryMode = EntryModes.Core; } else if (line.StartsWith(words[0] + "(")) { // This is a new function definition if (current != null) yield return current; var match = extensions.Match(words[0]); string extension = match != null && String.IsNullOrEmpty(match.Value) ? "Core" : match.Value; current = new XElement("function", new XAttribute("name", words[0]), new XAttribute("extension", extension)); CurrentMode = ParserModes.Func; } else if (current != null) { // This is an addition to the current element (enum or function) switch (CurrentMode) { case ParserModes.Enum: if (words[0] == "use") { current.Add(new XElement("use", new XAttribute("enum", words[1]), new XAttribute("token", words[2]))); //new XAttribute("profile", CurrentEntryMode == EntryModes.Compatibility ? // "compatibility" : "core"))); } else if (words[1] == "=") { current.Add(new XElement("token", new XAttribute("name", words[0]), new XAttribute("value", words[2]))); //new XAttribute("profile", CurrentEntryMode == EntryModes.Compatibility ? // "compatibility" : "core"))); } else if (words[0] == "profile:") { //CurrentEntryMode = words[1] == "compatibility" ? // EntryModes.Compatibility : EntryModes.Core; } else if (words[0].Contains("future_use")) { // This is a bug in the 4.3 specs. Unfortunately, // Khronos is no longer accepting bug reports for // the .spec files. continue; } else { // Typical cause is hand-editing the specs and forgetting to add an '=' sign. throw new InvalidOperationException(String.Format( "[Error] Invalid constant definition: \"{0}\"", line)); } break; case ParserModes.Func: switch (words[0]) { case "return": // Line denotes return value current.Add(new XElement("returns", new XAttribute("type", words[1]))); break; case "param": // Line denotes parameter int pointer = words[4].Contains("array") ? 1 : 0; pointer += words[4].Contains("reference") ? 1 : 0; var elem = new XElement("param", new XAttribute("name", words[1]), new XAttribute("type", words[2] + PointerLevel(pointer)), new XAttribute("flow", words[3] == "in" ? "in" : "out")); if (pointer > 0 && words.Length > 5 && words[5].Contains("[1]")) elem.Add(new XAttribute("count", 1)); current.Add(elem); break; case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5) // GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?) var version = current.Attribute("version"); if (version == null) current.Add(new XAttribute("version", words[1])); else version.Value = words[1]; break; case "category": current.Add(new XAttribute("category", words[1])); break; case "deprecated": current.Add(new XAttribute("deprecated", words[1])); break; } break; } } } if (current != null) { yield return current; } }
public override IEnumerable <XElement> Parse(string[] lines) { XElement current = null; foreach (string l in lines) { // Clean up line for further processing and skip invalid lines. string line = l.Replace('\t', ' ').Trim(); if (!IsValid(line)) { continue; } string[] words = SplitWords(line); if (line.Contains("enum:")) { // This is a new enum definition if (current != null) { yield return(current); } current = new XElement("enum", new XAttribute("name", words[0])); CurrentMode = ParserModes.Enum; CurrentEntryMode = EntryModes.Core; } else if (line.StartsWith(words[0] + "(")) { // This is a new function definition if (current != null) { yield return(current); } var match = extensions.Match(words[0]); string extension = match != null && String.IsNullOrEmpty(match.Value) ? "Core" : match.Value; current = new XElement("function", new XAttribute("name", words[0]), new XAttribute("extension", extension)); CurrentMode = ParserModes.Func; } else if (current != null) { // This is an addition to the current element (enum or function) switch (CurrentMode) { case ParserModes.Enum: if (words[0] == "use") { current.Add(new XElement("use", new XAttribute("enum", words[1]), new XAttribute("token", words[2]))); //new XAttribute("profile", CurrentEntryMode == EntryModes.Compatibility ? // "compatibility" : "core"))); } else if (words[1] == "=") { current.Add(new XElement("token", new XAttribute("name", words[0]), new XAttribute("value", words[2]))); //new XAttribute("profile", CurrentEntryMode == EntryModes.Compatibility ? // "compatibility" : "core"))); } else if (words[0] == "profile:") { //CurrentEntryMode = words[1] == "compatibility" ? // EntryModes.Compatibility : EntryModes.Core; } else if (words[0].Contains("future_use")) { // This is a bug in the 4.3 specs. Unfortunately, // Khronos is no longer accepting bug reports for // the .spec files. continue; } else { // Typical cause is hand-editing the specs and forgetting to add an '=' sign. throw new InvalidOperationException(String.Format( "[Error] Invalid constant definition: \"{0}\"", line)); } break; case ParserModes.Func: switch (words[0]) { case "return": // Line denotes return value current.Add(new XElement("returns", new XAttribute("type", words[1]))); break; case "param": // Line denotes parameter int pointer = words[4].Contains("array") ? 1 : 0; pointer += words[4].Contains("reference") ? 1 : 0; var elem = new XElement("param", new XAttribute("name", words[1]), new XAttribute("type", words[2] + PointerLevel(pointer)), new XAttribute("flow", words[3] == "in" ? "in" : "out")); if (pointer > 0 && words.Length > 5 && words[5].Contains("[1]")) { elem.Add(new XAttribute("count", 1)); } current.Add(elem); break; case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5) // GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?) var version = current.Attribute("version"); if (version == null) { current.Add(new XAttribute("version", words[1])); } else { version.Value = words[1]; } break; case "category": current.Add(new XAttribute("category", words[1])); break; case "deprecated": current.Add(new XAttribute("deprecated", words[1])); break; } break; } } } if (current != null) { yield return(current); } }