From 3896f18892f87f3c354cb47965c4064d3ff26f5d Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Fri, 7 Aug 2009 01:11:11 -0400 Subject: [PATCH] module: Split out the GTypeModule subclass. --- src/Makefile.am | 3 +- src/module.c | 113 +---------------------------------- src/package.c | 133 ++++++++++++++++++++++++++++++++++++++++++ src/uobject/package.h | 51 ++++++++++++++++ 4 files changed, 189 insertions(+), 111 deletions(-) create mode 100644 src/package.c create mode 100644 src/uobject/package.h diff --git a/src/Makefile.am b/src/Makefile.am index 1082de3..a6e3372 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,7 +6,8 @@ noinst_HEADERS = pack.h avl.h include uobject/Makefile.inc include engine/Makefile.inc -libuobject_la_SOURCES = uobject.c module.c avl.c loadable.c exportable.c +libuobject_la_SOURCES = uobject.c module.c avl.c package.c \ + loadable.c exportable.c libuobject_la_CPPFLAGS = $(GLIB_CFLAGS) $(LTDLINCL) libuobject_la_LIBADD = $(LIBLTDL) $(GLIB_LIBS) libuobject_la_LDFLAGS = -export-symbols-regex '^uobject_' diff --git a/src/module.c b/src/module.c index eec80e7..ffc06e2 100644 --- a/src/module.c +++ b/src/module.c @@ -25,31 +25,9 @@ #include #include +#include #include "avl.h" -#define UPKG_MODULE_TYPE (upkg_module_get_type()) -#define UPKG_MODULE(obj) \ - G_TYPE_CHECK_INSTANCE_CAST(obj, UPKG_MODULE_TYPE, UPkgModule) -#define UPKG_MODULE_CLASS(class) \ - G_TYPE_CHECK_CLASS_CAST(class, UPKG_MODULE_TYPE, UPkgModuleClass) -#define IS_UPKG_MODULE(obj) \ - G_TYPE_CHECK_INSTANCE_TYPE(obj, UPKG_MODULE_TYPE) -#define IS_UPKG_MODULE_CLASS(class) \ - G_TYPE_CHECK_CLASS_TYPE(class, UPKG_MODULE_TYPE, UPkgModuleClass) - -typedef struct UPkgModule UPkgModule; -typedef struct UPkgModuleClass UPkgModuleClass; - -struct UPkgModule { - GTypeModule parent; - - lt_dlhandle dl; -}; - -struct UPkgModuleClass { - GTypeModuleClass parent; -}; - static unsigned initialized; static struct avl_table *package_tree; @@ -64,82 +42,6 @@ static char *str_cpy_lower(char *dst, const char *src) return dst; } -G_DEFINE_TYPE(UPkgModule, upkg_module, G_TYPE_TYPE_MODULE); - -static void dl_print_errors(const char *prefix) -{ - const char *err; - while ((err = lt_dlerror())) { - if (prefix) fprintf(stderr, "%s: ", prefix); - puts(err); - } -} - -static gboolean module_load(GTypeModule *m) -{ - UPkgModule *mod = UPKG_MODULE(m); - int (*init_func)(GTypeModule *); - - mod->dl = lt_dlopenext(G_TYPE_MODULE(m)->name); - if (!mod->dl) { - dl_print_errors(G_TYPE_MODULE(m)->name); - return FALSE; - } - - init_func = lt_dlsym(mod->dl, "init"); - if (!init_func || init_func(m) != 0) { - dl_print_errors(__func__); - lt_dlclose(mod->dl); - return FALSE; - } - - return TRUE; -} - -static void module_unload(GTypeModule *m) -{ - UPkgModule *mod = UPKG_MODULE(m); - - if (lt_dlclose(mod->dl) != 0) { - dl_print_errors(__func__); - } -} - -static void upkg_module_init(UPkgModule *mod) -{ -} - -static void upkg_module_class_init(UPkgModuleClass *class) -{ - GTypeModuleClass *modclass = G_TYPE_MODULE_CLASS(class); - - modclass->load = module_load; - modclass->unload = module_unload; -} - -static UPkgModule *uobject_module_new(const char *name) -{ - char *name2; - - if (!name) { - return NULL; - } - - name2 = malloc(strlen(name)+1); - if (!name2) { - return NULL; - } - - UPkgModule *mod = g_object_new(UPKG_MODULE_TYPE, NULL); - if (!mod) { - free(name2); - return NULL; - } - - G_TYPE_MODULE(mod)->name = str_cpy_lower(name2, name); - return mod; -} - static int modcmp(const void *a, const void *b, void *_data) { const GTypeModule *ma = a; @@ -157,12 +59,6 @@ int uobject_module_init(void) return -1; } - if (lt_dlinit() != 0) { - avl_destroy(package_tree, NULL); - dl_print_errors(__func__); - return -1; - } - g_type_init(); } @@ -175,10 +71,7 @@ int uobject_module_exit(void) if (--initialized) return 0; - if (lt_dlexit() != 0) { - dl_print_errors(__func__); - return -1; - } + avl_destroy(package_tree, NULL); return 0; } @@ -192,7 +85,7 @@ GType uobject_module_get_class(const char *package, const char *class) if (!mod) { void **p; - mod = G_TYPE_MODULE(uobject_module_new(package)); + mod = u_pkg_new(package); if (!mod) { return 0; } diff --git a/src/package.c b/src/package.c new file mode 100644 index 0000000..7b3b723 --- /dev/null +++ b/src/package.c @@ -0,0 +1,133 @@ +/* + * 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 + +#define U_PKG_GET_PRIV(o) \ + G_TYPE_INSTANCE_GET_PRIVATE(o, U_PKG_TYPE, struct upkg_priv) + +struct upkg_priv { + lt_dlhandle native; +}; + +G_DEFINE_TYPE(UPkg, u_pkg, G_TYPE_TYPE_MODULE); + +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 void dl_print_errors(const char *prefix) +{ + const char *err; + while ((err = lt_dlerror())) { + if (prefix) fprintf(stderr, "%s: ", prefix); + fprintf(stderr, "%s\n", err); + } +} + +static gboolean u_pkg_load(GTypeModule *m) +{ + struct upkg_priv *priv = U_PKG_GET_PRIV(m); + int (*init_func)(GTypeModule *); + + priv->native = lt_dlopenext(m->name); + if (!priv->native) { + dl_print_errors(m->name); + return FALSE; + } + + init_func = lt_dlsym(priv->native, "init"); + if (!init_func || init_func(m) != 0) { + dl_print_errors(__func__); + lt_dlclose(priv->native); + return FALSE; + } + + return TRUE; +} + +static void u_pkg_unload(GTypeModule *m) +{ + struct upkg_priv *priv = U_PKG_GET_PRIV(m); + void (*exit_func)(GTypeModule *); + + if (priv->native) { + exit_func = lt_dlsym(priv->native, "exit"); + if (exit_func) { + exit_func(m); + } + + if (lt_dlclose(priv->native) != 0) { + dl_print_errors(__func__); + } + } +} + +static void u_pkg_init(UPkg *pkg) +{ + +} + +static void u_pkg_class_init(UPkgClass *class) +{ + g_type_class_add_private(class, sizeof (struct upkg_priv)); + + GTypeModuleClass *modclass = G_TYPE_MODULE_CLASS(class); + + if (lt_dlinit() != 0) { + dl_print_errors(__func__); + } + + modclass->load = u_pkg_load; + modclass->unload = u_pkg_unload; +} + +GTypeModule *u_pkg_new(const char *name) +{ + g_return_val_if_fail(name != NULL, NULL); + + char *pkgname = malloc(strlen(name)+1); + if (!pkgname) { + return NULL; + } + + GTypeModule *mod = g_object_new(U_PKG_TYPE, NULL); + if (!mod) { + free(pkgname); + return NULL; + } + + mod->name = str_cpy_lower(pkgname, name); + return mod; +} diff --git a/src/uobject/package.h b/src/uobject/package.h new file mode 100644 index 0000000..6241aee --- /dev/null +++ b/src/uobject/package.h @@ -0,0 +1,51 @@ +/* + * 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 + */ + +#ifndef UOBJECT_PACKAGE_H_ +#define UOBJECT_PACKAGE_H_ + +#include + +#define U_PKG_TYPE (u_pkg_get_type()) +#define U_PKG(obj) \ + G_TYPE_CHECK_INSTANCE_CAST(obj, U_PKG_TYPE, UPkg) +#define U_PKG_CLASS(class) \ + G_TYPE_CHECK_CLASS_CAST(class, U_PKG_TYPE, UPkgClass) +#define IS_U_PKG(obj) \ + G_TYPE_CHECK_INSTANCE_TYPE(obj, U_PKG_TYPE) +#define IS_U_PKG_CLASS(class) \ + G_TYPE_CHECK_CLASS_TYPE(class, U_PKG_TYPE, UPkgClass) +#define U_PKG_GET_CLASS(obj) \ + G_TYPE_INSTANCE_GET_CLASS(obj, U_PKG_TYPE, UPkgClass) + +typedef struct UPkg UPkg; +typedef struct UPkgClass UPkgClass; + +struct UPkg { + GTypeModule parent; +}; + +struct UPkgClass { + GTypeModuleClass parent; +}; + +GType u_pkg_get_type(void); +GTypeModule *u_pkg_new(const char *name); + +#endif -- 2.43.0