1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Shader variable type utilities.
22 *//*--------------------------------------------------------------------*/
24 #include "gluVarTypeUtil.hpp"
33 VarTokenizer::VarTokenizer (const char* str)
35 , m_token (TOKEN_LAST)
42 int VarTokenizer::getNumber (void) const
44 return atoi(getIdentifier().c_str());
47 static inline bool isNum (char c) { return de::inRange(c, '0', '9'); }
48 static inline bool isAlpha (char c) { return de::inRange(c, 'a', 'z') || de::inRange(c, 'A', 'Z'); }
49 static inline bool isIdentifierChar (char c) { return isAlpha(c) || isNum(c) || c == '_'; }
51 void VarTokenizer::advance (void)
53 DE_ASSERT(m_token != TOKEN_END);
55 m_tokenStart += m_tokenLen;
59 if (m_str[m_tokenStart] == '[')
60 m_token = TOKEN_LEFT_BRACKET;
61 else if (m_str[m_tokenStart] == ']')
62 m_token = TOKEN_RIGHT_BRACKET;
63 else if (m_str[m_tokenStart] == 0)
65 else if (m_str[m_tokenStart] == '.')
66 m_token = TOKEN_PERIOD;
67 else if (isNum(m_str[m_tokenStart]))
69 m_token = TOKEN_NUMBER;
70 while (isNum(m_str[m_tokenStart+m_tokenLen]))
73 else if (isIdentifierChar(m_str[m_tokenStart]))
75 m_token = TOKEN_IDENTIFIER;
76 while (isIdentifierChar(m_str[m_tokenStart+m_tokenLen]))
80 TCU_FAIL("Unexpected character");
85 SubTypeAccess::SubTypeAccess (const VarType& type)
90 std::string parseVariableName (const char* nameWithPath)
92 VarTokenizer tokenizer(nameWithPath);
93 TCU_CHECK(tokenizer.getToken() == VarTokenizer::TOKEN_IDENTIFIER);
94 return tokenizer.getIdentifier();
97 void parseTypePath (const char* nameWithPath, const VarType& type, TypeComponentVector& path)
99 VarTokenizer tokenizer(nameWithPath);
101 if (tokenizer.getToken() == VarTokenizer::TOKEN_IDENTIFIER)
105 while (tokenizer.getToken() != VarTokenizer::TOKEN_END)
107 VarType curType = getVarType(type, path);
109 if (tokenizer.getToken() == VarTokenizer::TOKEN_PERIOD)
112 TCU_CHECK(tokenizer.getToken() == VarTokenizer::TOKEN_IDENTIFIER);
113 TCU_CHECK_MSG(curType.isStructType(), "Invalid field selector");
116 std::string memberName = tokenizer.getIdentifier();
118 for (; ndx < curType.getStructPtr()->getNumMembers(); ndx++)
120 if (memberName == curType.getStructPtr()->getMember(ndx).getName())
123 TCU_CHECK_MSG(ndx < curType.getStructPtr()->getNumMembers(), "Member not found in type");
125 path.push_back(VarTypeComponent(VarTypeComponent::STRUCT_MEMBER, ndx));
128 else if (tokenizer.getToken() == VarTokenizer::TOKEN_LEFT_BRACKET)
131 TCU_CHECK(tokenizer.getToken() == VarTokenizer::TOKEN_NUMBER);
133 int ndx = tokenizer.getNumber();
135 if (curType.isArrayType())
137 TCU_CHECK(de::inBounds(ndx, 0, curType.getArraySize()));
138 path.push_back(VarTypeComponent(VarTypeComponent::ARRAY_ELEMENT, ndx));
140 else if (curType.isBasicType() && isDataTypeMatrix(curType.getBasicType()))
142 TCU_CHECK(de::inBounds(ndx, 0, getDataTypeMatrixNumColumns(curType.getBasicType())));
143 path.push_back(VarTypeComponent(VarTypeComponent::MATRIX_COLUMN, ndx));
145 else if (curType.isBasicType() && isDataTypeVector(curType.getBasicType()))
147 TCU_CHECK(de::inBounds(ndx, 0, getDataTypeScalarSize(curType.getBasicType())));
148 path.push_back(VarTypeComponent(VarTypeComponent::VECTOR_COMPONENT, ndx));
151 TCU_FAIL("Invalid subscript");
154 TCU_CHECK(tokenizer.getToken() == VarTokenizer::TOKEN_RIGHT_BRACKET);
158 TCU_FAIL("Unexpected token");
162 std::ostream& operator<< (std::ostream& str, const TypeAccessFormat& format)
164 const VarType* curType = &format.type;
166 for (TypeComponentVector::const_iterator iter = format.path.begin(); iter != format.path.end(); iter++)
170 case VarTypeComponent::ARRAY_ELEMENT:
171 curType = &curType->getElementType(); // Update current type.
174 case VarTypeComponent::MATRIX_COLUMN:
175 case VarTypeComponent::VECTOR_COMPONENT:
176 str << "[" << iter->index << "]";
179 case VarTypeComponent::STRUCT_MEMBER:
181 const StructMember& member = curType->getStructPtr()->getMember(iter->index);
182 str << "." << member.getName();
183 curType = &member.getType();