socsvn commit: r254090 - soc2013/mattbw/backend
mattbw at FreeBSD.org
mattbw at FreeBSD.org
Fri Jul 5 02:12:23 UTC 2013
Author: mattbw
Date: Fri Jul 5 02:12:22 2013
New Revision: 254090
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254090
Log:
(fixed?) rearranged and corrected the packageID checks; string_match now works on empty strings as well as null ones so strv comparisons work directly
Modified:
soc2013/mattbw/backend/query.c
soc2013/mattbw/backend/query.h
soc2013/mattbw/backend/utils.c
Modified: soc2013/mattbw/backend/query.c
==============================================================================
--- soc2013/mattbw/backend/query.c Fri Jul 5 01:53:51 2013 (r254089)
+++ soc2013/mattbw/backend/query.c Fri Jul 5 02:12:22 2013 (r254090)
@@ -59,156 +59,27 @@
return (q == NULL ? NULL : q->backend);
}
-/* Converts a package to a PackageID. */
-void
-query_pkg_to_id(struct pkg *pkg, gchar **id_p)
-{
- const gchar **id_bits;
-
- /* Make sure the initial string vector's pointers are all NULL */
- id_bits = g_new0(const gchar *, 4);
-
- /* This is split through an intermediate function so the same code
- * can be used for the ID-checking logic.
- */
- query_pkg_to_id_through(pkg, id_p, id_bits);
-
- /* AFAIK we don't own any of the strings, so we don't use g_strfreev. */
- g_free(id_bits);
-}
-
-/* Gets the PackageKit repository name for the package. */
-static const char *
-get_repo_of(struct pkg *pkg)
-{
- const char *repo;
-
- switch (pkg_type(pkg)) {
- case PKG_FILE:
- repo = "local";
- break;
- case PKG_INSTALLED:
- repo = "installed";
- break;
- case PKG_REMOTE:
- repo = get_repo_of_remote(pkg);
- break;
- default:
- repo = "unknown";
- break;
- }
-
- return repo;
-}
-
/*
- * Gets the PackageKit repository name for the (remote) package.
- *
- * Currently this is actually the pkgng repository ident. This might change.
- *
- * This does not need to be freed (possibly, TODO: check).
+ * Performs a package database query against a PackageID, and then hands the
+ * matching result to an emitter function.
*/
-static const char *
-get_repo_of_remote(struct pkg *pkg)
-{
- const char *repo;
- const char *repo_name;
- struct pkg_repo *repo_struct;
-
- repo = NULL;
-
- /*
- * We can get the repo NAME directly, but we need the repo IDENT.
- * Short of chopping bits of the string off in the assumption that
- * the name is repo-IDENT, we'll have to grab it from the repo
- * structure itself.
- */
- pkg_get(pkg, PKG_REPONAME, &repo_name);
-
- repo_struct = pkg_repo_find_name(repo_name);
- if (repo_struct)
- repo = pkg_repo_ident(repo_struct);
-
- return repo;
-}
-
-static gboolean
-match_id_in_it(struct pkgdb_it *it,
- struct query *q,
- gchar **match_id_p,
- struct pkg **match_pkg_p)
-{
- /* TODO: Filters */
- gboolean found;
- int err;
- int load_flags;
-
- found = FALSE;
- *match_pkg_p = NULL;
- *match_id_p = NULL;
- load_flags = q->load_flags;
-
- for (HASH_FOR(err, pkgdb_it_next, it, match_pkg_p, load_flags)) {
- if (try_id_match(*match_pkg_p, q, match_id_p) == TRUE) {
- found = TRUE;
- break;
- }
- }
-
- return found;
-}
-
-static gboolean
-try_id_match(struct pkg *pkg, struct query *q, char **match_id)
-{
- gboolean cmp;
- const gchar **pkg_id_bits;
-
- pkg_id_bits = g_new0(const gchar *, 4);
- query_pkg_to_id_through(pkg, match_id, pkg_id_bits);
-
-
- /*
- * Succeed if this package's PackageID fields match the original
- * PackageID. Of course, the original ID might have missing fields
- * (NULLs), so we treat a comparison involving one as a success.
- */
- cmp = (string_match(q->name, pkg_id_bits[0]) &&
- string_match(q->version, pkg_id_bits[1]) &&
- string_match(q->arch, pkg_id_bits[2]) &&
- string_match(q->data, pkg_id_bits[3])) ? TRUE : FALSE;
- g_free(pkg_id_bits);
-
- return cmp;
-}
-
-/* Adds a single package to a jobs structure. */
-static int
-jobs_add_pkg(struct pkg_jobs *jobs, match_t type, struct pkg *pkg)
+gboolean
+query_emit_match(struct query *q, emit_ptr emitter)
{
- char *name;
-
- pkg_get(pkg, PKG_NAME, &name);
- return pkg_jobs_add(jobs, type, &name, 1);
-}
+ gboolean success;
+ gchar *match_id;
+ struct pkg *match_pkg;
-/* Converts a package to a PackageID, dumping the intermediate information into
- * the pointed-to string vector (which must have at least 4 places, and they
- * should be NULL).
- */
-static void
-query_pkg_to_id_through(struct pkg *pkg, gchar **id_p, const gchar **strv)
-{
- pkg_get(pkg,
- PKG_NAME, strv,
- PKG_ARCH, strv + 1,
- PKG_VERSION, strv + 2);
+ match_id = NULL;
+ match_pkg = NULL;
+ success = match(q, &match_id, &match_pkg);
+ if (success == TRUE && match_id != NULL && match_pkg != NULL)
+ emitter(match_pkg, match_id, q);
- *(strv + 3) = get_repo_of(pkg);
+ pkg_free(match_pkg);
+ g_free(match_id);
- if (*id_p != NULL)
- g_free(*id_p);
- *id_p = pk_package_id_build(strv[0], strv[1], strv[2], strv[3]);
+ return success;
}
/*
@@ -254,26 +125,71 @@
return no_error_yet;
}
-/*
- * Performs a package database query against a PackageID, and then hands the
- * matching result to an emitter function.
- */
+/* Creates a struct query for the given backend and target ID. */
gboolean
-query_emit_match(struct query *q, emit_ptr emitter)
+query_init(const gchar *id,
+ PkBackend *backend,
+ struct pkgdb *db,
+ int load_flags,
+ struct query **q_p)
{
gboolean success;
- gchar *match_id;
- struct pkg *match_pkg;
+ gboolean loading_files;
+ struct query *q;
- match_id = NULL;
- match_pkg = NULL;
- success = match(q, &match_id, &match_pkg);
- if (success == TRUE && match_id != NULL && match_pkg != NULL)
- emitter(match_pkg, match_id, q);
+ q = *q_p;
+ if (q == NULL)
+ q = g_new0(struct query, 1);
+ else
+ query_free_contents(q);
- pkg_free(match_pkg);
- g_free(match_id);
+ q->backend = backend;
+ q->load_flags = load_flags;
+ q->db = db;
+
+ success = split_id(id,
+ &(q->strv),
+ &(q->name),
+ &(q->version),
+ &(q->arch),
+ &(q->data));
+ if (success == FALSE)
+ pk_backend_error_code(backend,
+ PK_ERROR_ENUM_PACKAGE_ID_INVALID,
+ "invalid package id");
+ /*
+ * Check the repository to make sure it's sane, and populate the repo
+ * type flags in the state for later consumption.
+ */
+ if (success == TRUE) {
+ if (q->data == NULL)
+ q->any_repo = TRUE;
+ else if (strcmp(q->data, "installed") == 0)
+ q->local_repo = TRUE;
+ else if (pkg_repo_find_ident(q->data) == NULL) {
+ pk_backend_error_code(backend,
+ PK_ERROR_ENUM_PACKAGE_ID_INVALID,
+ "no such repository");
+ success = FALSE;
+ }
+ }
+ /*
+ * Stop pkg from catching fire if we try to load files from
+ * non-installed packages.
+ */
+ loading_files = (load_flags & PKG_LOAD_FILES) ? TRUE : FALSE;
+ if (success == TRUE && q->local_repo == FALSE && loading_files) {
+ pk_backend_error_code(backend,
+ PK_ERROR_ENUM_CANNOT_GET_FILELIST,
+ "cannot get files for remote package");
+ success = FALSE;
+ }
+ if (success == FALSE) {
+ query_free(q);
+ q = NULL;
+ }
+ *q_p = q;
return success;
}
@@ -316,6 +232,90 @@
}
+/* Deallocates a struct query and any contents it owns. */
+void
+query_free(struct query *q)
+{
+ if (q != NULL) {
+ query_free_contents(q);
+ g_free(q);
+ }
+}
+
+/* Converts a package to a PackageID. */
+void
+query_pkg_to_id(struct pkg *pkg, gchar **id_p)
+{
+ const gchar **id_bits;
+
+ /* Make sure the initial string vector's pointers are all NULL */
+ id_bits = g_new0(const gchar *, 4);
+
+ /*
+ * This is split through an intermediate function so the same code
+ * can be used for the ID-checking logic.
+ */
+ query_pkg_to_id_through(pkg, id_p, id_bits);
+
+ /* we don't own any of the strings, so we don't use g_strfreev. */
+ g_free(id_bits);
+}
+
+/* Gets the PackageKit repository name for the package. */
+static const char *
+get_repo_of(struct pkg *pkg)
+{
+ const char *repo;
+
+ switch (pkg_type(pkg)) {
+ case PKG_FILE:
+ repo = "local";
+ break;
+ case PKG_INSTALLED:
+ repo = "installed";
+ break;
+ case PKG_REMOTE:
+ repo = get_repo_of_remote(pkg);
+ break;
+ default:
+ repo = "unknown";
+ break;
+ }
+
+ return repo;
+}
+
+/*
+ * Gets the PackageKit repository name for the (remote) package.
+ *
+ * Currently this is actually the pkgng repository ident. This might change.
+ *
+ * This does not need to be freed (possibly, TODO: check).
+ */
+static const char *
+get_repo_of_remote(struct pkg *pkg)
+{
+ const char *repo;
+ const char *repo_name;
+ struct pkg_repo *repo_struct;
+
+ repo = NULL;
+
+ /*
+ * We can get the repo NAME directly, but we need the repo IDENT.
+ * Short of chopping bits of the string off in the assumption that
+ * the name is repo-IDENT, we'll have to grab it from the repo
+ * structure itself.
+ */
+ pkg_get(pkg, PKG_REPONAME, &repo_name);
+
+ repo_struct = pkg_repo_find_name(repo_name);
+ if (repo_struct)
+ repo = pkg_repo_ident(repo_struct);
+
+ return repo;
+}
+
/*
* Performs a package database query against a (potentially partial)
* PackageID, retrieving the matched package and its full PackageID.
@@ -374,81 +374,85 @@
return success;
}
-/* Creates a struct query for the given backend and target ID. */
-gboolean
-query_init(const gchar *id,
- PkBackend *backend,
- struct pkgdb *db,
- int load_flags,
- struct query **q_p)
+static gboolean
+match_id_in_it(struct pkgdb_it *it,
+ struct query *q,
+ gchar **match_id_p,
+ struct pkg **match_pkg_p)
{
- gboolean success;
- gboolean loading_files;
- struct query *q;
+ /* TODO: Filters */
+ int err;
+ int load_flags;
- q = *q_p;
- if (q == NULL)
- q = g_new0(struct query, 1);
- else
- query_free_contents(q);
+ *match_pkg_p = NULL;
+ *match_id_p = NULL;
+ load_flags = q->load_flags;
- q->backend = backend;
- q->load_flags = load_flags;
- q->db = db;
+ for (HASH_FOR(err, pkgdb_it_next, it, match_pkg_p, load_flags))
+ if (try_id_match(*match_pkg_p, q, match_id_p) == TRUE)
+ break;
- success = split_id(id,
- &(q->strv),
- &(q->name),
- &(q->version),
- &(q->arch),
- &(q->data));
- if (success == FALSE)
- pk_backend_error_code(backend,
- PK_ERROR_ENUM_PACKAGE_ID_INVALID,
- "invalid package id");
+ return (err == EPKG_OK && *match_id_p != NULL) ? TRUE : FALSE;
+}
+
+static gboolean
+try_id_match(struct pkg *pkg, struct query *q, char **match_id)
+{
+ gboolean matches;
+ int i;
+ const gchar **pkg_id_bits;
+
+ pkg_id_bits = g_new0(const gchar *, 4);
+ query_pkg_to_id_through(pkg, match_id, pkg_id_bits);
/*
- * Check the repository to make sure it's sane, and populate the repo
- * type flags in the state for later consumption.
- */
- if (success == TRUE) {
- if (q->data == NULL)
- q->any_repo = TRUE;
- else if (strcmp(q->data, "installed") == 0)
- q->local_repo = TRUE;
- else if (pkg_repo_find_ident(q->data) == NULL) {
- pk_backend_error_code(backend,
- PK_ERROR_ENUM_PACKAGE_ID_INVALID,
- "no such repository");
- success = FALSE;
- }
- }
- /*
- * Stop pkg from catching fire if we try to load files from
- * non-installed packages.
+ * Succeed if this package's PackageID fields match the original
+ * PackageID. Of course, the original ID might have missing fields
+ * (NULLs), so we treat a comparison involving one as a success.
+ * This means using our "weak strcmp" instead of normal strcmp or even
+ * g_strcmp0.
*/
- loading_files = (load_flags & PKG_LOAD_FILES) ? TRUE : FALSE;
- if (success == TRUE && q->local_repo == FALSE && loading_files) {
- pk_backend_error_code(backend,
- PK_ERROR_ENUM_CANNOT_GET_FILELIST,
- "cannot get files for remote package");
- success = FALSE;
- }
- if (success == FALSE) {
- query_free(q);
- q = NULL;
- }
- *q_p = q;
- return success;
+ for (matches = TRUE, i = PK_PACKAGE_ID_NAME;
+ matches == TRUE && i <= PK_PACKAGE_ID_DATA;
+ i++)
+ matches = string_match((q->strv)[i], pkg_id_bits[i]);
+
+ g_free(pkg_id_bits);
+ return matches;
}
-void
-query_free(struct query *q)
+/* Adds a single package to a jobs structure. */
+static int
+jobs_add_pkg(struct pkg_jobs *jobs, match_t type, struct pkg *pkg)
{
- if (q != NULL) {
- query_free_contents(q);
- g_free(q);
- }
+ char *name;
+
+ pkg_get(pkg, PKG_NAME, &name);
+ return pkg_jobs_add(jobs, type, &name, 1);
+}
+
+/*
+ * Converts a package to a PackageID, dumping the intermediate information
+ * into the pointed-to string vector (which must have at least 4 places, and
+ * they should be NULL).
+ */
+static void
+query_pkg_to_id_through(struct pkg *pkg, gchar **id_p, const gchar **strv)
+{
+
+ pkg_get(pkg,
+ PKG_NAME, strv + PK_PACKAGE_ID_NAME,
+ PKG_VERSION, strv + PK_PACKAGE_ID_VERSION,
+ PKG_ARCH, strv + PK_PACKAGE_ID_ARCH);
+
+ strv[PK_PACKAGE_ID_DATA] = get_repo_of(pkg);
+
+ if (*id_p != NULL)
+ g_free(*id_p);
+ *id_p = pk_package_id_build(strv[PK_PACKAGE_ID_NAME],
+ strv[PK_PACKAGE_ID_VERSION],
+ strv[PK_PACKAGE_ID_ARCH],
+ strv[PK_PACKAGE_ID_DATA]);
}
static void
Modified: soc2013/mattbw/backend/query.h
==============================================================================
--- soc2013/mattbw/backend/query.h Fri Jul 5 01:53:51 2013 (r254089)
+++ soc2013/mattbw/backend/query.h Fri Jul 5 02:12:22 2013 (r254090)
@@ -31,7 +31,6 @@
typedef void (*job_emit_ptr) (struct pkg_jobs *jobs, struct query *q);
typedef gboolean (*query_body_ptr) (struct query *q);
-
PkBackend *query_backend(struct query *q);
gboolean query_emit_match(struct query *q, emit_ptr emitter);
gboolean query_for_all_ids(PkBackend *backend, int load_flags, query_body_ptr body);
Modified: soc2013/mattbw/backend/utils.c
==============================================================================
--- soc2013/mattbw/backend/utils.c Fri Jul 5 01:53:51 2013 (r254089)
+++ soc2013/mattbw/backend/utils.c Fri Jul 5 02:12:22 2013 (r254090)
@@ -78,7 +78,7 @@
/*
* Checks two strings with strcmp and emits TRUE if they match. If either
- * string is NULL, emit TRUE as well (this is so that missing PackageID
+ * string is NULL or empty, emit TRUE as well (this is so that missing PackageID
* elements trigger matches).
*/
gboolean
@@ -88,6 +88,8 @@
if (left == NULL || right == NULL)
result = TRUE;
+ else if (*left == '\0' || *right == '\0')
+ result = TRUE;
else
result = (strcmp(left, right) == 0 ? TRUE : FALSE);
More information about the svn-soc-all
mailing list