From c85943d37456ef89f914bb1043f734deb8904dad Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sat, 11 Jul 2009 00:43:47 -0400 Subject: [PATCH] upkg: Print package export info. --- src/libupkg.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/upkg.c | 23 +++++++++++- src/upkg.h | 5 +++ 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/src/libupkg.c b/src/libupkg.c index 8e5de38..d5203b4 100644 --- a/src/libupkg.c +++ b/src/libupkg.c @@ -422,6 +422,105 @@ const char *upkg_get_name(struct upkg *pkg, unsigned long idx) return pkg->priv->names[idx].name; } +long upkg_export_find(struct upkg *pkg, const char *name) +{ + /* This is wrong. + * Export names are not necessarily unique within a package. */ + for (unsigned i = 0; i < pkg->export_count; i++) { + struct upkg_export *export = &pkg->priv->exports[i]; + if (strcmp(export->name, name) == 0) { + return i; + } + } + + return -1; +} + +const char *upkg_export_name(struct upkg *pkg, unsigned long idx) +{ + if (idx < pkg->export_count) + return pkg->priv->exports[idx].name; + return NULL; +} + +const char *upkg_export_class(struct upkg *pkg, unsigned long idx, + const char **package, const char **group) +{ + struct upkg_export *export; + struct upkg_import *iclass, *ipackage; + unsigned long pkg_idx; + + if (idx >= pkg->export_count) + return NULL; + + export = &pkg->priv->exports[idx]; + + /* ASSUMPTION: class references are always imports */ + if (export->class > 0) { + fprintf(stderr, "Assumption Violated: class not import\n"); + return NULL; + } + + /* ASSUMPTION: group references are always exports */ + if (export->package < 0) { + fprintf(stderr, "Assumption Violated: group not export\n"); + return NULL; + } + + /* Get the group name. */ + if (export->package > 0) { + pkg_idx = export->package - 1; + + if (pkg_idx >= pkg->export_count) { + return NULL; + } + + /* Lots more to handle. Function arguments are stupid. */ + + if (group) *group = pkg->priv->exports[pkg_idx].name; + } else { + if (group) *group = NULL; + } + + /* Get the class. */ + if (export->class == 0) { + if (package) *package = "Core"; + return "Class"; + } + + pkg_idx = -(export->class + 1); + if (pkg_idx >= pkg->import_count) + return NULL; + iclass = &pkg->priv->imports[pkg_idx]; + + /* ASSUMPTION: Class references are always Core.Class */ + if (strcmp(iclass->class_name, "Class") || strcmp(iclass->class_package, "Core")) { + fprintf(stderr, "Assumption Violated: class not Core.Class\n"); + return NULL; + } + + /* ASSUMPTION: Package references are always imports */ + if (iclass->package >= 0) { + fprintf(stderr, "Assumption Violated: package not import\n"); + return NULL; + } + + /* Get the package. */ + pkg_idx = -(iclass->package + 1); + if (pkg_idx >= pkg->import_count) + return NULL; + ipackage = &pkg->priv->imports[pkg_idx]; + + /* ASSUMPTION: Package references are always Core.Package */ + if (strcmp(ipackage->class_name, "Package") || strcmp(ipackage->class_package, "Core")) { + fprintf(stderr, "Assumption Violated: package not Core.Package\n"); + return NULL; + } + + if (package) *package = ipackage->object_name; + return iclass->object_name; +} + struct upkg_file *upkg_export_open(struct upkg *pkg, unsigned long idx) { struct upkg_file *f; diff --git a/src/upkg.c b/src/upkg.c index 6da174c..12dc09e 100644 --- a/src/upkg.c +++ b/src/upkg.c @@ -107,6 +107,23 @@ void print_guid(unsigned char guid[static 16]) } } +void print_upkg_exports(struct upkg *pkg) +{ + for (unsigned i = 0; i < pkg->export_count; i++) { + const char *name, *package, *group, *class; + + name = upkg_export_name(pkg, i); + class = upkg_export_class(pkg, i, &package, &group); + + if (!name || !class) + continue; + + printf("%u - %s%s%s (%s.%s)\n", i+1, + group ? group : "", group ? "." : "", name, + package, class); + } +} + int package_info(struct upkg *pkg) { printf("Version: %u\n", pkg->version); @@ -128,13 +145,17 @@ int package_info(struct upkg *pkg) } } + printf("Exports: %lu\n", pkg->export_count); + if (verbose >= 1) print_upkg_exports(pkg); + printf("Imports: %lu\n", pkg->import_count); + return EXIT_SUCCESS; } int main(int argc, char **argv) { struct upkg *pkg; - unsigned mode; + unsigned mode = MODE_INFO; int opt, rc = EXIT_FAILURE; if (argc > 0) progname = argv[0]; diff --git a/src/upkg.h b/src/upkg.h index 7ef55d7..08ee13a 100644 --- a/src/upkg.h +++ b/src/upkg.h @@ -66,6 +66,11 @@ int upkg_close(struct upkg *pkg); const char *upkg_get_name(struct upkg *pkg, unsigned long idx); +long upkg_export_find(struct upkg *pkg, const char *name); +const char *upkg_export_name(struct upkg *pkg, unsigned long idx); +const char *upkg_export_class(struct upkg *pkg, unsigned long idx, + const char **package, const char **group); + struct upkg_file *upkg_export_open(struct upkg *pkg, unsigned long idx); size_t upkg_export_read(struct upkg_file *f, void *buf, size_t n); int upkg_export_seek(struct upkg_file *f, long offset, int whence); -- 2.43.2