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 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 68 | String[] getList() |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 69 | { |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 70 | String arg = args; |
David Li | 7ec7773 | 2011-04-11 11:11:32 -0700 | [diff] [blame] | 71 | args = args.substring(args.lastIndexOf('}') + 1); |
David Li | a130006 | 2011-04-22 18:18:30 -0700 | [diff] [blame] | 72 | final int comma = args.indexOf(','); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 73 | if (comma >= 0) |
| 74 | args = args.substring(comma + 1).trim(); |
| 75 | else |
| 76 | args = null; |
David Li | a130006 | 2011-04-22 18:18:30 -0700 | [diff] [blame] | 77 | |
| 78 | final int comment = arg.indexOf('='); |
| 79 | if (comment >= 0) |
| 80 | arg = arg.substring(comment + 1); |
| 81 | arg = arg.trim(); |
| 82 | assert arg.charAt(0) == '{'; |
David Li | 7ec7773 | 2011-04-11 11:11:32 -0700 | [diff] [blame] | 83 | arg = arg.substring(1, arg.lastIndexOf('}')).trim(); |
David Li | a130006 | 2011-04-22 18:18:30 -0700 | [diff] [blame] | 84 | return arg.split("\\s*,\\s*"); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 85 | } |
| 86 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 87 | ByteString parseFloats(int count) { |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 88 | ByteBuffer buffer = ByteBuffer.allocate(count * 4); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 89 | buffer.order(SampleView.targetByteOrder); |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 90 | String [] arg = getList(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 91 | for (int i = 0; i < count; i++) |
| 92 | buffer.putFloat(Float.parseFloat(arg[i].trim())); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 93 | buffer.rewind(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 94 | return ByteString.copyFrom(buffer); |
| 95 | } |
| 96 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 97 | ByteString parseInts(int count) { |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 98 | ByteBuffer buffer = ByteBuffer.allocate(count * 4); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 99 | buffer.order(SampleView.targetByteOrder); |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 100 | String [] arg = getList(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 101 | for (int i = 0; i < count; i++) |
| 102 | buffer.putInt(Integer.parseInt(arg[i].trim())); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 103 | buffer.rewind(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 104 | return ByteString.copyFrom(buffer); |
| 105 | } |
| 106 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 107 | ByteString parseUInts(int count) { |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 108 | ByteBuffer buffer = ByteBuffer.allocate(count * 4); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 109 | buffer.order(SampleView.targetByteOrder); |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 110 | String [] arg = getList(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 111 | for (int i = 0; i < count; i++) |
| 112 | buffer.putInt((int)(Long.parseLong(arg[i].trim()) & 0xffffffff)); |
David Li | 5d916df | 2011-04-13 16:16:38 -0700 | [diff] [blame] | 113 | buffer.rewind(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 114 | return ByteString.copyFrom(buffer); |
| 115 | } |
| 116 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 117 | ByteString parseMatrix(int columns, int count) { |
David Li | a130006 | 2011-04-22 18:18:30 -0700 | [diff] [blame] | 118 | return parseFloats(columns * columns * count); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 119 | } |
| 120 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 121 | ByteString parseString() { |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 122 | // TODO: escape sequence and proper string literal |
| 123 | String arg = args.substring(args.indexOf('"') + 1, args.lastIndexOf('"')); |
| 124 | args = args.substring(args.lastIndexOf('"')); |
| 125 | int comma = args.indexOf(','); |
| 126 | if (comma >= 0) |
| 127 | args = args.substring(comma + 1).trim(); |
| 128 | else |
| 129 | args = null; |
| 130 | return ByteString.copyFromUtf8(arg); |
| 131 | } |
| 132 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 133 | String getArgument() |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 134 | { |
David Li | a130006 | 2011-04-22 18:18:30 -0700 | [diff] [blame] | 135 | final int comma = args.indexOf(','); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 136 | String arg = null; |
| 137 | if (comma >= 0) |
| 138 | { |
David Li | a130006 | 2011-04-22 18:18:30 -0700 | [diff] [blame] | 139 | arg = args.substring(0, comma); |
| 140 | args = args.substring(comma + 1); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 141 | } |
| 142 | else |
| 143 | { |
| 144 | arg = args; |
| 145 | args = null; |
| 146 | } |
David Li | a130006 | 2011-04-22 18:18:30 -0700 | [diff] [blame] | 147 | final int comment = arg.indexOf('='); |
| 148 | if (comment >= 0) |
| 149 | arg = arg.substring(comment + 1); |
| 150 | return arg.trim(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 151 | } |
| 152 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 153 | int parseArgument() |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 154 | { |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 155 | String arg = getArgument(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 156 | if (arg.startsWith("GL_")) |
| 157 | return GLEnum.valueOf(arg).value; |
| 158 | else if (arg.toLowerCase().startsWith("0x")) |
| 159 | return Integer.parseInt(arg.substring(2), 16); |
| 160 | else |
| 161 | return Integer.parseInt(arg); |
| 162 | } |
| 163 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 164 | int parseFloat() |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 165 | { |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 166 | String arg = getArgument(); |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 167 | return Float.floatToRawIntBits(Float.parseFloat(arg)); |
| 168 | } |
| 169 | |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 170 | public void parse(final Message.Builder builder, String string) { |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 171 | int lparen = string.indexOf("("), rparen = string.lastIndexOf(")"); |
| 172 | String s = string.substring(0, lparen).trim(); |
| 173 | args = string.substring(lparen + 1, rparen); |
| 174 | String[] t = s.split(" "); |
| 175 | Function function = Function.valueOf(t[t.length - 1]); |
| 176 | builder.setFunction(function); |
| 177 | switch (function) { |
| 178 | """) |
| 179 | |
| 180 | abstractParsers = "" |
| 181 | |
| 182 | for line in lines: |
| 183 | if line.find("API_ENTRY(") >= 0: # a function prototype |
| 184 | returnType = line[0: line.find(" API_ENTRY(")].replace("const ", "") |
| 185 | functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name |
| 186 | parameterList = line[line.find(")(") + 2: line.find(") {")] |
| 187 | |
| 188 | parameters = parameterList.split(',') |
| 189 | paramIndex = 0 |
| 190 | |
| 191 | #if returnType != "void": |
| 192 | #else: |
| 193 | |
| 194 | if parameterList == "void": |
| 195 | parameters = [] |
| 196 | inout = "" |
| 197 | |
| 198 | paramNames = [] |
| 199 | abstract = False |
| 200 | argumentSetters = "" |
| 201 | output.write("\ |
| 202 | case %s:\n" % (functionName)) |
| 203 | |
| 204 | for parameter in parameters: |
| 205 | parameter = parameter.replace("const","") |
| 206 | parameter = parameter.strip() |
| 207 | paramType = parameter.split(' ')[0] |
| 208 | paramName = parameter.split(' ')[1] |
| 209 | annotation = "" |
| 210 | |
| 211 | argumentParser = "" |
| 212 | |
| 213 | if parameter.find(":") >= 0: |
| 214 | dataSetter = "" |
| 215 | assert inout == "" # only one parameter should be annotated |
| 216 | inout = paramType.split(":")[2] |
| 217 | annotation = paramType.split(":")[1] |
| 218 | paramType = paramType.split(":")[0] |
| 219 | count = 1 |
| 220 | countArg = "" |
| 221 | if annotation.find("*") >= 0: # [1,n] * param |
| 222 | count = int(annotation.split("*")[0]) |
| 223 | countArg = annotation.split("*")[1] |
| 224 | assert countArg in paramNames |
| 225 | elif annotation in paramNames: |
| 226 | count = 1 |
| 227 | countArg = annotation |
| 228 | elif annotation == "GLstring": |
| 229 | annotation = annotation |
| 230 | else: |
| 231 | count = int(annotation) |
| 232 | |
| 233 | if paramType == "GLfloat": |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 234 | argumentParser = "parseFloats" |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 235 | elif paramType == "GLint": |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 236 | argumentParser = "parseInts" |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 237 | elif paramType == "GLuint": |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 238 | argumentParser = "parseUInts" |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 239 | elif annotation == "GLstring": |
| 240 | assert paramType == 'GLchar' |
| 241 | elif paramType.find("void") >= 0: |
| 242 | assert 1 |
| 243 | else: |
| 244 | assert 0 |
| 245 | |
| 246 | if functionName.find('Matrix') >= 0: |
| 247 | columns = int(functionName[functionName.find("fv") - 1: functionName.find("fv")]) |
| 248 | assert columns * columns == count |
| 249 | assert countArg != "" |
| 250 | assert paramType == "GLfloat" |
David Li | a130006 | 2011-04-22 18:18:30 -0700 | [diff] [blame] | 251 | dataSetter = "builder.setData(parseMatrix(%d, builder.getArg%d()));" % ( |
| 252 | columns, paramNames.index(countArg)) |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 253 | elif annotation == "GLstring": |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 254 | dataSetter = "builder.setData(parseString());" |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 255 | elif paramType.find("void") >= 0: |
| 256 | dataSetter = "// TODO" |
| 257 | abstract = True |
| 258 | elif countArg == "": |
| 259 | dataSetter = "builder.setData(%s(%d));" % (argumentParser, count) |
| 260 | else: |
| 261 | dataSetter = "builder.setData(%s(%d * builder.getArg%d()));" % ( |
| 262 | argumentParser, count, paramNames.index(countArg)) |
| 263 | argumentSetters += "\ |
| 264 | %s // %s %s\n" % (dataSetter, paramType, paramName) |
| 265 | else: |
| 266 | if paramType == "GLfloat" or paramType == "GLclampf": |
| 267 | argumentSetters += "\ |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 268 | builder.setArg%d(parseFloat()); // %s %s\n" % ( |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 269 | paramIndex, paramType, paramName) |
| 270 | elif paramType.find("*") >= 0: |
| 271 | argumentSetters += "\ |
| 272 | // TODO: %s %s\n" % (paramType, paramName) |
| 273 | abstract = True |
| 274 | else: |
| 275 | argumentSetters += "\ |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 276 | builder.setArg%d(parseArgument()); // %s %s\n" % ( |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 277 | paramIndex, paramType, paramName) |
| 278 | paramNames.append(paramName) |
| 279 | paramIndex += 1 |
| 280 | |
| 281 | if not abstract: |
| 282 | output.write("%s" % argumentSetters) |
| 283 | else: |
| 284 | output.write("\ |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 285 | parse_%s(builder);\n" % functionName) |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 286 | abstractParsers += "\ |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 287 | abstract void parse_%s(Message.Builder builder);\n" % functionName |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 288 | print """\ |
| 289 | @Override |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 290 | void parse_%s(Message.Builder builder) { |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 291 | %s } |
David Li | c26ad8b | 2011-04-15 09:56:38 -0700 | [diff] [blame] | 292 | """ % (functionName, argumentSetters) # print skeleton code for MessageParserEx |
David Li | 067eefe | 2011-03-22 10:06:00 -0700 | [diff] [blame] | 293 | |
| 294 | output.write("\ |
| 295 | break;\n") |
| 296 | output.write("""\ |
| 297 | default: |
| 298 | assert false; |
| 299 | } |
| 300 | } |
| 301 | """) |
| 302 | output.write(abstractParsers) |
| 303 | output.write("\ |
| 304 | }""") |