X-Git-Url: https://git.draconx.ca/gitweb/upkg.git/blobdiff_plain/557eccb32013460418b72bb20acd79c018a5e95a..7b7fa9198e6872739a50374aebe61b6444611438:/src/uobject/package.c diff --git a/src/uobject/package.c b/src/uobject/package.c index bd97135..5b29afd 100644 --- a/src/uobject/package.c +++ b/src/uobject/package.c @@ -25,6 +25,7 @@ #include #include +#include #include "upkg.h" #define U_PKG_GET_PRIV(o) \ @@ -36,13 +37,6 @@ struct upkg_priv { G_DEFINE_TYPE(UPkg, u_pkg, G_TYPE_TYPE_MODULE); -/* Package search path. */ -static char *search_path; -static size_t search_path_sz; - -/* List of package file extensions, in descending order of precedence. */ -static const char u_pkg_exts[][5] = { ".u", ".utx", ".umx", ".uax", ".unr" }; - static char *str_cpy_lower(char *dst, const char *src) { size_t i; @@ -54,25 +48,6 @@ static char *str_cpy_lower(char *dst, const char *src) return dst; } -static int str_cmp_lower(const char *s1, const char *s2) -{ - size_t i; - - for (i = 0; s1[i] && s2[i]; i++) { - int c1 = tolower(s1[i]), c2 = tolower(s2[i]); - if (c1 < c2) - return -1; - if (c1 > c2) - return 1; - } - - if (s1[i]) - return 1; - if (s2[i]) - return -1; - return 0; -} - static void dl_print_errors(const char *prefix) { const char *err; @@ -82,74 +57,25 @@ 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 class member - * will be filled in. - */ -static int find_package_by_name(const char *filename, void *data) -{ - GTypeModule *m = G_TYPE_MODULE(data); - UPkg *upkg = U_PKG(data); - - const char *base; - size_t len; - char *buf; - - base = strrchr(filename, '/'); - if (base) { - base++; - } else { - base = filename; - } - - if (str_cmp_lower(base, m->name) != 0) - return 0; - - len = strlen(filename); - buf = malloc(len + sizeof **u_pkg_exts); - if (!buf) - return 0; - strcpy(buf, filename); - - for (unsigned i = 0; i < sizeof u_pkg_exts / sizeof *u_pkg_exts; i++) { - strcpy(buf+len, u_pkg_exts[i]); - upkg->pkg = upkg_fopen(buf); - if (!upkg->pkg) { - free(buf); - return 1; - } - } - - free(buf); - return 0; -} - static gboolean u_pkg_load(GTypeModule *m) { struct upkg_priv *priv = U_PKG_GET_PRIV(m); int (*init_func)(GTypeModule *); - if (m->name) { - priv->native = lt_dlopenext(m->name); - if (!priv->native) { - dl_print_errors(m->name); - return FALSE; - } + /* Ignore failure here until we get rid of native-only packages. */ + U_PKG(m)->pkg = u_pkg_vfs_open_by_name(m->name); + priv->native = lt_dlopenext(m->name); + if (priv->native) { init_func = lt_dlsym(priv->native, "init"); if (!init_func || init_func(m) != 0) { dl_print_errors(__func__); lt_dlclose(priv->native); + upkg_close(U_PKG(m)->pkg); return FALSE; } } - if (!U_PKG(m)->pkg) { - lt_dlforeachfile(u_pkg_get_search_path(), find_package_by_name, m); - } - return TRUE; } @@ -168,6 +94,8 @@ static void u_pkg_unload(GTypeModule *m) if (lt_dlclose(priv->native) != 0) { dl_print_errors(__func__); } + + priv->native = NULL; } if (upkg->pkg) { @@ -183,11 +111,7 @@ 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); - } + u_pkg_unload(G_TYPE_MODULE(o)); } static void u_pkg_class_init(UPkgClass *class) @@ -215,56 +139,7 @@ static void u_pkg_class_init(UPkgClass *class) objclass->finalize = u_pkg_finalize; } -static int expand_search_path(size_t need) -{ - size_t want = search_path_sz; - if (want == 0) want = 1; - - while (want < need) - want *= 2; - - if (want > search_path_sz) { - char *new = realloc(search_path, want); - if (!new) { - return -1; - } - - search_path = new; - search_path_sz = want; - } - - return 0; -} - -const char *u_pkg_get_search_path(void) -{ - return search_path ? search_path : ""; -} - -int u_pkg_set_search_path(const char *path) -{ - if (expand_search_path(strlen(path)+1) != 0) - return -1; - strcpy(search_path, path); - return 0; -} - -int u_pkg_add_search_dir(const char *path) -{ - size_t end = search_path ? strlen(search_path) : 0; - - if (end == 0) { - return u_pkg_set_search_path(path); - } - - if (expand_search_path(end + strlen(path) + 2) != 0) - return -1; - search_path[end] = LT_PATHSEP_CHAR; - strcpy(search_path+end+1, path); - return 0; -} - -GTypeModule *u_pkg_new_by_name(const char *name) +GTypeModule *u_pkg_open(const char *name) { g_return_val_if_fail(name != NULL, NULL); @@ -283,20 +158,9 @@ GTypeModule *u_pkg_new_by_name(const char *name) return mod; } -GTypeModule *u_pkg_new_by_file(const char *filename) +bool u_pkg_is_native(GTypeModule *m) { - 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; - } + struct upkg_priv *priv = U_PKG_GET_PRIV(m); - mod->name = NULL; - U_PKG(mod)->pkg = pkg; - return mod; + return priv->native; }