1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Random Shader Generator
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 Source Formatter.
22 *//*--------------------------------------------------------------------*/
24 #include "rsgPrettyPrinter.hpp"
25 #include "deStringUtil.hpp"
30 static const char* s_tokenStr[] =
32 DE_NULL, // IDENTIFIER,
34 "invariant", // INVARIANT,
35 "precision", // PRECISION,
38 "continue", // CONTINUE,
44 "discard", // DISCARD,
51 "]", // RIGHT_BRACKET,
79 "sampler2D", // SAMPLER2D,
80 "samplerCube", // SAMPLERCUBE,
81 DE_NULL, // FLOAT_LITERAL,
82 DE_NULL, // INT_LITERAL,
83 DE_NULL, // BOOL_LITERAL,
85 " *= ", // MUL_ASSIGN,
86 " /= ", // DIV_ASSIGN,
87 " += ", // ADD_ASSIGN,
88 " -= ", // SUB_ASSIGN,
95 " && ", // LOGICAL_AND,
96 " || ", // LOGICAL_OR,
98 " ^^ ", // LOGICAL_XOR,
99 "attribute", // ATTRIBUTE,
100 "uniform", // UNIFORM,
101 "varying", // VARYING,
104 "highp", // HIGH_PRECISION,
105 "mediump", // MEDIUM_PRECISION,
106 "lowp", // LOW_PRECISION,
111 "location", // LOCATION,
112 DE_NULL, // INDENT_INC,
113 DE_NULL, // INDENT_DEC,
117 PrettyPrinter::PrettyPrinter (std::ostringstream& str)
123 inline const char* PrettyPrinter::getSimpleTokenStr (Token::Type token)
125 DE_ASSERT(de::inBounds<int>(token, 0, (int)DE_LENGTH_OF_ARRAY(s_tokenStr)));
126 return s_tokenStr[token];
129 void PrettyPrinter::append (const TokenStream& tokens)
131 for (int ndx = 0; ndx < tokens.getSize(); ndx++)
132 processToken(tokens[ndx]);
135 inline bool isIdentifierChar (char c)
137 return de::inRange(c, 'a', 'z') || de::inRange(c, 'A', 'Z') || de::inRange(c, '0', '9') || c == '_';
140 void PrettyPrinter::processToken (const Token& token)
142 bool prevIsIdentifierChar = m_line.length() > 0 && isIdentifierChar(m_line[m_line.length()-1]);
144 switch (token.getType())
146 case Token::IDENTIFIER:
147 if (prevIsIdentifierChar)
149 m_line += token.getIdentifier();
152 case Token::FLOAT_LITERAL:
154 std::string f = de::toString(token.getFloat());
155 if (f.find('.') == std::string::npos)
156 f += ".0"; // Make sure value parses as float
161 case Token::INT_LITERAL:
162 m_line += de::toString(token.getInt());
165 case Token::BOOL_LITERAL:
166 m_line += (token.getBool() ? "true" : "false");
169 case Token::INDENT_INC:
173 case Token::INDENT_DEC:
179 for (int i = 0; i < m_indentDepth; i++)
182 // Flush line to source
183 m_str << m_line + "\n";
189 const char* tokenStr = getSimpleTokenStr(token.getType());
190 if (prevIsIdentifierChar && isIdentifierChar(tokenStr[0]))