/* * upkg: tool for manipulating Unreal Tournament packages. * Copyright (C) 2009 Nick Bowler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include "avl.h" static unsigned initialized; static struct avl_table *package_tree; static char *str_cpy_lower(char *dst, const char *src) { size_t i; for (i = 0; src[i]; i++) dst[i] = tolower(src[i]); dst[i] = 0; return dst; } static int modcmp(const void *a, const void *b, void *_data) { const GTypeModule *ma = a; const GTypeModule *mb = b; return strcmp(ma->name, mb->name); } int u_object_module_init(void) { if (!initialized) { package_tree = avl_create(modcmp, NULL, NULL); if (!package_tree) { fprintf(stderr, "%s: failed to create package tree.\n", __func__); return -1; } g_type_init(); } initialized++; return 0; } int u_object_module_exit(void) { if (--initialized) return 0; avl_destroy(package_tree, NULL); return 0; } GType u_object_module_get_class(const char *package, const char *class) { char buf[strlen(package) + strlen(class) + 1]; GTypeModule search = { .name = str_cpy_lower(buf, package) }; GTypeModule *mod = avl_find(package_tree, &search); if (!mod) { void **p; mod = u_pkg_new(package); if (!mod) { return 0; } p = avl_probe(package_tree, mod); if (!p) { g_object_unref(mod); return 0; } } if (!g_type_module_use(mod)) return 0; str_cpy_lower(buf+strlen(package), class); buf[0] = toupper(buf[0]); buf[strlen(package)] = toupper(buf[strlen(package)]); return g_type_from_name(buf); }