David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | # -*- coding: utf-8 -*- |
| 3 | |
| 4 | # |
| 5 | # Copyright 2011, The Android Open Source Project |
| 6 | # |
| 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 |
| 10 | # |
| 11 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | # |
| 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. |
| 18 | # |
| 19 | |
| 20 | import os |
| 21 | import sys |
| 22 | |
| 23 | def RemoveAnnotation(line): |
| 24 | if line.find(":") >= 0: |
| 25 | annotation = line[line.find(":"): line.find(" ", line.find(":"))] |
| 26 | return line.replace(annotation, "*") |
| 27 | else: |
| 28 | return line |
| 29 | |
| 30 | if __name__ == "__main__": |
| 31 | externs = [] |
| 32 | lines = open("../../../frameworks/base/opengl/libs/GLES2_dbg/gl2_api_annotated.in").readlines() |
| 33 | output = open("src/com/android/glesv2debugger/MessageParser.java", "w") |
| 34 | |
| 35 | i = 0 |
| 36 | output.write("""\ |
| 37 | /* |
| 38 | ** Copyright 2011, The Android Open Source Project |
| 39 | ** |
| 40 | ** Licensed under the Apache License, Version 2.0 (the "License"); |
| 41 | ** you may not use this file except in compliance with the License. |
| 42 | ** You may obtain a copy of the License at |
| 43 | ** |
| 44 | ** http://www.apache.org/licenses/LICENSE-2.0 |
| 45 | ** |
| 46 | ** Unless required by applicable law or agreed to in writing, software |
| 47 | ** distributed under the License is distributed on an "AS IS" BASIS, |
| 48 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 49 | ** See the License for the specific language governing permissions and |
| 50 | ** limitations under the License. |
| 51 | */ |
| 52 | |
| 53 | // auto generated by generate_MessageParser_java.py, |
| 54 | // which also prints skeleton code for MessageParserEx.java |
| 55 | |
| 56 | package com.android.glesv2debugger; |
| 57 | |
| 58 | import com.android.glesv2debugger.DebuggerMessage.Message; |
| 59 | import com.android.glesv2debugger.DebuggerMessage.Message.Function; |
| 60 | import com.google.protobuf.ByteString; |
| 61 | |
| 62 | import java.nio.ByteBuffer; |
| 63 | |
| 64 | public abstract class MessageParser { |
| 65 | |
| 66 | String args; |
| 67 | |
| 68 | String[] GetList() |
| 69 | { |
David Li | 7ec7773 | 2011-04-11 11:11:32 -0700 | [diff] [blame] | 70 | assert args.charAt(0) == '{'; |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 71 | String arg = args; |
David Li | 7ec7773 | 2011-04-11 11:11:32 -0700 | [diff] [blame] | 72 | args = args.substring(args.lastIndexOf('}') + 1); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 73 | int comma = args.indexOf(','); |
| 74 | if (comma >= 0) |
| 75 | args = args.substring(comma + 1).trim(); |
| 76 | else |
| 77 | args = null; |
David Li | 7ec7773 | 2011-04-11 11:11:32 -0700 | [diff] [blame] | 78 | arg = arg.substring(1, arg.lastIndexOf('}')).trim(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 79 | return arg.split(","); |
| 80 | } |
| 81 | |
| 82 | ByteString ParseFloats(int count) { |
| 83 | ByteBuffer buffer = ByteBuffer.allocate(count * 4); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 84 | buffer.order(SampleView.targetByteOrder); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 85 | String [] arg = GetList(); |
| 86 | for (int i = 0; i < count; i++) |
| 87 | buffer.putFloat(Float.parseFloat(arg[i].trim())); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 88 | buffer.rewind(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 89 | return ByteString.copyFrom(buffer); |
| 90 | } |
| 91 | |
| 92 | ByteString ParseInts(int count) { |
| 93 | ByteBuffer buffer = ByteBuffer.allocate(count * 4); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 94 | buffer.order(SampleView.targetByteOrder); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 95 | String [] arg = GetList(); |
| 96 | for (int i = 0; i < count; i++) |
| 97 | buffer.putInt(Integer.parseInt(arg[i].trim())); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 98 | buffer.rewind(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 99 | return ByteString.copyFrom(buffer); |
| 100 | } |
| 101 | |
| 102 | ByteString ParseUInts(int count) { |
| 103 | ByteBuffer buffer = ByteBuffer.allocate(count * 4); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 104 | buffer.order(SampleView.targetByteOrder); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 105 | String [] arg = GetList(); |
| 106 | for (int i = 0; i < count; i++) |
| 107 | buffer.putInt((int)(Long.parseLong(arg[i].trim()) & 0xffffffff)); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 108 | buffer.rewind(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 109 | return ByteString.copyFrom(buffer); |
| 110 | } |
| 111 | |
| 112 | ByteString ParseMatrix(int columns, int count) { |
| 113 | return ParseFloats(columns * count); |
| 114 | } |
| 115 | |
| 116 | ByteString ParseString() { |
| 117 | // TODO: escape sequence and proper string literal |
| 118 | String arg = args.substring(args.indexOf('"') + 1, args.lastIndexOf('"')); |
| 119 | args = args.substring(args.lastIndexOf('"')); |
| 120 | int comma = args.indexOf(','); |
| 121 | if (comma >= 0) |
| 122 | args = args.substring(comma + 1).trim(); |
| 123 | else |
| 124 | args = null; |
| 125 | return ByteString.copyFromUtf8(arg); |
| 126 | } |
| 127 | |
| 128 | String GetArgument() |
| 129 | { |
| 130 | int comma = args.indexOf(","); |
| 131 | String arg = null; |
| 132 | if (comma >= 0) |
| 133 | { |
| 134 | arg = args.substring(0, comma).trim(); |
| 135 | args = args.substring(comma + 1).trim(); |
| 136 | } |
| 137 | else |
| 138 | { |
| 139 | arg = args; |
| 140 | args = null; |
| 141 | } |
| 142 | if (arg.indexOf("=") >= 0) |
| 143 | arg = arg.substring(arg.indexOf("=") + 1); |
| 144 | return arg; |
| 145 | } |
| 146 | |
| 147 | int ParseArgument() |
| 148 | { |
| 149 | String arg = GetArgument(); |
| 150 | if (arg.startsWith("GL_")) |
| 151 | return GLEnum.valueOf(arg).value; |
| 152 | else if (arg.toLowerCase().startsWith("0x")) |
| 153 | return Integer.parseInt(arg.substring(2), 16); |
| 154 | else |
| 155 | return Integer.parseInt(arg); |
| 156 | } |
| 157 | |
| 158 | int ParseFloat() |
| 159 | { |
| 160 | String arg = GetArgument(); |
| 161 | return Float.floatToRawIntBits(Float.parseFloat(arg)); |
| 162 | } |
| 163 | |
| 164 | public void Parse(final Message.Builder builder, String string) { |
| 165 | int lparen = string.indexOf("("), rparen = string.lastIndexOf(")"); |
| 166 | String s = string.substring(0, lparen).trim(); |
| 167 | args = string.substring(lparen + 1, rparen); |
| 168 | String[] t = s.split(" "); |
| 169 | Function function = Function.valueOf(t[t.length - 1]); |
| 170 | builder.setFunction(function); |
| 171 | switch (function) { |
| 172 | """) |
| 173 | |
| 174 | abstractParsers = "" |
| 175 | |
| 176 | for line in lines: |
| 177 | if line.find("API_ENTRY(") >= 0: # a function prototype |
| 178 | returnType = line[0: line.find(" API_ENTRY(")].replace("const ", "") |
| 179 | functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name |
| 180 | parameterList = line[line.find(")(") + 2: line.find(") {")] |
| 181 | |
| 182 | parameters = parameterList.split(',') |
| 183 | paramIndex = 0 |
| 184 | |
| 185 | #if returnType != "void": |
| 186 | #else: |
| 187 | |
| 188 | if parameterList == "void": |
| 189 | parameters = [] |
| 190 | inout = "" |
| 191 | |
| 192 | paramNames = [] |
| 193 | abstract = False |
| 194 | argumentSetters = "" |
| 195 | output.write("\ |
| 196 | case %s:\n" % (functionName)) |
| 197 | |
| 198 | for parameter in parameters: |
| 199 | parameter = parameter.replace("const","") |
| 200 | parameter = parameter.strip() |
| 201 | paramType = parameter.split(' ')[0] |
| 202 | paramName = parameter.split(' ')[1] |
| 203 | annotation = "" |
| 204 | |
| 205 | argumentParser = "" |
| 206 | |
| 207 | if parameter.find(":") >= 0: |
| 208 | dataSetter = "" |
| 209 | assert inout == "" # only one parameter should be annotated |
| 210 | inout = paramType.split(":")[2] |
| 211 | annotation = paramType.split(":")[1] |
| 212 | paramType = paramType.split(":")[0] |
| 213 | count = 1 |
| 214 | countArg = "" |
| 215 | if annotation.find("*") >= 0: # [1,n] * param |
| 216 | count = int(annotation.split("*")[0]) |
| 217 | countArg = annotation.split("*")[1] |
| 218 | assert countArg in paramNames |
| 219 | elif annotation in paramNames: |
| 220 | count = 1 |
| 221 | countArg = annotation |
| 222 | elif annotation == "GLstring": |
| 223 | annotation = annotation |
| 224 | else: |
| 225 | count = int(annotation) |
| 226 | |
| 227 | if paramType == "GLfloat": |
| 228 | argumentParser = "ParseFloats" |
| 229 | elif paramType == "GLint": |
| 230 | argumentParser = "ParseInts" |
| 231 | elif paramType == "GLuint": |
| 232 | argumentParser = "ParseUInts" |
| 233 | elif annotation == "GLstring": |
| 234 | assert paramType == 'GLchar' |
| 235 | elif paramType.find("void") >= 0: |
| 236 | assert 1 |
| 237 | else: |
| 238 | assert 0 |
| 239 | |
| 240 | if functionName.find('Matrix') >= 0: |
| 241 | columns = int(functionName[functionName.find("fv") - 1: functionName.find("fv")]) |
| 242 | assert columns * columns == count |
| 243 | assert countArg != "" |
| 244 | assert paramType == "GLfloat" |
| 245 | dataSetter = "builder.setData(ParseMatrix(%d, %d * builder.getArg%d()));" % ( |
| 246 | columns, count, paramNames.index(countArg)) |
| 247 | elif annotation == "GLstring": |
| 248 | dataSetter = "builder.setData(ParseString());" |
| 249 | elif paramType.find("void") >= 0: |
| 250 | dataSetter = "// TODO" |
| 251 | abstract = True |
| 252 | elif countArg == "": |
| 253 | dataSetter = "builder.setData(%s(%d));" % (argumentParser, count) |
| 254 | else: |
| 255 | dataSetter = "builder.setData(%s(%d * builder.getArg%d()));" % ( |
| 256 | argumentParser, count, paramNames.index(countArg)) |
| 257 | argumentSetters += "\ |
| 258 | %s // %s %s\n" % (dataSetter, paramType, paramName) |
| 259 | else: |
| 260 | if paramType == "GLfloat" or paramType == "GLclampf": |
| 261 | argumentSetters += "\ |
| 262 | builder.setArg%d(ParseFloat()); // %s %s\n" % ( |
| 263 | paramIndex, paramType, paramName) |
| 264 | elif paramType.find("*") >= 0: |
| 265 | argumentSetters += "\ |
| 266 | // TODO: %s %s\n" % (paramType, paramName) |
| 267 | abstract = True |
| 268 | else: |
| 269 | argumentSetters += "\ |
| 270 | builder.setArg%d(ParseArgument()); // %s %s\n" % ( |
| 271 | paramIndex, paramType, paramName) |
| 272 | paramNames.append(paramName) |
| 273 | paramIndex += 1 |
| 274 | |
| 275 | if not abstract: |
| 276 | output.write("%s" % argumentSetters) |
| 277 | else: |
| 278 | output.write("\ |
| 279 | Parse_%s(builder);\n" % functionName) |
| 280 | abstractParsers += "\ |
| 281 | abstract void Parse_%s(Message.Builder builder);\n" % functionName |
| 282 | print """\ |
| 283 | @Override |
| 284 | void Parse_%s(Message.Builder builder) { |
| 285 | %s } |
| 286 | """ % (functionName, argumentSetters) # print skeleton code for MessageParserE |
| 287 | |
| 288 | output.write("\ |
| 289 | break;\n") |
| 290 | output.write("""\ |
| 291 | default: |
| 292 | assert false; |
| 293 | } |
| 294 | } |
| 295 | """) |
| 296 | output.write(abstractParsers) |
| 297 | output.write("\ |
| 298 | }""") |