]> git.ipfire.org Git - pakfire.git/commitdiff
packages: Unify the dependency functions
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 26 Oct 2022 17:53:37 +0000 (17:53 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 26 Oct 2022 17:53:37 +0000 (17:53 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/package.c
src/libpakfire/archive.c
src/libpakfire/build.c
src/libpakfire/db.c
src/libpakfire/dependencies.c
src/libpakfire/include/pakfire/dependencies.h
src/libpakfire/include/pakfire/package.h
src/libpakfire/libpakfire.sym
src/libpakfire/package.c
src/libpakfire/packager.c
src/libpakfire/parser.c

index 69496ccc6b3b922542d1105b30396c0f7f085b5d..bd4ae159a8de5f74a3feb445819d26d78dc2cd4e 100644 (file)
@@ -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);
 
index c1c5e9530d29f32cc1e5a1556baeef9cb479f40d..195debbc205736105e650fcd3656022c3c330989 100644 (file)
@@ -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;
                }
        }
 
index 15ceae51acd1a88d27b1e53efed47511b11a438e..9dce793b872d17683bb43aabac36d8e875342b20 100644 (file)
@@ -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;
index 2b7fa90860d2ab6bad1367ea3779f343786f4060..cc0728949984e7c8779ffc65fe4b9b0899eba9bf 100644 (file)
@@ -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;
                }
        }
 
index a2b243c95d3cf90995cba7e2f3233e80498f9d6c..0e08ee743832288dbbaad3b0d7333b142d2f1fb9 100644 (file)
 #include <pakfire/string.h>
 #include <pakfire/util.h>
 
+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;
 }
index 01bbeb0f767ddc60b1eadceddc21d1cb4b1d9617..baa5e91d66a82147698c0e6f5233af16144b3bef 100644 (file)
 #ifndef PAKFIRE_DEPENDENCIES_H
 #define PAKFIRE_DEPENDENCIES_H
 
+#ifdef PAKFIRE_PRIVATE
+
 #include <solv/pool.h>
 
 #include <pakfire/package.h>
 #include <pakfire/pakfire.h>
 
+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 */
index 71086d3bf081124ec46cc40a6cbd8748e529868d..9f2f3f8db8b7d642668a3e21f1d382174d8ade5c 100644 (file)
@@ -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);
index 00ff171d122566a10dfb565f30a0e3cf947e791f..1648f50210dc3e0e6293c49cca6f6ba49f1d7c93 100644 (file)
@@ -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;
index c24aeadd756342840db886718c81b7a8dc75896b..cf7fe8b857d3c8af9d183f6a9d58e8745235f516 100644 (file)
@@ -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;
 
index 71f10b40dcd0994c521959ad9dd6837ef503e317..8e3a8faeb713487c0aa993653fcf54948a1bef2c 100644 (file)
@@ -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);
index e861c08ecd6f3d363a9019643beb1639c2087e28..e2577bb1d9fb8cf7996b0e241f4fc29130e7880e 100644 (file)
@@ -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;
 }