David Li | 291f5fe | 2011-03-21 17:42:50 -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 | externs = [] |
| 24 | |
| 25 | def generate_caller(lines): |
| 26 | i = 0 |
| 27 | output = "" |
| 28 | skipFunctions = [] |
| 29 | |
| 30 | for line in lines: |
| 31 | if line.find("API_ENTRY(") >= 0: # a function prototype |
| 32 | returnType = line[0: line.find(" API_ENTRY(")] |
| 33 | functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name |
| 34 | parameterList = line[line.find(")(") + 2: line.find(") {")] |
| 35 | |
| 36 | #if line.find("*") >= 0: |
| 37 | # extern = "%s Debug_%s(%s);" % (returnType, functionName, parameterList) |
| 38 | # externs.append(extern) |
| 39 | # continue |
| 40 | |
| 41 | if functionName in skipFunctions: |
| 42 | sys.stderr.write("!\n! skipping function '%s'\n!\n" % functionName) |
| 43 | continue |
| 44 | output += "\ |
| 45 | case glesv2debugger::Message_Function_%s:\n" % functionName |
| 46 | parameters = parameterList.split(',') |
| 47 | paramIndex = 0 |
| 48 | if line.find("*") >= 0 and (line.find("*") < line.find(":") or line.find("*") > line.rfind(":")): # unannotated pointer |
| 49 | # add function to list of functions that should be hand written, but generate code anyways |
| 50 | externs.append(functionName) |
| 51 | output += "\ |
| 52 | ret = GenerateCall_%s(dbg, cmd, msg, prevRet);\n\ |
| 53 | break;\n" % (functionName) |
| 54 | continue |
| 55 | elif line.find(":out") >= 0 or line.find(":inout") >= 0: |
| 56 | externs.append(functionName) |
| 57 | output += "\ |
| 58 | ret = GenerateCall_%s(dbg, cmd, msg, prevRet);\n\ |
| 59 | break; // annotated output pointers\n" % (functionName) |
| 60 | continue |
| 61 | |
| 62 | if parameterList == "void": |
| 63 | parameters = [] |
| 64 | arguments = "" |
| 65 | paramNames = [] |
| 66 | inout = "" |
| 67 | getData = "" |
| 68 | |
| 69 | callerMembers = "" |
| 70 | |
| 71 | for parameter in parameters: |
| 72 | const = parameter.find("const") |
| 73 | parameter = parameter.replace("const", "") |
| 74 | parameter = parameter.strip() |
| 75 | paramType = parameter.split(' ')[0] |
| 76 | paramName = parameter.split(' ')[1] |
| 77 | annotation = "" |
| 78 | if parameter.find(":") >= 0: # has annotation |
| 79 | assert inout == "" # only one parameter should be annotated |
| 80 | sys.stderr.write("%s is annotated: %s \n" % (functionName, paramType)) |
| 81 | inout = paramType.split(":")[2] |
| 82 | annotation = paramType.split(":")[1] |
| 83 | paramType = paramType.split(":")[0] |
| 84 | count = 1 |
| 85 | countArg = "" |
| 86 | if annotation.find("*") >= 0: # [1,n] * param |
| 87 | count = int(annotation.split("*")[0]) |
| 88 | countArg = annotation.split("*")[1] |
| 89 | assert countArg in paramNames |
| 90 | elif annotation in paramNames: |
| 91 | count = 1 |
| 92 | countArg = annotation |
| 93 | elif annotation == "GLstring": |
| 94 | annotation = "strlen(%s)" % (paramName) |
| 95 | else: |
| 96 | count = int(annotation) |
| 97 | |
| 98 | paramType += "*" |
| 99 | arguments += "reinterpret_cast<%s>(const_cast<char *>(cmd.data().data()))" % (paramType) |
| 100 | elif paramType == "GLboolean": |
| 101 | arguments += "GLboolean(cmd.arg%d())" % (paramIndex) |
| 102 | else: |
| 103 | arguments += "static_cast<%s>(cmd.arg%d())" % (paramType, paramIndex) |
| 104 | |
| 105 | if paramIndex < len(parameters) - 1: |
| 106 | arguments += ", " |
| 107 | if len(arguments) - arguments.rfind("\n") > 60 : |
| 108 | arguments += "\n\ |
| 109 | " |
| 110 | if const >= 0: |
| 111 | paramType = "const " + paramType |
| 112 | paramNames.append(paramName) |
| 113 | paramIndex += 1 |
| 114 | |
| 115 | if returnType == "void": |
| 116 | output += "\ |
| 117 | dbg->hooks->gl.%s(\n\ |
| 118 | %s);\n\ |
| 119 | break;\n" % (functionName, arguments) |
| 120 | else: |
| 121 | output += "\ |
| 122 | msg.set_ret(static_cast<int>(dbg->hooks->gl.%s(\n\ |
| 123 | %s)));\n\ |
| 124 | if (cmd.has_ret())\n\ |
| 125 | ret = reinterpret_cast<int *>(msg.ret());\n\ |
| 126 | break;\n" % (functionName, arguments) |
| 127 | return output |
| 128 | |
| 129 | if __name__ == "__main__": |
| 130 | |
| 131 | lines = open("gl2_api_annotated.in").readlines() |
| 132 | output = generate_caller(lines) |
| 133 | |
| 134 | out = open("src/caller.cpp", "w") |
| 135 | out.write("""\ |
| 136 | /* |
| 137 | ** Copyright 2011, The Android Open Source Project |
| 138 | ** |
| 139 | ** Licensed under the Apache License, Version 2.0 (the "License"); |
| 140 | ** you may not use this file except in compliance with the License. |
| 141 | ** You may obtain a copy of the License at |
| 142 | ** |
| 143 | ** http://www.apache.org/licenses/LICENSE-2.0 |
| 144 | ** |
| 145 | ** Unless required by applicable law or agreed to in writing, software |
| 146 | ** distributed under the License is distributed on an "AS IS" BASIS, |
| 147 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 148 | ** See the License for the specific language governing permissions and |
| 149 | ** limitations under the License. |
| 150 | */ |
| 151 | |
| 152 | // auto generated by generate_caller_cpp.py |
| 153 | // implement declarations in caller.h |
| 154 | |
| 155 | #include "header.h" |
| 156 | |
| 157 | namespace android { |
| 158 | |
| 159 | """) |
| 160 | |
| 161 | for extern in externs: |
| 162 | out.write("\ |
| 163 | static const int * GenerateCall_%s(DbgContext * const dbg,\n\ |
| 164 | const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);\n" % (extern)) |
| 165 | print("\ |
| 166 | static const int * GenerateCall_%s(DbgContext * const dbg,\n\ |
| 167 | const glesv2debugger::Message & cmd,\n\ |
| 168 | glesv2debugger::Message & msg, const int * const prevRet)\n\ |
| 169 | { assert(0); return prevRet; }\n" % (extern)) |
| 170 | |
| 171 | out.write( |
| 172 | """ |
| 173 | #include "caller.h" |
| 174 | |
| 175 | const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd, |
| 176 | glesv2debugger::Message & msg, const int * const prevRet) |
| 177 | { |
| 178 | LOGD("GenerateCall function=%u", cmd.function()); |
| 179 | const int * ret = prevRet; // only some functions have return value |
David Li | 291f5fe | 2011-03-21 17:42:50 -0700 | [diff] [blame] | 180 | nsecs_t c0 = systemTime(timeMode); |
| 181 | switch (cmd.function()) {""") |
| 182 | |
| 183 | out.write(output) |
| 184 | |
| 185 | out.write("""\ |
| 186 | default: |
| 187 | assert(0); |
| 188 | } |
| 189 | msg.set_time((systemTime(timeMode) - c0) * 1e-6f); |
| 190 | msg.set_context_id(reinterpret_cast<int>(dbg)); |
| 191 | msg.set_function(cmd.function()); |
| 192 | msg.set_type(glesv2debugger::Message_Type_AfterCall); |
| 193 | return ret; |
| 194 | } |
| 195 | |
| 196 | }; // name space android { |
| 197 | """) |
| 198 | |
| 199 | |