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 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 200