| 238 | |
| 239 | |
| 240 | int main(int argc, char* argv[]) |
| 241 | { |
| 242 | if (argc < 5) |
| 243 | { |
| 244 | fprintf(stderr, "Usage: generator <header> <output> <output_template> <output_enum>\n"); |
| 245 | return 1; |
| 246 | } |
| 247 | |
| 248 | // Parse API header to get type and function information |
| 249 | map<QualifiedName, Ref<Type>> types, vars, funcs; |
| 250 | string errors; |
| 251 | auto arch = new CoreArchitecture(BNGetNativeTypeParserArchitecture()); |
| 252 | |
| 253 | // Enable ephemeral settings |
| 254 | Settings::Instance()->LoadSettingsFile(""); |
| 255 | Settings::Instance()->Set("analysis.types.parserName", "ClangTypeParser"); |
| 256 | bool ok = arch->GetStandalonePlatform()->ParseTypesFromSourceFile(argv[1], types, vars, funcs, errors); |
| 257 | |
| 258 | if (!ok) |
| 259 | { |
| 260 | fprintf(stderr, "Errors: %s\n", errors.c_str()); |
| 261 | return 1; |
| 262 | } |
| 263 | |
| 264 | FILE* out = fopen(argv[2], "w"); |
| 265 | FILE* out_template = fopen(argv[3], "r"); |
| 266 | FILE* enums = fopen(argv[4], "w"); |
| 267 | |
| 268 | fprintf(enums, "import enum\n"); |
| 269 | |
| 270 | // Copy the content of the template to the output file |
| 271 | int c; |
| 272 | while((c = fgetc(out_template)) != EOF) |
| 273 | fputc(c, out); |
| 274 | |
| 275 | // Create type objects |
| 276 | fprintf(out, "# Type definitions\n"); |
| 277 | for (auto& i : types) |
| 278 | { |
| 279 | string name; |
| 280 | if (i.first.size() != 1) |
| 281 | continue; |
| 282 | name = i.first[0]; |
| 283 | if (i.second->GetClass() == StructureTypeClass) |
| 284 | { |
| 285 | fprintf(out, "class %s(ctypes.Structure):\n", name.c_str()); |
| 286 | |
| 287 | // python uses str's, C uses byte-arrays |
| 288 | bool stringField = false; |
| 289 | for (auto& arg : i.second->GetStructure()->GetMembers()) |
| 290 | { |
| 291 | if ((arg.type->GetClass() == PointerTypeClass) && |
| 292 | (arg.type->GetChildType()->GetWidth() == 1) && |
| 293 | (arg.type->GetChildType()->IsSigned())) |
| 294 | { |
| 295 | fprintf(out, "\t@property\n\tdef %s(self):\n\t\treturn pyNativeStr(self._%s)\n", arg.name.c_str(), arg.name.c_str()); |
| 296 | fprintf(out, "\t@%s.setter\n\tdef %s(self, value):\n\t\tself._%s = cstr(value)\n", arg.name.c_str(), arg.name.c_str(), arg.name.c_str()); |
| 297 | stringField = true; |
nothing calls this directly
no test coverage detected