]> git.draconx.ca Git - upkg.git/commitdiff
libupkg: Store export parent pointers directly.
authorNick Bowler <nbowler@draconx.ca>
Mon, 14 May 2012 21:47:14 +0000 (17:47 -0400)
committerNick Bowler <nbowler@draconx.ca>
Mon, 14 May 2012 21:47:14 +0000 (17:47 -0400)
Making users handle the package member directly leads to some fairly
ridiculous and somewhat tricky code.  Resolve them all at package load
time and store pointers directly in the upkg_export structure, which
should help simplify the callers.

At this point, we codify the "exports cannot have packages which are
imports" assumption, which appears to be valid.  It's not obvious how
name lookup could possibly succeed if this were not the case.

src/libupkg.c
src/upkg.c
src/upkg.h

index 5a9dce7f29ad0d8ec6936827f01b5181d6d89c67..307e1beb03bd73fc774b9e0d1b1b05ab04fd516d 100644 (file)
@@ -276,6 +276,7 @@ static int pkg_init_exports(struct upkg_priv *pkg)
 
        while (index < pkg->pub.export_count) {
                struct upkg_export_priv *export = &pkg->exports[index];
+               unsigned long parent_index;
                long tmp;
 
                /* Read some data into buffer. */
@@ -296,9 +297,17 @@ static int pkg_init_exports(struct upkg_priv *pkg)
                len += rc;
 
                if (nbuf-len < 4) goto err;
-               export->pub.package = unpack_s32_le(buf+len);
+               parent_index = unpack_32_le(buf+len);
                len += 4;
 
+               export->pub.parent = NULL;
+               if (parent_index > 0) {
+                       parent_index--;
+                       if (parent_index >= pkg->pub.export_count)
+                               goto err;
+                       export->pub.parent = &pkg->exports[parent_index].pub;
+               }
+
                rc = upkg_decode_index(&tmp, buf+len, nbuf-len);
                if (rc == 0 || tmp < 0 || tmp >= pkg->pub.name_count) goto err;
                export->pub.name = pkg->names[tmp].name;
@@ -488,22 +497,22 @@ const char *upkg_get_name(struct upkg *pub, unsigned long idx)
        return pkg->names[idx].name;
 }
 
-long upkg_export_find(struct upkg *pub, long parent, const char *name)
+long upkg_export_find(struct upkg *pub, long parent_index, const char *name)
 {
        struct upkg_priv *pkg = (struct upkg_priv *)pub;
+       struct upkg_export *parent = NULL;
 
-       /* This only makes sense if the assertion below is not violated. */
-       long package = parent < 0 ? 0 : parent + 1;
+       if (parent_index >= 0) {
+               if (parent_index >= pkg->pub.export_count)
+                       return -1;
+               parent = &pkg->exports[parent_index].pub;
+       }
 
        for (unsigned long i = 0; i < pkg->pub.export_count; i++) {
                struct upkg_export_priv *e = &pkg->exports[i];
 
-               /* Assertion: an object's package is an export. */
-               format_assert(e->pub.package >= 0, continue);
-               if (e->pub.package == package
-                   && strcmp(e->pub.name, name) == 0) {
+               if (e->pub.parent == parent && !strcmp(e->pub.name, name))
                        return i;
-               }
        }
 
        return -1;
index 8fe9a2afd2789c98c5e32d1d84903e87d5fd0a64..e174c215b459112358c35188342552f21f76016f 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <assert.h>
 #include <getopt.h>
 
 #include <glib-object.h>
@@ -228,7 +229,7 @@ int package_info(struct upkg *pkg)
 static void export_print_name(struct upkg *upkg, const struct upkg_export *e)
 {
        if (e) {
-               export_print_name(upkg, upkg_get_export(upkg, e->package-1));
+               export_print_name(upkg, e->parent);
                printf(".%s", e->name);
        }
 }
@@ -240,15 +241,20 @@ export_print_fullname(GTypeModule *pkg, const struct upkg_export *export)
        export_print_name(U_PKG(pkg)->pkg, export);
 }
 
-static int package_list(GTypeModule *pkg, long parent)
+static int package_list(GTypeModule *pkg, long current)
 {
        struct upkg *upkg = U_PKG(pkg)->pkg;
-       const struct upkg_export *export;
+       const struct upkg_export *parent = NULL;
+
+       if (current >= 0) {
+               parent = upkg_get_export(upkg, current);
+               assert(parent != NULL);
+       }
 
        for (unsigned i = 0; i < upkg->export_count; i++) {
-               export = upkg_get_export(upkg, i);
+               const struct upkg_export *export = upkg_get_export(upkg, i);
 
-               if (export->package != parent)
+               if (export->parent != parent)
                        continue;
 
                export_print_fullname(pkg, export);
@@ -496,7 +502,7 @@ static int process_object(int mode, const char *objname)
                        ret = object_info(pkg, current);
                break;
        case MODE_LIST:
-               ret = package_list(pkg, current+1);
+               ret = package_list(pkg, current);
                break;
        case MODE_EXPORT:
                if (current < 0)
index 34291b7f7bf18717e6256dfe18441e65b2cca9be..12104cbcb8c4cfac729ff67aa068c6c0144b05d6 100644 (file)
@@ -78,10 +78,10 @@ struct upkg {
 };
 
 struct upkg_export {
-       const char *name;
+       const struct upkg_export *parent;
 
+       const char *name;
        unsigned long flags;
-       long package;
 };
 
 struct upkg_file {