From 6f3fad3be5e89d49b642aaa783894ef4076d76ea Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 26 Oct 2022 17:53:37 +0000 Subject: [PATCH] packages: Unify the dependency functions Signed-off-by: Michael Tremer --- src/_pakfire/package.c | 14 +- src/libpakfire/archive.c | 52 +--- src/libpakfire/build.c | 9 +- src/libpakfire/db.c | 68 ++--- src/libpakfire/dependencies.c | 31 +- src/libpakfire/include/pakfire/dependencies.h | 11 +- src/libpakfire/include/pakfire/package.h | 38 +-- src/libpakfire/libpakfire.sym | 10 +- src/libpakfire/package.c | 279 ++++++++++-------- src/libpakfire/packager.c | 63 +++- src/libpakfire/parser.c | 40 +-- 11 files changed, 324 insertions(+), 291 deletions(-) diff --git a/src/_pakfire/package.c b/src/_pakfire/package.c index 69496ccc6..bd4ae159a 100644 --- a/src/_pakfire/package.c +++ b/src/_pakfire/package.c @@ -390,7 +390,7 @@ static PyObject* Package_get_repo(PackageObject* self) { } static PyObject* Package_get_path(PackageObject* self) { - const char* path = pakfire_package_get_path(self->package); + const char* path = pakfire_package_get_string(self->package, PAKFIRE_PKG_PATH); if (!path) { PyErr_SetFromErrno(PyExc_OSError); return NULL; @@ -421,7 +421,7 @@ static PyObject* PyList_FromRelationList(char** deps) { } static PyObject* Package_get_provides(PackageObject* self) { - char** deps = pakfire_package_get_provides(self->package); + char** deps = pakfire_package_get_deps(self->package, PAKFIRE_PKG_PROVIDES); PyObject* list = PyList_FromRelationList(deps); @@ -435,7 +435,7 @@ static PyObject* Package_get_provides(PackageObject* self) { } static PyObject* Package_get_requires(PackageObject* self) { - char** deps = pakfire_package_get_requires(self->package); + char** deps = pakfire_package_get_deps(self->package, PAKFIRE_PKG_REQUIRES); PyObject* list = PyList_FromRelationList(deps); @@ -449,7 +449,7 @@ static PyObject* Package_get_requires(PackageObject* self) { } static PyObject* Package_get_obsoletes(PackageObject* self) { - char** deps = pakfire_package_get_obsoletes(self->package); + char** deps = pakfire_package_get_deps(self->package, PAKFIRE_PKG_OBSOLETES); PyObject* list = PyList_FromRelationList(deps); @@ -463,7 +463,7 @@ static PyObject* Package_get_obsoletes(PackageObject* self) { } static PyObject* Package_get_conflicts(PackageObject* self) { - char** deps = pakfire_package_get_conflicts(self->package); + char** deps = pakfire_package_get_deps(self->package, PAKFIRE_PKG_CONFLICTS); PyObject* list = PyList_FromRelationList(deps); @@ -477,7 +477,7 @@ static PyObject* Package_get_conflicts(PackageObject* self) { } static PyObject* Package_get_recommends(PackageObject* self) { - char** deps = pakfire_package_get_recommends(self->package); + char** deps = pakfire_package_get_deps(self->package, PAKFIRE_PKG_RECOMMENDS); PyObject* list = PyList_FromRelationList(deps); @@ -491,7 +491,7 @@ static PyObject* Package_get_recommends(PackageObject* self) { } static PyObject* Package_get_suggests(PackageObject* self) { - char** deps = pakfire_package_get_suggests(self->package); + char** deps = pakfire_package_get_deps(self->package, PAKFIRE_PKG_SUGGESTS); PyObject* list = PyList_FromRelationList(deps); diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index c1c5e9530..195debbc2 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -1221,25 +1221,9 @@ static int pakfire_archive_make_package_from_json(struct pakfire_archive* archiv } // Dependencies - const struct dependencies { - const char* type; - void (*func)(struct pakfire_package*, const char* s); - } dependencies[] = { - { "provides", pakfire_package_add_provides }, - { "prerequires", pakfire_package_add_prerequires }, - { "requires", pakfire_package_add_requires }, - { "conflicts", pakfire_package_add_conflicts }, - { "obsoletes", pakfire_package_add_obsoletes }, - { "recommends", pakfire_package_add_recommends }, - { "suggests", pakfire_package_add_suggests }, - { "supplements", pakfire_package_add_supplements }, - { "enhances", pakfire_package_add_enhances }, - { NULL, NULL }, - }; - - for (const struct dependencies* deps = dependencies; deps->type; deps++) { + for (const struct pakfire_dep* dep = pakfire_deps; dep->key; dep++) { struct json_object* array = pakfire_archive_metadata_get_object( - archive, "dependencies", deps->type); + archive, "dependencies", dep->name); if (!array) continue; @@ -1260,7 +1244,9 @@ static int pakfire_archive_make_package_from_json(struct pakfire_archive* archiv continue; // Add the dependency to the package - deps->func(pkg, string); + r = pakfire_package_add_dep(pkg, dep->key, string); + if (r) + goto ERROR; } } @@ -1461,29 +1447,15 @@ static int pakfire_archive_make_legacy_package(struct pakfire_archive* archive, pakfire_package_set_num(pkg, PAKFIRE_PKG_BUILD_TIME, t); } - // Relations - - const struct __relation { - const char* type; - void (*func)(struct pakfire_package*, const char* dep); - } relations[] = { - { "provides", pakfire_package_add_provides }, - { "prerequires", pakfire_package_add_prerequires }, - { "requires", pakfire_package_add_requires }, - { "conflicts", pakfire_package_add_conflicts }, - { "obsoletes", pakfire_package_add_obsoletes }, - { "recommends", pakfire_package_add_recommends }, - { "suggests", pakfire_package_add_suggests }, - { "supplements", pakfire_package_add_supplements }, - { "enhances", pakfire_package_add_enhances }, - { NULL, NULL }, - }; - - for (const struct __relation* relation = relations; relation->type; relation++) { - char* rels = pakfire_archive_get(archive, "dependencies", relation->type); + // Dependencies + for (const struct pakfire_dep* dep = pakfire_deps; dep->key; dep++) { + char* rels = pakfire_archive_get(archive, "dependencies", dep->name); if (rels) { - pakfire_str2deps(archive->pakfire, pkg, relation->func, rels); + r = pakfire_str2deps(archive->pakfire, pkg, dep->key, rels); free(rels); + + if (r) + goto ERROR; } } diff --git a/src/libpakfire/build.c b/src/libpakfire/build.c index 15ceae51a..9dce793b8 100644 --- a/src/libpakfire/build.c +++ b/src/libpakfire/build.c @@ -247,8 +247,7 @@ static int pakfire_build_find_dependencies(struct pakfire_build* build, // Add all provides to the package if (provides) { - r = pakfire_str2deps(build->pakfire, pkg, - pakfire_package_add_provides, provides); + r = pakfire_str2deps(build->pakfire, pkg, PAKFIRE_PKG_PROVIDES, provides); if (r) { ERROR(build->pakfire, "Could not add provides: %m\n"); goto ERROR; @@ -257,8 +256,7 @@ static int pakfire_build_find_dependencies(struct pakfire_build* build, // Add all requires to the package if (requires) { - r = pakfire_str2deps(build->pakfire, pkg, - pakfire_package_add_requires, requires); + r = pakfire_str2deps(build->pakfire, pkg, PAKFIRE_PKG_REQUIRES, requires); if (r) { ERROR(build->pakfire, "Could not add provides: %m\n"); goto ERROR; @@ -417,8 +415,7 @@ static int pakfire_build_add_scriptlet_requires(struct pakfire_build* build, // Add all pre-requires to the package if (prerequires) { - r = pakfire_str2deps(build->pakfire, pkg, - pakfire_package_add_prerequires, prerequires); + r = pakfire_str2deps(build->pakfire, pkg, PAKFIRE_PKG_PREREQUIRES, prerequires); if (r) { ERROR(build->pakfire, "Could not add pre-requires: %m\n"); goto ERROR; diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c index 2b7fa9086..cc0728949 100644 --- a/src/libpakfire/db.c +++ b/src/libpakfire/db.c @@ -839,6 +839,7 @@ static void pakfire_db_add_userinstalled(struct pakfire* pakfire, const char* na static int pakfire_db_add_dependencies(struct pakfire_db* db, unsigned long id, struct pakfire_package* pkg) { sqlite3_stmt* stmt = NULL; + char** list = NULL; int r = 1; const char* sql = "INSERT INTO dependencies(pkg, type, dependency) VALUES(?, ?, ?)"; @@ -851,28 +852,14 @@ static int pakfire_db_add_dependencies(struct pakfire_db* db, unsigned long id, goto END; } - const struct __relation { - const char* type; - char** (*func)(struct pakfire_package*); - } relations[] = { - { "provides", pakfire_package_get_provides }, - { "prerequires", pakfire_package_get_prerequires }, - { "requires", pakfire_package_get_requires }, - { "conflicts", pakfire_package_get_conflicts }, - { "obsoletes", pakfire_package_get_obsoletes }, - { "recommends", pakfire_package_get_recommends }, - { "suggests", pakfire_package_get_suggests }, - { "supplements", pakfire_package_get_supplements }, - { "enhances", pakfire_package_get_enhances }, - { NULL, NULL }, - }; - - for (const struct __relation* relation = relations; relation->type; relation++) { - char** list = relation->func(pkg); - if (!list) - continue; + for (const struct pakfire_dep* dep = pakfire_deps; dep->key; dep++) { + list = pakfire_package_get_deps(pkg, dep->key); + if (!list) { + r = 1; + goto END; + } - for (char** dep = list; *dep; dep++) { + for (char** d = list; *d; d++) { // Bind package ID r = sqlite3_bind_int64(stmt, 1, id); if (r) { @@ -882,7 +869,7 @@ static int pakfire_db_add_dependencies(struct pakfire_db* db, unsigned long id, } // Bind type - r = sqlite3_bind_text(stmt, 2, relation->type, -1, NULL); + r = sqlite3_bind_text(stmt, 2, dep->name, -1, NULL); if (r) { ERROR(db->pakfire, "Could not bind type: %s\n", sqlite3_errmsg(db->handle)); @@ -890,7 +877,7 @@ static int pakfire_db_add_dependencies(struct pakfire_db* db, unsigned long id, } // Bind dependency - r = sqlite3_bind_text(stmt, 3, *dep, -1, NULL); + r = sqlite3_bind_text(stmt, 3, *d, -1, NULL); if (r) { ERROR(db->pakfire, "Could not bind dependency: %s\n", sqlite3_errmsg(db->handle)); @@ -902,13 +889,9 @@ static int pakfire_db_add_dependencies(struct pakfire_db* db, unsigned long id, r = sqlite3_step(stmt); } while (r == SQLITE_BUSY); - free(*dep); - // Reset bound values sqlite3_reset(stmt); } - - free(list); } // All okay @@ -917,6 +900,11 @@ static int pakfire_db_add_dependencies(struct pakfire_db* db, unsigned long id, END: if (stmt) sqlite3_finalize(stmt); + if (list) { + for (char** dep = list; *dep; dep++) + free(dep); + free(list); + } return r; } @@ -1882,24 +1870,26 @@ static int pakfire_db_load_package(struct pakfire_db* db, struct pakfire_repo* r const struct dependency { unsigned int field; - void (*func)(struct pakfire_package* pkg, const char* dep); + const enum pakfire_package_key key; } dependencies[] = { - { 20, pakfire_package_add_provides }, - { 21, pakfire_package_add_prerequires }, - { 22, pakfire_package_add_requires }, - { 23, pakfire_package_add_conflicts }, - { 24, pakfire_package_add_obsoletes }, - { 25, pakfire_package_add_recommends }, - { 26, pakfire_package_add_suggests }, - { 27, pakfire_package_add_supplements }, - { 28, pakfire_package_add_enhances }, - { 0, NULL }, + { 20, PAKFIRE_PKG_PROVIDES }, + { 21, PAKFIRE_PKG_PREREQUIRES }, + { 22, PAKFIRE_PKG_REQUIRES }, + { 23, PAKFIRE_PKG_CONFLICTS }, + { 24, PAKFIRE_PKG_OBSOLETES }, + { 25, PAKFIRE_PKG_RECOMMENDS }, + { 26, PAKFIRE_PKG_SUGGESTS }, + { 27, PAKFIRE_PKG_SUPPLEMENTS }, + { 28, PAKFIRE_PKG_ENHANCES }, + { 0 }, }; for (const struct dependency* deps = dependencies; deps->field; deps++) { const char* relations = (const char*)sqlite3_column_text(stmt, deps->field); if (relations) { - pakfire_str2deps(db->pakfire, pkg, deps->func, relations); + r = pakfire_str2deps(db->pakfire, pkg, deps->key, relations); + if (r) + goto ERROR; } } diff --git a/src/libpakfire/dependencies.c b/src/libpakfire/dependencies.c index a2b243c95..0e08ee743 100644 --- a/src/libpakfire/dependencies.c +++ b/src/libpakfire/dependencies.c @@ -32,6 +32,19 @@ #include #include +const struct pakfire_dep pakfire_deps[] = { + { PAKFIRE_PKG_PROVIDES, "provides" }, + { PAKFIRE_PKG_PREREQUIRES, "prerequires" }, + { PAKFIRE_PKG_REQUIRES, "requires" }, + { PAKFIRE_PKG_CONFLICTS, "conflicts" }, + { PAKFIRE_PKG_OBSOLETES, "obsoletes" }, + { PAKFIRE_PKG_RECOMMENDS, "recommends" }, + { PAKFIRE_PKG_SUGGESTS, "suggests" }, + { PAKFIRE_PKG_SUPPLEMENTS, "supplements" }, + { PAKFIRE_PKG_ENHANCES, "enhances" }, + { 0, NULL }, +}; + static const struct pakfire_rich_operation { const char* keyword; const int flags; @@ -307,11 +320,12 @@ Id pakfire_str2dep(struct pakfire* pakfire, const char* s) { } int pakfire_str2deps(struct pakfire* pakfire, struct pakfire_package* pkg, - void (callback)(struct pakfire_package* pkg, const char* dep), const char* deps) { + const enum pakfire_package_key key, const char* deps) { char* p = NULL; + int r = 0; // Check for valid inputs - if (!callback || !deps) { + if (!deps) { errno = EINVAL; return 1; } @@ -319,7 +333,7 @@ int pakfire_str2deps(struct pakfire* pakfire, struct pakfire_package* pkg, // Copy deps into a working buffer char* buffer = strdup(deps); if (!buffer) - return 1; + goto ERROR; char* dep = strtok_r(buffer, "\n", &p); @@ -328,12 +342,17 @@ int pakfire_str2deps(struct pakfire* pakfire, struct pakfire_package* pkg, DEBUG(pakfire, "Found dep '%s'\n", dep); // Add the dependency - callback(pkg, dep); + r = pakfire_package_add_dep(pkg, key, dep); + if (r) + goto ERROR; // Move on to next token dep = strtok_r(NULL, "\n", &p); } - free(buffer); - return 0; +ERROR: + if (buffer) + free(buffer); + + return r; } diff --git a/src/libpakfire/include/pakfire/dependencies.h b/src/libpakfire/include/pakfire/dependencies.h index 01bbeb0f7..baa5e91d6 100644 --- a/src/libpakfire/include/pakfire/dependencies.h +++ b/src/libpakfire/include/pakfire/dependencies.h @@ -21,15 +21,24 @@ #ifndef PAKFIRE_DEPENDENCIES_H #define PAKFIRE_DEPENDENCIES_H +#ifdef PAKFIRE_PRIVATE + #include #include #include +extern const struct pakfire_dep { + const enum pakfire_package_key key; + const char* name; +} pakfire_deps[]; + const char* pakfire_dep2str(struct pakfire* pakfire, Id id); Id pakfire_str2dep(struct pakfire* pakfire, const char* s); int pakfire_str2deps(struct pakfire* pakfire, struct pakfire_package* pkg, - void (callback)(struct pakfire_package* pkg, const char* dep), const char* deps); + const enum pakfire_package_key key, const char* deps); + +#endif /* PAKFIRE_PRIVATE */ #endif /* PAKFIRE_DEPENDENCIES_H */ diff --git a/src/libpakfire/include/pakfire/package.h b/src/libpakfire/include/pakfire/package.h index 71086d3bf..9f2f3f8db 100644 --- a/src/libpakfire/include/pakfire/package.h +++ b/src/libpakfire/include/pakfire/package.h @@ -60,6 +60,17 @@ enum pakfire_package_key { PAKFIRE_PKG_SOURCE_NAME, PAKFIRE_PKG_SOURCE_EVR, PAKFIRE_PKG_SOURCE_ARCH, + + // Dependencies + PAKFIRE_PKG_PROVIDES, + PAKFIRE_PKG_PREREQUIRES, + PAKFIRE_PKG_REQUIRES, + PAKFIRE_PKG_CONFLICTS, + PAKFIRE_PKG_OBSOLETES, + PAKFIRE_PKG_RECOMMENDS, + PAKFIRE_PKG_SUGGESTS, + PAKFIRE_PKG_SUPPLEMENTS, + PAKFIRE_PKG_ENHANCES, }; int pakfire_package_create(struct pakfire_package** package, struct pakfire* pakfire, @@ -91,22 +102,16 @@ unsigned long long pakfire_package_get_num(struct pakfire_package* pkg, int pakfire_package_set_num(struct pakfire_package* pkg, const enum pakfire_package_key key, unsigned long long num); +// Dependencies +char** pakfire_package_get_deps(struct pakfire_package* pkg, + const enum pakfire_package_key key); + const unsigned char* pakfire_package_get_digest(struct pakfire_package* pkg, enum pakfire_digest_types* type, size_t* length); int pakfire_package_set_digest(struct pakfire_package* pkg, enum pakfire_digest_types type, const unsigned char* digest, const size_t length); size_t pakfire_package_get_size(struct pakfire_package* pkg); -char** pakfire_package_get_provides(struct pakfire_package* pkg); -char** pakfire_package_get_prerequires(struct pakfire_package* pkg); -char** pakfire_package_get_requires(struct pakfire_package* pkg); -char** pakfire_package_get_conflicts(struct pakfire_package* pkg); -char** pakfire_package_get_obsoletes(struct pakfire_package* pkg); -char** pakfire_package_get_recommends(struct pakfire_package* pkg); -char** pakfire_package_get_suggests(struct pakfire_package* pkg); -char** pakfire_package_get_supplements(struct pakfire_package* pkg); -char** pakfire_package_get_enhances(struct pakfire_package* pkg); - int pakfire_package_get_reverse_requires(struct pakfire_package* pkg, struct pakfire_packagelist** list); @@ -143,15 +148,10 @@ char* pakfire_package_join_evr(const char* e, const char* v, const char* r); int pakfire_package_is_installed(struct pakfire_package* pkg); -void pakfire_package_add_provides(struct pakfire_package* pkg, const char* dep); -void pakfire_package_add_prerequires(struct pakfire_package* pkg, const char* dep); -void pakfire_package_add_requires(struct pakfire_package* pkg, const char* dep); -void pakfire_package_add_conflicts(struct pakfire_package* pkg, const char* dep); -void pakfire_package_add_obsoletes(struct pakfire_package* pkg, const char* dep); -void pakfire_package_add_recommends(struct pakfire_package* pkg, const char* dep); -void pakfire_package_add_suggests(struct pakfire_package* pkg, const char* dep); -void pakfire_package_add_supplements(struct pakfire_package* pkg, const char* dep); -void pakfire_package_add_enhances(struct pakfire_package* pkg, const char* dep); +// Dependencies +int pakfire_package_add_dep(struct pakfire_package* pkg, + const enum pakfire_package_key key, const char* dep); + int pakfire_package_has_rich_deps(struct pakfire_package* pkg); struct json_object* pakfire_package_to_json(struct pakfire_package* pkg); diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index 00ff171d1..1648f5021 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -168,25 +168,17 @@ global: pakfire_package_dump; pakfire_package_eq; pakfire_package_get_cache_path; - pakfire_package_get_conflicts; + pakfire_package_get_deps; pakfire_package_get_digest; - pakfire_package_get_enhances; pakfire_package_get_filelist; pakfire_package_get_location; pakfire_package_get_num; - pakfire_package_get_obsoletes; pakfire_package_get_pakfire; pakfire_package_get_path; - pakfire_package_get_prerequires; - pakfire_package_get_provides; - pakfire_package_get_recommends; pakfire_package_get_repo; - pakfire_package_get_requires; pakfire_package_get_reverse_requires; pakfire_package_get_size; pakfire_package_get_string; - pakfire_package_get_suggests; - pakfire_package_get_supplements; pakfire_package_get_uuid; pakfire_package_ref; pakfire_package_set_checksum; diff --git a/src/libpakfire/package.c b/src/libpakfire/package.c index c24aeadd7..cf7fe8b85 100644 --- a/src/libpakfire/package.c +++ b/src/libpakfire/package.c @@ -837,121 +837,134 @@ PAKFIRE_EXPORT size_t pakfire_package_get_size(struct pakfire_package* pkg) { return pakfire_package_get_num(pkg, PAKFIRE_PKG_DOWNLOADSIZE, 0); } -static char** pakfire_package_get_relationlist( - struct pakfire_package* pkg, Id type, Id marker) { - char** array = NULL; +// Dependencies - Queue q; - queue_init(&q); - - Solvable* s = get_solvable(pkg); +static int pakfire_package_dep2id(const enum pakfire_package_key key, + Id* id, Id* marker) { + switch (key) { + case PAKFIRE_PKG_PROVIDES: + *id = SOLVABLE_PROVIDES; + *marker = -SOLVABLE_FILEMARKER; + break; - // Fetch all deps - solvable_lookup_deparray(s, type, &q, marker); + case PAKFIRE_PKG_PREREQUIRES: + *id = SOLVABLE_REQUIRES; + *marker = SOLVABLE_PREREQMARKER; + break; - // Nothing to do if the array was empty - if (!q.count) - goto ERROR; + case PAKFIRE_PKG_REQUIRES: + *id = SOLVABLE_REQUIRES; + *marker = -SOLVABLE_PREREQMARKER; + break; - // Allocate array - array = calloc(q.count + 1, sizeof(*array)); - if (!array) - goto ERROR; + case PAKFIRE_PKG_CONFLICTS: + *id = SOLVABLE_CONFLICTS; + break; - for (int i = 0; i < q.count; i++) { - const char* dep = pakfire_dep2str(pkg->pakfire, q.elements[i]); + case PAKFIRE_PKG_OBSOLETES: + *id = SOLVABLE_OBSOLETES; + break; - array[i] = strdup(dep); - } + case PAKFIRE_PKG_RECOMMENDS: + *id = SOLVABLE_RECOMMENDS; + break; -ERROR: - queue_free(&q); + case PAKFIRE_PKG_SUGGESTS: + *id = SOLVABLE_SUGGESTS; + break; - return array; -} + case PAKFIRE_PKG_SUPPLEMENTS: + *id = SOLVABLE_SUPPLEMENTS; + break; -static void pakfire_package_add_dep(struct pakfire_package* pkg, Id type, - const char* dep, Id marker) { - Solvable* s = get_solvable(pkg); + case PAKFIRE_PKG_ENHANCES: + *id = SOLVABLE_ENHANCES; + break; - // Parse the dependency - Id id = pakfire_str2dep(pkg->pakfire, dep); - if (!id) - return; + // This operation is not possible for any other types + default: + errno = EINVAL; + return 1; + } - solvable_add_deparray(s, type, id, marker); + return 0; } -PAKFIRE_EXPORT char** pakfire_package_get_provides(struct pakfire_package* pkg) { - return pakfire_package_get_relationlist(pkg, SOLVABLE_PROVIDES, -SOLVABLE_FILEMARKER); -} +PAKFIRE_EXPORT char** pakfire_package_get_deps(struct pakfire_package* pkg, + const enum pakfire_package_key key) { + Solvable* s = get_solvable(pkg); + char** ret = NULL; + int r; -void pakfire_package_add_provides(struct pakfire_package* pkg, const char* dep) { - pakfire_package_add_dep(pkg, SOLVABLE_PROVIDES, dep, -SOLVABLE_FILEMARKER); -} + Queue q; + Id id = ID_NULL; + Id marker = ID_NULL; + const char* dep = NULL; -PAKFIRE_EXPORT char** pakfire_package_get_prerequires(struct pakfire_package* pkg) { - return pakfire_package_get_relationlist(pkg, SOLVABLE_REQUIRES, SOLVABLE_PREREQMARKER); -} + r = pakfire_package_dep2id(key, &id, &marker); + if (r) + return NULL; -void pakfire_package_add_prerequires(struct pakfire_package* pkg, const char* dep) { - pakfire_package_add_dep(pkg, SOLVABLE_REQUIRES, dep, SOLVABLE_PREREQMARKER); -} + // Initialize the output queue + queue_init(&q); -PAKFIRE_EXPORT char** pakfire_package_get_requires(struct pakfire_package* pkg) { - return pakfire_package_get_relationlist(pkg, SOLVABLE_REQUIRES, -SOLVABLE_PREREQMARKER); -} + // Fetch all deps + solvable_lookup_deparray(s, id, &q, marker); -void pakfire_package_add_requires(struct pakfire_package* pkg, const char* dep) { - pakfire_package_add_dep(pkg, SOLVABLE_REQUIRES, dep, -SOLVABLE_PREREQMARKER); -} + // Allocate array + ret = calloc(q.count + 1, sizeof(*ret)); + if (!ret) + goto ERROR; -PAKFIRE_EXPORT char** pakfire_package_get_conflicts(struct pakfire_package* pkg) { - return pakfire_package_get_relationlist(pkg, SOLVABLE_CONFLICTS, 0); -} + for (int i = 0; i < q.count; i++) { + dep = pakfire_dep2str(pkg->pakfire, q.elements[i]); + if (!dep) + goto ERROR; -void pakfire_package_add_conflicts(struct pakfire_package* pkg, const char* dep) { - pakfire_package_add_dep(pkg, SOLVABLE_CONFLICTS, dep, 0); -} + ret[i] = strdup(dep); + if (!ret[i]) + goto ERROR; + } -PAKFIRE_EXPORT char** pakfire_package_get_obsoletes(struct pakfire_package* pkg) { - return pakfire_package_get_relationlist(pkg, SOLVABLE_OBSOLETES, 0); -} + // All good! + goto SUCCESS; -void pakfire_package_add_obsoletes(struct pakfire_package* pkg, const char* dep) { - pakfire_package_add_dep(pkg, SOLVABLE_OBSOLETES, dep, 0); -} +ERROR: + if (ret) { + for (char** e = ret; *e; e++) + free(*e); + free(ret); -PAKFIRE_EXPORT char** pakfire_package_get_recommends(struct pakfire_package* pkg) { - return pakfire_package_get_relationlist(pkg, SOLVABLE_RECOMMENDS, 0); -} + ret = NULL; + } -void pakfire_package_add_recommends(struct pakfire_package* pkg, const char* dep) { - pakfire_package_add_dep(pkg, SOLVABLE_RECOMMENDS, dep, 0); -} +SUCCESS: + queue_free(&q); -PAKFIRE_EXPORT char** pakfire_package_get_suggests(struct pakfire_package* pkg) { - return pakfire_package_get_relationlist(pkg, SOLVABLE_SUGGESTS, 0); + return ret; } -void pakfire_package_add_suggests(struct pakfire_package* pkg, const char* dep) { - pakfire_package_add_dep(pkg, SOLVABLE_SUGGESTS, dep, 0); -} +int pakfire_package_add_dep(struct pakfire_package* pkg, + const enum pakfire_package_key key, const char* dep) { + Solvable* s = get_solvable(pkg); + int r; -PAKFIRE_EXPORT char** pakfire_package_get_supplements(struct pakfire_package* pkg) { - return pakfire_package_get_relationlist(pkg, SOLVABLE_SUPPLEMENTS, 0); -} + Id id = ID_NULL; + Id marker = ID_NULL; -void pakfire_package_add_supplements(struct pakfire_package* pkg, const char* dep) { - pakfire_package_add_dep(pkg, SOLVABLE_SUPPLEMENTS, dep, 0); -} + r = pakfire_package_dep2id(key, &id, &marker); + if (r) + return r; -PAKFIRE_EXPORT char** pakfire_package_get_enhances(struct pakfire_package* pkg) { - return pakfire_package_get_relationlist(pkg, SOLVABLE_ENHANCES, 0); -} + // Parse the dependency + Id depid = pakfire_str2dep(pkg->pakfire, dep); + if (!depid) + return 1; -void pakfire_package_add_enhances(struct pakfire_package* pkg, const char* dep) { - pakfire_package_add_dep(pkg, SOLVABLE_ENHANCES, dep, 0); + // Append to the dependency array + solvable_add_deparray(s, id, depid, marker); + + return 0; } PAKFIRE_EXPORT int pakfire_package_get_reverse_requires(struct pakfire_package* pkg, @@ -1246,40 +1259,64 @@ PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags pakfire_package_dump_add_line(&string, _("Build Host"), build_host); // Dependencies - - const struct relation { - const char* name; - char** (*get)(struct pakfire_package* pkg); - } relations[] = { - { _("Provides"), pakfire_package_get_provides, }, - { _("Pre-Requires"), pakfire_package_get_prerequires, }, - { _("Requires"), pakfire_package_get_requires, }, - { _("Conflicts"), pakfire_package_get_conflicts, }, - { _("Obsoletes"), pakfire_package_get_obsoletes, }, - { _("Recommends"), pakfire_package_get_recommends, }, - { _("Suggests"), pakfire_package_get_suggests, }, - { _("Supplements"), pakfire_package_get_supplements, }, - { _("Enhances"), pakfire_package_get_enhances, }, - { NULL, NULL}, - }; - - for (const struct relation* relation = relations; relation->name; relation++) { - char** deps = relation->get(pkg); + for (const struct pakfire_dep* dep = pakfire_deps; dep->key; dep++) { + char** deps = pakfire_package_get_deps(pkg, dep->key); if (deps) { - name = relation->name; size_t count = 0; // Count elements in the list - for (char** dep = deps; *dep; dep++) + for (char** d = deps; *d; d++) count++; // Sort the list qsort(deps, count, sizeof(*deps), pakfire_sort_dependencies); + switch (dep->key) { + case PAKFIRE_PKG_PROVIDES: + name = _("Provides"); + break; + + case PAKFIRE_PKG_PREREQUIRES: + name = _("Pre-Requires"); + break; + + case PAKFIRE_PKG_REQUIRES: + name = _("Requires"); + break; + + case PAKFIRE_PKG_CONFLICTS: + name = _("Conflicts"); + break; + + case PAKFIRE_PKG_OBSOLETES: + name = _("Obsoletes"); + break; + + case PAKFIRE_PKG_RECOMMENDS: + name = _("Recommends"); + break; + + case PAKFIRE_PKG_SUGGESTS: + name = _("Suggests"); + break; + + case PAKFIRE_PKG_SUPPLEMENTS: + name = _("Supplements"); + break; + + case PAKFIRE_PKG_ENHANCES: + name = _("Enhances"); + break; + + default: + name = NULL; + break; + } + // Write it to the console - for (char** dep = deps; *dep; dep++) { - pakfire_package_dump_add_line(&string, name, *dep); - free(*dep); + for (char** d = deps; *d; d++) { + pakfire_package_dump_add_line(&string, name, *d); + free(*d); // Clear name after first line name = NULL; @@ -1456,13 +1493,11 @@ static int _pakfire_package_add_json_dependencies( struct pakfire_package* pkg, struct json_object* json, const char* name, - char** (*func)(struct pakfire_package* pkg)) { + const enum pakfire_package_key key) { // Fetch dependencies - char** dependencies = func(pkg); - - // Nothing to do if there are no dependencies + char** dependencies = pakfire_package_get_deps(pkg, key); if (!dependencies) - return 0; + return 1; // Add dependencies int r = pakfire_json_add_string_array(pkg->pakfire, json, name, dependencies); @@ -1490,55 +1525,55 @@ static int pakfire_package_add_json_dependencies( // Pre-requires r = _pakfire_package_add_json_dependencies(pkg, object, - "prerequires", pakfire_package_get_prerequires); + "prerequires", PAKFIRE_PKG_PREREQUIRES); if (r) goto ERROR; // Requires r = _pakfire_package_add_json_dependencies(pkg, object, - "requires", pakfire_package_get_requires); + "requires", PAKFIRE_PKG_REQUIRES); if (r) goto ERROR; // Provides r = _pakfire_package_add_json_dependencies(pkg, object, - "provides", pakfire_package_get_provides); + "provides", PAKFIRE_PKG_PROVIDES); if (r) goto ERROR; // Conflicts r = _pakfire_package_add_json_dependencies(pkg, object, - "conflicts", pakfire_package_get_conflicts); + "conflicts", PAKFIRE_PKG_CONFLICTS); if (r) goto ERROR; // Obsoletes r = _pakfire_package_add_json_dependencies(pkg, object, - "obsoletes", pakfire_package_get_obsoletes); + "obsoletes", PAKFIRE_PKG_OBSOLETES); if (r) goto ERROR; // Recommends r = _pakfire_package_add_json_dependencies(pkg, object, - "recommends", pakfire_package_get_recommends); + "recommends", PAKFIRE_PKG_RECOMMENDS); if (r) goto ERROR; // Suggests r = _pakfire_package_add_json_dependencies(pkg, object, - "suggests", pakfire_package_get_suggests); + "suggests", PAKFIRE_PKG_SUGGESTS); if (r) goto ERROR; // Supplements r = _pakfire_package_add_json_dependencies(pkg, object, - "supplements", pakfire_package_get_supplements); + "supplements", PAKFIRE_PKG_SUPPLEMENTS); if (r) goto ERROR; // Enhances r = _pakfire_package_add_json_dependencies(pkg, object, - "enhances", pakfire_package_get_enhances); + "enhances", PAKFIRE_PKG_ENHANCES); if (r) goto ERROR; diff --git a/src/libpakfire/packager.c b/src/libpakfire/packager.c index 71f10b40d..8e3a8faeb 100644 --- a/src/libpakfire/packager.c +++ b/src/libpakfire/packager.c @@ -132,18 +132,42 @@ int pakfire_packager_create(struct pakfire_packager** packager, goto ERROR; // Add a requirement for the cryptographic algorithms we are using - if (p->digests & PAKFIRE_DIGEST_SHA3_512) - pakfire_package_add_requires(p->pkg, "pakfire(Digest-SHA3-512)"); - if (p->digests & PAKFIRE_DIGEST_SHA3_256) - pakfire_package_add_requires(p->pkg, "pakfire(Digest-SHA3-256)"); - if (p->digests & PAKFIRE_DIGEST_BLAKE2B512) - pakfire_package_add_requires(p->pkg, "pakfire(Digest-BLAKE2b512)"); - if (p->digests & PAKFIRE_DIGEST_BLAKE2S256) - pakfire_package_add_requires(p->pkg, "pakfire(Digest-BLAKE2s256)"); - if (p->digests & PAKFIRE_DIGEST_SHA2_512) - pakfire_package_add_requires(p->pkg, "pakfire(Digest-SHA2-512)"); - if (p->digests & PAKFIRE_DIGEST_SHA2_256) - pakfire_package_add_requires(p->pkg, "pakfire(Digest-SHA2-256)"); + if (p->digests & PAKFIRE_DIGEST_SHA3_512) { + r = pakfire_package_add_dep(p->pkg, + PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA3-512)"); + if (r) + goto ERROR; + } + if (p->digests & PAKFIRE_DIGEST_SHA3_256) { + r = pakfire_package_add_dep(p->pkg, + PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA3-256)"); + if (r) + goto ERROR; + } + if (p->digests & PAKFIRE_DIGEST_BLAKE2B512) { + r = pakfire_package_add_dep(p->pkg, + PAKFIRE_PKG_REQUIRES, "pakfire(Digest-BLAKE2b512)"); + if (r) + goto ERROR; + } + if (p->digests & PAKFIRE_DIGEST_BLAKE2S256) { + r = pakfire_package_add_dep(p->pkg, + PAKFIRE_PKG_REQUIRES, "pakfire(Digest-BLAKE2s256)"); + if (r) + goto ERROR; + } + if (p->digests & PAKFIRE_DIGEST_SHA2_512) { + r = pakfire_package_add_dep(p->pkg, + PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA2-512)"); + if (r) + goto ERROR; + } + if (p->digests & PAKFIRE_DIGEST_SHA2_256) { + r = pakfire_package_add_dep(p->pkg, + PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA2-256)"); + if (r) + goto ERROR; + } *packager = p; @@ -266,8 +290,10 @@ static int pakfire_packager_write_format(struct pakfire_packager* packager, return r; // Add package format marker - pakfire_package_add_requires(packager->pkg, + r = pakfire_package_add_dep(packager->pkg, PAKFIRE_PKG_REQUIRES, "pakfire(PackageFormat-" TO_STRING(PACKAGE_FORMAT) ")"); + if (r) + return r; return 0; } @@ -351,8 +377,12 @@ int pakfire_packager_finish(struct pakfire_packager* packager, FILE* f) { const char* nevra = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_NEVRA); // Add requires feature markers - if (pakfire_package_has_rich_deps(packager->pkg)) - pakfire_package_add_requires(packager->pkg, "pakfire(RichDependencies)"); + if (pakfire_package_has_rich_deps(packager->pkg)) { + r = pakfire_package_add_dep(packager->pkg, + PAKFIRE_PKG_REQUIRES, "pakfire(RichDependencies)"); + if (r) + goto ERROR; + } #ifdef ENABLE_DEBUG DEBUG(packager->pakfire, "Filelist:\n"); @@ -423,7 +453,8 @@ int pakfire_packager_finish(struct pakfire_packager* packager, FILE* f) { } // Add feature marker - pakfire_package_add_requires(packager->pkg, "pakfire(Compress-Zstandard)"); + pakfire_package_add_dep(packager->pkg, + PAKFIRE_PKG_REQUIRES, "pakfire(Compress-Zstandard)"); // Store the filelist r = pakfire_package_set_filelist(packager->pkg, packager->filelist); diff --git a/src/libpakfire/parser.c b/src/libpakfire/parser.c index e861c08ec..e2577bb1d 100644 --- a/src/libpakfire/parser.c +++ b/src/libpakfire/parser.c @@ -881,6 +881,7 @@ int pakfire_parser_create_package(struct pakfire_parser* parser, char* name = NULL; char* evr = NULL; char* arch = NULL; + char* deps = NULL; DEBUG(parser->pakfire, "Building package from namespace '%s'\n", namespace); @@ -967,34 +968,19 @@ int pakfire_parser_create_package(struct pakfire_parser* parser, // Fetch build dependencies if (is_source) { - char* requires = pakfire_parser_get(parser, "build", "requires"); - if (requires) { - pakfire_str2deps(parser->pakfire, *pkg, - pakfire_package_add_requires, requires); - free(requires); + deps = pakfire_parser_get(parser, "build", "requires"); + if (deps) { + r = pakfire_str2deps(parser->pakfire, *pkg, PAKFIRE_PKG_REQUIRES, deps); + if (r) + goto CLEANUP; } } else { - const struct relation { - const char* type; - void (*func)(struct pakfire_package*, const char* dep); - } relations[] = { - { "provides", pakfire_package_add_provides }, - { "prerequires", pakfire_package_add_prerequires }, - { "requires", pakfire_package_add_requires }, - { "conflicts", pakfire_package_add_conflicts }, - { "obsoletes", pakfire_package_add_obsoletes }, - { "recommends", pakfire_package_add_recommends }, - { "suggests", pakfire_package_add_suggests }, - { "supplements", pakfire_package_add_supplements }, - { "enhances", pakfire_package_add_enhances }, - { NULL, NULL }, - }; - - for (const struct relation* relation = relations; relation->type; relation++) { - char* rels = pakfire_parser_get(parser, namespace, relation->type); - if (rels) { - pakfire_str2deps(parser->pakfire, *pkg, relation->func, rels); - free(rels); + for (const struct pakfire_dep* dep = pakfire_deps; dep->key; dep++) { + deps = pakfire_parser_get(parser, namespace, dep->name); + if (deps) { + r = pakfire_str2deps(parser->pakfire, *pkg, dep->key, deps); + if (r) + goto CLEANUP; } } } @@ -1009,6 +995,8 @@ CLEANUP: free(evr); if (arch) free(arch); + if (deps) + free(deps); return r; } -- 2.39.5