Date: Sun, 25 Aug 2013 11:30:48 GMT From: mattbw@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r256499 - in soc2013/mattbw/backend: . actions query Message-ID: <201308251130.r7PBUmCU009462@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mattbw Date: Sun Aug 25 11:30:48 2013 New Revision: 256499 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=256499 Log: (*STILL* broken) Dump of work to query code. This is not a very well-structured commit as it contains lots of broken changes to lots of things, but I thought that it'd be better to have at least some record of the story so far in the version control. Currently working on the long overdue query overhaul with an eye to implementing GetDepends and GetRequires later today. Added: soc2013/mattbw/backend/query/find.c soc2013/mattbw/backend/query/packages.c soc2013/mattbw/backend/query/packages.h soc2013/mattbw/backend/query/split_id.c soc2013/mattbw/backend/query/traverse.c Modified: soc2013/mattbw/backend/Makefile soc2013/mattbw/backend/actions/resolve.c soc2013/mattbw/backend/query.h soc2013/mattbw/backend/query/core.c soc2013/mattbw/backend/query/do.c soc2013/mattbw/backend/query/match.c Modified: soc2013/mattbw/backend/Makefile ============================================================================== --- soc2013/mattbw/backend/Makefile Sun Aug 25 10:57:48 2013 (r256498) +++ soc2013/mattbw/backend/Makefile Sun Aug 25 11:30:48 2013 (r256499) @@ -64,6 +64,14 @@ PKGS= pkg gio-2.0 gio-unix-2.0 +# ATF test flags +TESTSRCS= \ + query/id_test.c + +TESTCFLAGS= `pkgconf --cflags atf-c` +TESTLDFLAGS= `pkgconf --libs-only-L --libs-only-other atf-c` +TESTLIBS= `pkgconf --libs-only-l atf-c` + # 0.6.* versions of PackageKit do not export pkgconf information, so here's a # bodge. USE_PK_PKGCONF= 0 # Set to 1 if using recent PackageKit @@ -82,4 +90,11 @@ group_map.c: groups group_map.awk sort groups | awk -f group_map.awk > group_map.c +# TODO: Find a more BSD way of doing this +query/id_test: query/id_test.o query/id.o + ${CC} ${LDFLAGS} ${TESTLDFLAGS} -o ${.TARGET} ${.ALLSRC} ${LIBS} ${TESTLIBS} + +query/id_test.o: query/id_test.c + ${CC} ${CFLAGS} ${TESTCFLAGS} -o query/id_test.o -c query/id_test.c + .include <bsd.lib.mk> Modified: soc2013/mattbw/backend/actions/resolve.c ============================================================================== --- soc2013/mattbw/backend/actions/resolve.c Sun Aug 25 10:57:48 2013 (r256498) +++ soc2013/mattbw/backend/actions/resolve.c Sun Aug 25 11:30:48 2013 (r256499) @@ -28,6 +28,7 @@ #include "../actions.h" /* resolve_thread prototype */ static bool emit(struct pkg *pkg, const gchar *id, struct query *q); +static bool query_with_db(struct pkgdb *db, PkBackend *backend); /* * Resolves a package identifier, which may be a full PackageID or a package @@ -36,22 +37,63 @@ gboolean resolve_thread(PkBackend *backend) { - gboolean success; - struct query_source s; - struct query_target t; + bool success; + struct pkgdb *db; + assert(backend != NULL); + + db = db_open_remote(backend); + if (db != NULL) { + success = query_with_db(db, backend); + + db_close(&db); + } +/* s.type = QUERY_BACKEND_MIXED; t.load_flags = PKG_LOAD_BASIC; t.f = emit; t.error_if_not_found = true; success = query_do(backend, &s, &t); +*/ (void)pk_backend_finished(backend); return success ? TRUE : FALSE; } static bool +query_with_db(struct pkgdb *db, PkBackend *backend) +{ + bool success; + guint count; + struct query_id *query_ids; + gchar **names; + struct pkg **packages; + + assert(db != NULL); + assert(backend != NULL); + + success = false; + + names = pk_backend_get_strv("package_ids"); + assert(names != NULL); + count = g_strv_length(names); + + query_ids = query_id_array_from_names(names, count); + if (query_ids != NULL) { + packages = query_match_ids(query_ids, count, db, + PKG_LOAD_BASIC); + } + + if (packages != NULL) { + success = emit_packages(backend, db, emit, packages, count); + query_free_packages(packages, count); + } + + return success; +} + +static bool emit(struct pkg *pkg, const gchar *id, struct query *q) { PkBackend *backend; Modified: soc2013/mattbw/backend/query.h ============================================================================== --- soc2013/mattbw/backend/query.h Sun Aug 25 10:57:48 2013 (r256498) +++ soc2013/mattbw/backend/query.h Sun Aug 25 11:30:48 2013 (r256499) @@ -25,6 +25,6 @@ #include "query/do.h" /* query_do_... */ #include "query/match.h" /* query_match_... */ -#include "query/depends.h" /* query_depends_... */ +#include "query/id.h" /* query_id_... */ #endif /* !_PKGNG_BACKEND_QUERY_H_ */ Modified: soc2013/mattbw/backend/query/core.c ============================================================================== --- soc2013/mattbw/backend/query/core.c Sun Aug 25 10:57:48 2013 (r256498) +++ soc2013/mattbw/backend/query/core.c Sun Aug 25 11:30:48 2013 (r256499) @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #include <assert.h> /* assert */ #include <stdbool.h> #include <string.h> @@ -30,19 +29,6 @@ #include "../pkgutils.h" /* pkgutils_... */ #include "core.h" /* Prototypes */ - -struct query { - PkBackend *backend; - struct pkgdb *db; - - gchar **id_strv; - - enum repo_type rtype; - - struct query_source *s; - struct query_target *t; -}; - typedef struct pkgdb_it * (*query_func_ptr) (struct query *q); static bool can_remote_iterate(struct query *q); @@ -56,153 +42,6 @@ static struct pkgdb_it *remote_query(struct query *q); -struct query_split_id { - gchar *namever; - gchar *arch; - gchar *repo; -} - -/* Given an array of PackageIDs, returns an array of matching packages. - * - * Returns NULL if any of the packages did not match. - */ -struct pkg ** -query_by_ids(PkBackend *backend, unsigned int load_flags, - gchar **package_ids, unsigned int package_count) -{ - struct pkg **packages; - struct query_split_id **package_split_ids; - - assert(backend != NULL); - assert(package_ids != NULL); - - packages = NULL; - - package_split_ids = split_package_ids(package_ids, count); - if (package_split_ids != NULL) { - packages = query_by_split_ids(backend, load_flags, - package_split_ids, package_count); - free_split_package_ids(&package_split_ids); - } - - return packages; -} - - -struct pkg ** -query_by_names(PkBackend *backend, unsigned int load_flags, - const char **package_names, unsigned int package_count) -{ - struct pkg **packages; - struct query_split_id **package_split_ids; - - assert(backend != NULL); - assert(package_names != NULL); - - packages = NULL; - - package_split_ids = names_to_split_ids(package_names, count); - if (package_split_ids != NULL) { - packages = query_by_split_ids(backend, load_flags, - package_split_ids, package_count); - free_split_package_ids(&package_split_ids); - } - - return packages; -} - -struct pkg ** -query_by_split_ids(PkBackend *backend, unsigned int load_flags, - struct query_split_id *package_split_ids, unsigned int package_count) -{ - struct pkg **packages; - - packages = -} - -/* Converts an array of PackageIDs to split IDs. */ -static struct query_split_id * -split_package_ids(gchar **package_ids, unsigned int package_count) -{ - unsigned int i; - struct query_split_id *split_ids; - - split_ids = alloc_split_ids(package_count); - for () - - return split_ids; -} - -/* Converts an array of names (or name-version strings) to split IDs. */ -static struct query_split_id * -names_to_split(gchar **package_names, unsigned int package_count) -{ - unsigned int i; - gchar *split_package_id; - struct query_split_id *split_ids; - - split_ids = alloc_split_ids(package_count); - if (split_ids != NULL) { - bool error; - unsigned int i; - - error = false; - for (i = 0; i < package_count; i++) { - error = name_to_split(package_names[i], split_ids + i); - if (error) { - free_split_ids(&split_ids, package_count); - break; - } - } - } - - return split_ids; -} - -bool -name_to_split(const char *name, struct query_split_id *split_id) -{ - bool success; - - assert(name != NULL); - assert(split_id != NULL); - - split_ids->namever = strdup(name); - split_ids->arch = NULL; - split_ids->repo = NULL; - - return (split_ids->namever == NULL); -} - -bool -package_id_to_split(gchar *package_id, struct query_split_id *split_id) -{ - bool success; - gchar **split_package_id; - - assert(name != NULL); - assert(split_id != NULL); - - split_package_id = pk_package_id_split(package_id); - if (split_package_id == NULL) { - error = true; - } else if () { - - split_ids[i].namever = join_namever(name, version); - g_strfreev(split_package_id); - } - } - } - - return split_ids; -} - -static struct query_split_id * -alloc_split_ids(unsigned int count) -{ - return calloc(package_count, sizeof(struct query_split_id)); -} - /* * Returns the backend stored inside the given query. */ @@ -470,111 +309,3 @@ return match_id; } - -/* - * Tries to find a query-matching package in a database iterator. Returns the - * package if one matches, or NULL; if match_id_p is non-null, its full - * PackageID will be emitted there. - */ -static struct pkg * -match_iterator(struct pkgdb_it *it, struct query *q, gchar **match_id_p) -{ - gchar *match_id; - struct pkg *pkg; - - assert(it != NULL); - assert(q != NULL); - - match_id = NULL; - pkg = NULL; - while (pkgdb_it_next(it, &pkg, q->t->load_flags) == EPKG_OK) { - match_id = match_pkg(pkg, q); - /* Did it match? */ - if (match_id != NULL) - break; - } - - if (match_id_p != NULL) { - g_free(*match_id_p); - *match_id_p = match_id; - } else - g_free(match_id); - - return pkg; -} - -static struct pkgdb_it * -local_query(struct query *q) -{ - - return pkgdb_query(q->db, q->id_strv[PK_PACKAGE_ID_NAME], MATCH_EXACT); -} - -static struct pkgdb_it * -remote_query(struct query *q) -{ - struct pkgdb_it *iterator; - - iterator = pkgdb_rquery(q->db, q->id_strv[PK_PACKAGE_ID_NAME], - MATCH_EXACT, query_repo(q)); - - /* - * Make sure we can use this iterator. (We only check now so that - * the case of there being no remote matches is properly handled.) - */ - if (iterator != NULL && !can_remote_iterate(q)) { - pkgdb_it_free(iterator); - iterator = NULL; - } - - return iterator; -} - -/* Unpacks a query source into name/version/arch/data pointers. */ -static gchar ** -init_unpack_source(PkBackend *backend, struct query_source *s) -{ - gchar **id_strv; - - assert(backend != NULL); - assert(s != NULL); - - id_strv = NULL; - if (s->type == QUERY_SINGLE_NAME) { - id_strv = make_fake_id_split(s->single); - } else if (s->type == QUERY_SINGLE_ID) { - id_strv = pk_package_id_split(s->single); - if (id_strv == NULL) - ERR(backend, - PK_ERROR_ENUM_PACKAGE_ID_INVALID, - "invalid package id"); - } else { - ERR(backend, - PK_ERROR_ENUM_INTERNAL_ERROR, - "init_unpack_source given silly source type"); - } - - return id_strv; -} - -static gchar ** -make_fake_id_split(const char *name) -{ - gchar **id_strv; - - assert(name != NULL); - - /* - * Make a snake-oil ID vector; we won't be doing rigid - * checking against it so it doesn't matter that the version - * might be in the name column etc. - */ - id_strv = g_malloc0_n(5, (gsize) sizeof(gchar *)); - - id_strv[PK_PACKAGE_ID_NAME] = g_strdup(name); - id_strv[PK_PACKAGE_ID_VERSION] = g_strdup(""); - id_strv[PK_PACKAGE_ID_ARCH] = g_strdup(""); - id_strv[PK_PACKAGE_ID_DATA] = g_strdup(""); - - return id_strv; -} Modified: soc2013/mattbw/backend/query/do.c ============================================================================== --- soc2013/mattbw/backend/query/do.c Sun Aug 25 10:57:48 2013 (r256498) +++ soc2013/mattbw/backend/query/do.c Sun Aug 25 11:30:48 2013 (r256499) @@ -31,93 +31,88 @@ #include "do.h" /* query_do_... */ #include "core.h" /* query_... */ -static bool do_single(PkBackend *backend, struct pkgdb *db, struct query_source *s, struct query_target *t); -static bool do_backend_ids(PkBackend *backend, struct pkgdb *db, struct query_source *s, struct query_target *t); - +static bool emit_packages(PkBackend *backend, struct pkgdb *db, emit_ptr emitter, struct pkg *packages, unsigned int count); +static bool query_with_db(struct pkgdb *db, PkBackend *backend, unsigned int load_flags, emit_ptr emitter); /* - * Given information about a query's source and target, creates and runs it. + * Runs a query over the PackageIDs selected in the backend that sends the + * first match to an emitting function. + * + * This is a wrapper over several lower level query functions. */ bool -query_do(PkBackend *backend, struct query_source *s, struct query_target *t) +query_do_from_backend(PkBackend *backend, unsigned int load_flags, + emit_ptr emitter) { bool success; struct pkgdb *db; + assert(backend != NULL); + assert(emitter != NULL); + success = false; db = db_open_remote(backend); if (db != NULL) { - switch (s->type) { - case QUERY_BACKEND_IDS: - case QUERY_BACKEND_MIXED: - success = do_backend_ids(backend, db, s, t); - break; - case QUERY_SINGLE_NAME: - case QUERY_SINGLE_ID: - success = do_single(backend, db, s, t); - break; - } + success = query_with_db(db, backend, load_flags, emitter); - pkgdb_close(db); + db_close(&db); } - return success; } -/* - * Performs a query whose source is the set of PackageIDs stored in the - * backend. - */ static bool -do_backend_ids(PkBackend *backend, struct pkgdb *db, struct query_source *s, - struct query_target *t) +query_with_db(struct pkgdb *db, PkBackend *backend, unsigned int load_flags, + emit_ptr emitter) { bool success; - gchar **package_ids; - struct query_source new_s; - - /* Cheat by running a separate single-ID query for each ID. */ - - success = true; - package_ids = pk_backend_get_strv(backend, "package_ids"); - - new_s.total = g_strv_length(package_ids); + guint count; + struct pkg **packages; + struct query_id *query_ids; + gchar **package_ids; + + assert(backend != NULL); + assert(db != NULL); + assert(emitter != NULL); - for (new_s.position = 0; - new_s.position < new_s.total && success; - (new_s.position)++) { - if (!success) { - break; - } - - new_s.single = package_ids[new_s.position]; + success = false; + packages = NULL; - /* Treat non-PackageIDs as pkgng package names, if allowed */ - if (s->type == QUERY_BACKEND_IDS || - pk_package_id_check(new_s.single) == TRUE) - new_s.type = QUERY_SINGLE_ID; - else - new_s.type = QUERY_SINGLE_NAME; + package_ids = pk_backend_get_strv("package_ids"); + assert(package_ids != NULL); + count = g_strv_length(package_ids); + + query_ids = query_id_array_from_package_ids(package_ids, count); + if (query_ids != NULL) { + packages = query_match_ids(query_ids, count, db, load_flags); + } - success = do_single(backend, db, &new_s, t); + if (packages != NULL) { + success = emit_packages(backend, db, emitter, packages, count); + query_free_packages(packages, count); } return success; } -/* - * Performs a query whose source is a single PackageID or name. - */ static bool -do_single(PkBackend *backend, struct pkgdb *db, struct query_source *s, - struct query_target *t) +emit_packages(PkBackend *backend, struct pkgdb *db, emit_ptr emitter, + struct pkg *packages, unsigned int count) { bool success; - struct query *q; + unsigned int i; + + assert(backend != NULL); + assert(db != NULL); + assert(emitter != NULL); + assert(packages != NULL); - q = query_init(backend, db, s, t); - success = q == NULL ? false : query_run(q); - query_free(&q); + success = true; + for (i = 0; i < count; i++) { + success = emitter(backend, db, packages + i); + if (success = false) { + break; + } + } return success; } Added: soc2013/mattbw/backend/query/find.c ============================================================================== Modified: soc2013/mattbw/backend/query/match.c ============================================================================== --- soc2013/mattbw/backend/query/match.c Sun Aug 25 10:57:48 2013 (r256498) +++ soc2013/mattbw/backend/query/match.c Sun Aug 25 11:30:48 2013 (r256499) @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #include <stdbool.h> #include "../pk-backend.h" @@ -25,89 +24,186 @@ #include "do.h" /* query_do... */ #include "match.h" /* query_match_... */ +typedef struct pkgdb_it * (*query_func_ptr) (struct query_id *id, struct pkgdb *db); + +static struct pkg *match_iterator(struct pkgdb_it *it, struct query *q, gchar **match_id_p); +static struct pkg *query_match_from(query_func_ptr function, struct pkgdb *db, struct query_id *query_id); +static struct pkgdb_it *local_query(struct query_id *id, struct pkgdb *db); +static struct pkgdb_it *remote_query(struct query_id *id, struct pkgdb *db); + +/* Attempts to match a set of QueryIDs into packages. */ +struct pkg ** +query_match_ids(struct query_id *query_ids, unsigned int count, + struct pkgdb *db, int load_flags) +{ + bool success; + unsigned int i; + struct pkg *packages; + + assert(query_ids != NULL); + assert(db != NULL); + + packages = query_packages_array_alloc(count); + success = (packages != NULL); + + for (i = 0; i < count; i++) { + if (!success) { + /* + * Catch both the packages being NULL and any failures + * below. + */ + break; + } + + success = query_match_id(packages + i, query_ids + i, + db, load_flags); + } -static bool emit_packages(PkBackend *backend, struct pkgdb *db, emit_ptr emitter, struct pkg *packages, unsigned int count); -static bool query_with_db(struct pkgdb *db, PkBackend *backend, unsigned int load_flags, emit_ptr emitter); + if (!success) { + package_array_free(&packages, count); + } + return packages; +} /* - * Runs a query over the PackageIDs selected in the backend that sends the - * first match to an emitting function. + * Takes a QueryID and attempts to retrieve its corresponding package. */ bool -query_match_id_to_emitter(PkBackend *backend, unsigned int load_flags, - emit_ptr emitter) +query_match_id(struct pkg **package_p, struct query_id *query_id, + struct pkgdb *db, int load_flags) { bool success; + bool try_local; + bool try_remote; - assert(backend != NULL); - assert(emitter != NULL); + assert(package_p != NULL); + assert(*package_p == NULL); + assert(db != NULL); success = false; - db = db_open_remote(backend); - if (db != NULL) { - success = query_with_db(db, backend, load_flags, emitter); + /* + * If we're not given a specific repository in the PackageID, we want + * to try searching locally first and then remotely; otherwise which + * database we query depends on the repository we have been given. + */ + repo_type = type_of_repo_name(query_id->repo); + try_local = (repo_type != REPO_REMOTE); + try_remote = (repo_type != REPO_LOCAL); - db_close(&db); + if (try_local) { + *package_p = query_match_from(query_find_local, db, query_id); + } + if (*package_p == NULL && try_remote) { + *package_p = query_match_from(query_find_remote, db, query_id); } - return success; + + return (package_p != NULL); } -static bool -query_with_db(struct pkgdb *db, PkBackend *backend, unsigned int load_flags, - emit_ptr emitter) +/* Takes a querying function and attempts to find a QueryID using it. */ +static struct pkg * +query_match_from(query_func_ptr function, struct pkgdb *db, + struct query_id *query_id) { - bool success; - guint count; - struct pkg *packages; - struct pkgdb *db; - struct query_id *query_ids; - gchar **package_ids; + struct pkg *result; + struct pkgdb_it *iterator; - assert(backend != NULL); + assert(function != NULL); assert(db != NULL); - assert(emitter != NULL); + assert(query_id != NULL); - success = false; - packages = NULL; + result = NULL; + + iterator = function(db, query_id); + if (iterator != NULL) { + result = match_iterator(iterator, q, match_id_p); + pkgdb_it_free(iterator); + } + + return result; +} - package_ids = pk_backend_get_strv("package_ids"); - assert(package_ids != NULL); - count = g_strv_length(package_ids); +/* + * Tries to find a query-matching package in a database iterator. Returns the + * package if one matches, or NULL; if match_id_p is non-null, its full + * PackageID will be emitted there. + */ +static struct pkg * +match_iterator(struct pkgdb_it *it, struct query *q, gchar **match_id_p) +{ + gchar *match_id; + struct pkg *pkg; - query_ids = query_id_array_from_package_ids(package_ids, count); - if (query_ids != NULL) { - packages = query_match_ids(query_ids, count, load_flags); + assert(it != NULL); + assert(q != NULL); + + match_id = NULL; + pkg = NULL; + while (pkgdb_it_next(it, &pkg, q->t->load_flags) == EPKG_OK) { + match_id = match_pkg(pkg, q); + /* Did it match? */ + if (match_id != NULL) + break; } - if (packages != NULL) { - success = emit_packages(backend, db, emitter, packages, count); - query_free_packages(packages, count); + if (match_id_p != NULL) { + g_free(*match_id_p); + *match_id_p = match_id; + } else + g_free(match_id); + + return pkg; +} + +static struct pkgdb_it * +local_query(struct query_id *id, struct pkgdb *db) +{ + + return pkgdb_query(db, q->id_strv[PK_PACKAGE_ID_NAME], MATCH_EXACT); +} + +static struct pkgdb_it * +remote_query(struct query_id *id, struct pkgdb *db) +{ + struct pkgdb_it *iterator; + + iterator = pkgdb_rquery(db, q->id_strv[PK_PACKAGE_ID_NAME], + MATCH_EXACT, query_repo(q)); + + /* + * Make sure we can use this iterator. (We only check now so that + * the case of there being no remote matches is properly handled.) + */ + if (iterator != NULL && !can_remote_iterate(query_id)) { + pkgdb_it_free(iterator); + iterator = NULL; } - return success; + return iterator; } -static bool -emit_packages(PkBackend *backend, struct pkgdb *db, emit_ptr emitter, - struct pkg *packages, unsigned int count) +static struct pkg ** +query_packages_array_alloc(unsigned int package_count) +{ + + return calloc(package_count, sizeof(struct pkg *)) +} + +static void +query_packages_array_free(struct pkg **packages_p, unsigned int package_count) { - bool success; unsigned int i; - assert(backend != NULL); - assert(db != NULL); - assert(emitter != NULL); - assert(packages != NULL); + assert(packages_p != NULL); - success = true; - for (i = 0; i < count; i++) { - success = emitter(backend, packages + i); - if (success = false) { - break; + if (*packages_p != NULL) { + for (i = 0; i < package_count; i++) { + pkg_free((*packages_p)[i]); } - } - return success; + free(*packages_p); + *packages_p = NULL; + } } Added: soc2013/mattbw/backend/query/packages.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/mattbw/backend/query/packages.c Sun Aug 25 11:30:48 2013 (r256499) @@ -0,0 +1,50 @@ +/*- + * Copyright (C) 2013 Matt Windsor <mattbw@FreeBSD.org> + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Functions for dealing with arrays of package pointers. */ +#include "pkg.h" /* struct pkg, pkg_free */ + +#include "packages.h" /* query_packages_... */ + +/* Allocates an array of size 'package_count' of null pointers to packages. */ +struct pkg ** +query_packages_array_alloc(unsigned int package_count) +{ + + return calloc(package_count, sizeof(struct pkg *)) +} + +/* Frees an array of size 'package_count' of pointers to packages. */ +void +query_packages_array_free(struct pkg **packages_p, unsigned int package_count) +{ + unsigned int i; + + assert(packages_p != NULL); + + if (*packages_p != NULL) { + for (i = 0; i < package_count; i++) { + pkg_free((*packages_p)[i]); + } + + free(*packages_p); + *packages_p = NULL; + } +} Added: soc2013/mattbw/backend/query/packages.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/mattbw/backend/query/packages.h Sun Aug 25 11:30:48 2013 (r256499) @@ -0,0 +1,29 @@ +/*- + * Copyright (C) 2013 Matt Windsor <mattbw@FreeBSD.org> + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _PKGNG_BACKEND_QUERY_PACKAGES_H_ +#define _PKGNG_BACKEND_QUERY_PACKAGES_H_ + +#include "pkg.h" + +struct pkg **query_packages_array_alloc(unsigned int package_count); +void query_packages_array_free(struct pkg **packages_p, unsigned int package_count); + +#endif /* !_PKGNG_BACKEND_QUERY_PACKAGES_H_ */ Added: soc2013/mattbw/backend/query/split_id.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/mattbw/backend/query/split_id.c Sun Aug 25 11:30:48 2013 (r256499) @@ -0,0 +1,38 @@ +/* Converts an array of PackageIDs to split IDs. */ +static struct query_split_id * +split_package_ids(gchar **package_ids, unsigned int package_count) +{ + unsigned int i; + struct query_split_id *split_ids; + + split_ids = alloc_split_ids(package_count); + for () + + return split_ids; +} + +/* Converts an array of names (or name-version strings) to split IDs. */ +static struct query_split_id * +names_to_split(gchar **package_names, unsigned int package_count) +{ + unsigned int i; + gchar *split_package_id; + struct query_split_id *split_ids; + + split_ids = alloc_split_ids(package_count); + if (split_ids != NULL) { + bool error; + unsigned int i; + + error = false; + for (i = 0; i < package_count; i++) { + error = name_to_split(package_names[i], split_ids + i); + if (error) { + free_split_ids(&split_ids, package_count); + break; + } + } + } + + return split_ids; +} Added: soc2013/mattbw/backend/query/traverse.c ==============================================================================
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308251130.r7PBUmCU009462>