public void Read(TextReader reader) { VkType activeType = null; string prevBlockData = null; StringBuilder prevBlockBuilder = new StringBuilder(); VkMember activeMember = null; while (true) { var line = reader.ReadLine()?.Trim(); if (line == null) { break; } var includeIndex = line.IndexOf("include:", StringComparison.OrdinalIgnoreCase); if (includeIndex >= 0) { var endKey = line.LastIndexOf(".txt", StringComparison.OrdinalIgnoreCase); if (endKey < 0) { continue; } var startKey = line.LastIndexOf('/', endKey); if (startKey < 0) { continue; } var key = line.Substring(startKey + 1, endKey - startKey - 1); activeType = _spec.TypeDefs.GetValueOrDefault(key); if (!string.IsNullOrWhiteSpace(prevBlockData) && activeType != null && string.IsNullOrWhiteSpace(activeType.Comment)) { activeType.Comment = prevBlockData; } continue; } if (line.StartsWith("*") || line.Length == 0) { prevBlockData = prevBlockBuilder.ToString(); if (activeMember != null && activeMember.Comment == null) { activeMember.Comment = prevBlockData; } prevBlockBuilder.Clear(); activeMember = null; } var pnameIndex = line.IndexOf("pname:", StringComparison.OrdinalIgnoreCase); if (pnameIndex >= 0 && line.Substring(0, pnameIndex).Trim() == "*") { var memberNameIndex = line.IndexOfAny(new[] { ' ', '\t' }, pnameIndex); if (memberNameIndex == -1) { continue; } var memberName = line.Substring(pnameIndex + 6, memberNameIndex - pnameIndex - 6); prevBlockBuilder.Clear(); if (activeType is VkStructOrUnion ss) { activeMember = ss.Members.FirstOrDefault(x => x.Name.Equals(memberName)); } else if (activeType is VkTypeFunction fn) { activeMember = fn.Arguments.FirstOrDefault(x => x.Name.Equals(memberName)); } prevBlockBuilder.Append(line.Substring(memberNameIndex + 1).Trim()).Append(' '); } else { prevBlockBuilder.Append(line).Append(' '); } } }
private void ReadFunctionPointer(XElement type) { var stringbuilder = new StringBuilder(); List <string> argTypes = new List <string>(); string funcName = null; foreach (var child in type.Nodes()) { switch (child) { case XElement e: if (e.Name.LocalName.Equals("name")) { funcName = e.Value.Trim(); } else if (e.Name.LocalName.Equals("type")) { argTypes.Add(e.Value.Trim()); } stringbuilder.Append(StringifyElement(e)); break; case XText t: stringbuilder.Append(t.Value); break; } } Debug.Assert(funcName != null); var content = stringbuilder.ToString(); var argumentsReversed = new List <VkMember>(); #region Parse Arguments { var i = stringbuilder.Length - 1; var paramId = argTypes.Count - 1; while (i >= 0 && paramId >= 0) { var argEnd = content.LastIndexOfAny(new char[] { ')', ',' }, i); var argBegin = content.LastIndexOfAny(new char[] { '(', ',' }, argEnd - 1); if (argEnd == -1 || argBegin == -1) { break; } i = argBegin; var paramDesc = content.Substring(argBegin + 1, argEnd - argBegin - 1); var typeName = argTypes[paramId--]; var typeData = paramDesc.IndexOf(typeName, StringComparison.Ordinal); Debug.Assert(typeData != -1); var isConstant = paramDesc.LastIndexOf("const", typeData, StringComparison.OrdinalIgnoreCase) != -1; var isOptional = false; var ptrInfo = PointerLevel(paramDesc, 0, typeData) + PointerLevel(paramDesc, typeData + typeName.Length); var bufferSize = FixedBufferSize(paramDesc, typeData + typeName.Length); var nameBegin = -1; var nameEnd = -1; for (var j = paramDesc.Length - 1; j >= typeData + typeName.Length; j--) { var boundary = paramDesc[j] == ',' || paramDesc[j] == '*' || char.IsWhiteSpace(paramDesc[j]); if (nameEnd == -1 && !boundary) { nameEnd = j + 1; } else if (nameEnd != -1 && boundary) { nameBegin = j + 1; break; } } Debug.Assert(nameBegin != -1); Debug.Assert(nameEnd != -1); argumentsReversed.Add(new VkMember(paramDesc.Substring(nameBegin, nameEnd - nameBegin), null, typeName, ptrInfo, null, null, bufferSize, isConstant, isOptional)); } } #endregion VkMember returnType; #region Parse Return Type { var typedefIndex = content.IndexOf("typedef", StringComparison.OrdinalIgnoreCase); Debug.Assert(typedefIndex != -1); typedefIndex += "typedef".Length; var openParen = content.IndexOf('(', typedefIndex); Debug.Assert(openParen != -1); var returnInfo = content.Substring(typedefIndex, openParen - typedefIndex - 1).Trim(); var ptrInfo = PointerLevel(returnInfo); var typeNoPtr = returnInfo.Trim('*', ' ', '\t', '\r', '\n'); var fixedBufferSize = FixedBufferSize(typeNoPtr); if (fixedBufferSize != null) { var openBracket = typeNoPtr.IndexOf('['); Debug.Assert(openBracket != -1); typeNoPtr = typeNoPtr.Substring(0, openBracket); } returnType = new VkMember("return", null, typeNoPtr.Trim(), ptrInfo, null, null, fixedBufferSize, false, false); } #endregion _spec.Add(new VkTypeFunctionPointer(funcName, returnType, null, ((IEnumerable <VkMember>)argumentsReversed).Reverse().ToArray())); }