Example #1
0
        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(' ');
                }
            }
        }
Example #2
0
        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()));
        }