]> git.draconx.ca Git - upkg.git/commitdiff
package: Allow opening by filename in addition to package name.
authorNick Bowler <nbowler@draconx.ca>
Wed, 16 Sep 2009 14:05:38 +0000 (10:05 -0400)
committerNick Bowler <nbowler@draconx.ca>
Wed, 16 Sep 2009 14:05:38 +0000 (10:05 -0400)
Ultimately, libupkg will be merged into libuobject.  This is step one of
that merger, and doesn't affect very much.

src/module.c
src/package.c
src/uobject/package.h
src/upkg.c

index d7db26869f33e3ce42e6a76ddea273cbaea75042..1872a8debdd799b37bb0d62a8e3dd0c95923ba13 100644 (file)
@@ -84,7 +84,7 @@ GType u_object_module_get_class(const char *package, const char *class)
        if (!mod) {
                void **p;
 
-               mod = u_pkg_new(package);
+               mod = u_pkg_new_by_name(package);
                if (!mod) {
                        return 0;
                }
index cbbaf09dd71efbcd6e0fb247cb78001e49e508c9..bd9713500392cb504ac5d3d19f250f75e37051ef 100644 (file)
 #include <ltdl.h>
 
 #include <uobject/package.h>
+#include "upkg.h"
 
 #define U_PKG_GET_PRIV(o) \
        G_TYPE_INSTANCE_GET_PRIVATE(o, U_PKG_TYPE, struct upkg_priv)
 
 struct upkg_priv {
        lt_dlhandle native;
-       FILE *pkg_file;
 };
 
 G_DEFINE_TYPE(UPkg, u_pkg, G_TYPE_TYPE_MODULE);
@@ -85,13 +85,13 @@ static void dl_print_errors(const char *prefix)
 /*
  * Function for use with lt_dlforeachfile.  The user data must point to
  * a UPkg with the GTypeModule name field initialized.  If a suitable file
- * is found and could be successfully opened for reading, the pkg_file member
- * of struct upkg_priv will be filled in.
+ * is found and could be successfully opened for reading, the pkg class member
+ * will be filled in.
  */
-static int find_package_by_name(const char *filename, void *_pkg)
+static int find_package_by_name(const char *filename, void *data)
 {
-       struct upkg_priv *priv = U_PKG_GET_PRIV(_pkg);
-       GTypeModule *m = _pkg;
+       GTypeModule *m = G_TYPE_MODULE(data);
+       UPkg *upkg = U_PKG(data);
 
        const char *base;
        size_t len;
@@ -115,8 +115,8 @@ static int find_package_by_name(const char *filename, void *_pkg)
 
        for (unsigned i = 0; i < sizeof u_pkg_exts / sizeof *u_pkg_exts; i++) {
                strcpy(buf+len, u_pkg_exts[i]);
-               priv->pkg_file = fopen(buf, "rb");
-               if (priv->pkg_file) {
+               upkg->pkg = upkg_fopen(buf);
+               if (!upkg->pkg) {
                        free(buf);
                        return 1;
                }
@@ -131,20 +131,24 @@ 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;
-       }
+       if (m->name) {
+               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;
+               init_func = lt_dlsym(priv->native, "init");
+               if (!init_func || init_func(m) != 0) {
+                       dl_print_errors(__func__);
+                       lt_dlclose(priv->native);
+                       return FALSE;
+               }
        }
 
-       lt_dlforeachfile(u_pkg_get_search_path(), find_package_by_name, m);
+       if (!U_PKG(m)->pkg) {
+               lt_dlforeachfile(u_pkg_get_search_path(), find_package_by_name, m);
+       }
 
        return TRUE;
 }
@@ -153,6 +157,7 @@ static void u_pkg_unload(GTypeModule *m)
 {
        struct upkg_priv *priv = U_PKG_GET_PRIV(m);
        void (*exit_func)(GTypeModule *);
+       UPkg *upkg = U_PKG(m);
 
        if (priv->native) {
                exit_func = lt_dlsym(priv->native, "exit");
@@ -165,8 +170,9 @@ static void u_pkg_unload(GTypeModule *m)
                }
        }
 
-       if (priv->pkg_file) {
-               fclose(priv->pkg_file);
+       if (upkg->pkg) {
+               upkg_close(upkg->pkg);
+               upkg->pkg = NULL;
        }
 }
 
@@ -175,9 +181,20 @@ static void u_pkg_init(UPkg *pkg)
 
 }
 
+static void u_pkg_finalize(GObject *o)
+{
+       UPkg *upkg = U_PKG(o);
+
+       if (upkg->pkg) {
+               upkg_close(upkg->pkg);
+       }
+}
+
 static void u_pkg_class_init(UPkgClass *class)
 {
        GTypeModuleClass *modclass = G_TYPE_MODULE_CLASS(class);
+       GObjectClass *objclass = G_OBJECT_CLASS(class);
+
        const char *modpath = getenv("UOBJECT_MODULE_PATH");
 
        g_type_class_add_private(class, sizeof (struct upkg_priv));
@@ -193,8 +210,9 @@ static void u_pkg_class_init(UPkgClass *class)
                dl_print_errors(__func__);
        }
 
-       modclass->load   = u_pkg_load;
-       modclass->unload = u_pkg_unload;
+       modclass->load     = u_pkg_load;
+       modclass->unload   = u_pkg_unload;
+       objclass->finalize = u_pkg_finalize;
 }
 
 static int expand_search_path(size_t need)
@@ -246,7 +264,7 @@ int u_pkg_add_search_dir(const char *path)
        return 0;
 }
 
-GTypeModule *u_pkg_new(const char *name)
+GTypeModule *u_pkg_new_by_name(const char *name)
 {
        g_return_val_if_fail(name != NULL, NULL);
 
@@ -264,3 +282,21 @@ GTypeModule *u_pkg_new(const char *name)
        mod->name = str_cpy_lower(pkgname, name);
        return mod;
 }
+
+GTypeModule *u_pkg_new_by_file(const char *filename)
+{
+       struct upkg *pkg = upkg_fopen(filename);
+       if (!pkg) {
+               return NULL;
+       }
+
+       GTypeModule *mod = g_object_new(U_PKG_TYPE, NULL);
+       if (!mod) {
+               upkg_close(pkg);
+               return NULL;
+       }
+
+       mod->name = NULL;
+       U_PKG(mod)->pkg = pkg;
+       return mod;
+}
index 697abd24fcdcafbacdcd1a34fc3bcf81a858171d..5e60a18d3467fc0bdb68d46b9ce60f194ba6cd03 100644 (file)
@@ -38,6 +38,7 @@ typedef struct UPkgClass UPkgClass;
 
 struct UPkg {
        GTypeModule parent;
+       struct upkg *pkg;
 };
 
 struct UPkgClass {
@@ -45,7 +46,8 @@ struct UPkgClass {
 };
 
 GType u_pkg_get_type(void);
-GTypeModule *u_pkg_new(const char *name);
+GTypeModule *u_pkg_new_by_name(const char *name);
+GTypeModule *u_pkg_new_by_file(const char *filename);
 
 const char *u_pkg_get_search_path(void);
 int u_pkg_set_search_path(const char *path);
index 94ace921cb22dde2558e26f7a4c9daa33b51705d..b3e27a33e719f5227ba13f4f5d861222ba177a28 100644 (file)
@@ -28,6 +28,7 @@
 #include <uobject/exportable.h>
 #include <uobject/loadable.h>
 #include <uobject/module.h>
+#include <uobject/package.h>
 
 enum {
        MODE_INFO,
@@ -285,7 +286,7 @@ int package_export(struct upkg *pkg)
 
 int main(int argc, char **argv)
 {
-       struct upkg *pkg;
+       UPkg *upkg;
        unsigned mode = MODE_INFO;
        int opt, rc = EXIT_FAILURE;
 
@@ -322,22 +323,22 @@ int main(int argc, char **argv)
        if (u_object_module_init() != 0)
                return EXIT_FAILURE;
 
-       pkg = upkg_fopen(argv[optind]);
-       if (!pkg) {
+       upkg = U_PKG(u_pkg_new_by_file(argv[optind]));
+       if (!upkg) {
                fprintf(stderr, "failed to open package!\n");
                return EXIT_FAILURE;
        }
 
        switch (mode) {
        case MODE_INFO:
-               rc = package_info(pkg);
+               rc = package_info(upkg->pkg);
                break;
        case MODE_EXPORT:
-               rc = package_export(pkg);
+               rc = package_export(upkg->pkg);
                break;
        }
 
-       upkg_close(pkg);
+       g_object_unref(upkg);
        u_object_module_exit();
        return rc;
 }