#include #include #include #include #include #include #include #include #include "vkgen.h" #include "vkstruct.h" #include "vkfixedarray.h" #include "vkenum.h" static AutoreleasePool *autorelease_pool; static void arp_start (void) { autorelease_pool = [[AutoreleasePool alloc] init]; } static void arp_end (void) { [autorelease_pool release]; autorelease_pool = nil; } void printf (string fmt, ...) = #0; void fprintf (QFile file, string format, ...) { Qputs (file, vsprintf (format, va_copy (@args))); } hashtab_t *available_types; hashtab_t *processed_types; Array *queue; Array *output_types; PLItem *parse; QFile output_file; QFile header_file; qfot_type_encodings_t *encodings; qfot_type_t * next_type (qfot_type_t *type) { int size = type.size; if (!size) size = 4; return (qfot_type_t *) ((int *) type + size); } int type_is_null (qfot_type_t *type) { return type.size == 0; } void print_type (qfot_type_t *type) { //printf ("type: %p %d %d %s", type, type.meta, type.size, type.encoding); switch (type.meta) { case ty_basic: //printf (" %d", type.type); switch (type.type) { case ev_ptr: case ev_field: //printf (" "); print_type (type.fldptr.aux_type); break; case ev_func: //printf (" %p %d\n", type.func.return_type, // type.func.num_params); default: //printf ("\n"); break; } break; case ty_struct: case ty_union: case ty_enum: //printf (" %s %d\n", type.strct.tag, type.strct.num_fields); break; case ty_array: //printf (" %p %d %d\n", type.array.type, type.array.base, // type.array.size); break; case ty_class: //printf (" %s\n", type.class); break; case ty_alias: //printf (" %d %s ", type.alias.type, type.alias.name); print_type (type.alias.aux_type); break; case ty_handle: //printf (" %s\n", type.handle.tag); break; } } void scan_types (void) { qfot_type_t *type; for (type = encodings.types; ((int *)type - (int *) encodings.types) < encodings.size; type = next_type (type)) { if (type.size) { string tag = str_mid(type.strct.tag, 4); Type *avail_type = [Type fromType: type]; if (avail_type) { if (!Hash_Find (available_types, [avail_type name])) { //printf ("scan: %s %s\n", tag, [avail_type name]); Hash_Add (available_types, avail_type); } } } } } static string get_string_key (void *str, void *unused) { return (string) str; } static string get_object_key (void *obj, void *unused) { return [(id)obj name]; } static void free_object (void *obj, void *unused) { [(id)obj release]; } void usage (string name) { printf ("%s [plist file] [output file] [header file]\n", name); } int main(int argc, string *argv) { int do_struct = 0; int do_enum = 0; string plist_filename; QFile plist_file; PLItem *plist; PLItem *search; PLItem *handles; arp_start (); if (argc != 4) { usage (argv[0]); return 1; } plist_filename = argv[1]; plist_file = Qopen (plist_filename, "rt"); if (!plist_file) { printf ("could not open property list file: %s\n", plist_filename); return 1; } plist = [[PLDictionary fromFile: plist_file] retain]; if (!plist) { printf ("error parsing: %s\n", plist_filename); return 1; } Qclose (plist_file); if ([plist class] != [PLDictionary class]) { printf ("%s not a dictionary\n", plist_filename); return 1; } search = [[plist getObjectForKey: "search"] retain]; handles = [[plist getObjectForKey: "handles"] retain]; parse = [[plist getObjectForKey: "parse"] retain]; encodings = PR_FindGlobal (".type_encodings"); if (!encodings) { printf ("Can't find encodings\n"); return 1; } queue = [[Array array] retain]; output_types = [[Array array] retain]; available_types = Hash_NewTable (127, get_object_key, free_object, nil); processed_types = Hash_NewTable (127, get_string_key, nil, nil); scan_types (); for (int i = [search numObjects]; i-- > 0; ) { PLString *str = (PLString *) [search getObjectAtIndex:i]; string search_name = [str string]; id obj = (id) Hash_Find (available_types, search_name); obj = [obj resolveType]; //printf("obj: %d %s\n", obj, class_get_class_name([obj class])); if (obj && ([obj class] == [Struct class] || [obj class] == [Enum class])) { [obj addToQueue]; } } while ([queue count]) { id obj = [queue objectAtIndex:0]; [queue removeObjectAtIndex:0]; if ([obj class] == [Struct class]) { string name = [obj name]; if (name == "char" // char type faked via a struct || [[parse getObjectForKey:name] string] == "skip") { continue; } [obj queueFieldTypes]; } [output_types addObject:obj]; } for (int i = 0; i < argc; i++) { //printf ("vkgen %d %s\n", i, argv[i]); } arp_end (); output_file = Qopen (argv[2], "wt"); header_file = Qopen (argv[3], "wt"); for (int i = [output_types count]; i-- > 0; ) { id obj = [output_types objectAtIndex:i]; if ([obj name] == "VkStructureType") { continue; } arp_start (); [obj writeForward]; [obj initParse:[parse getObjectForKey:[obj name]]]; arp_end (); } for (int i = [output_types count]; i-- > 0; ) { id obj = [output_types objectAtIndex:i]; if ([obj name] == "VkStructureType") { continue; } arp_start (); [obj writeTable]; arp_end (); } fprintf (output_file, "static void\n"); fprintf (output_file, "vkgen_init_symtabs (exprctx_t *context)\n"); fprintf (output_file, "{\n"); for (int i = [output_types count]; i-- > 0; ) { id obj = [output_types objectAtIndex:i]; if ([obj name] == "VkStructureType") { continue; } arp_start (); [obj writeSymtabInit]; [obj writeSymtabEntry]; arp_end (); } fprintf (output_file, "}\n"); Qclose (output_file); Qclose (header_file); Hash_DelTable (available_types); [plist release]; [search release]; [handles release]; [parse release]; [queue release]; [output_types release]; return 0; }