Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
pkgdb: can access reverse deps
Philippe Pepiot committed 15 years ago
commit 9cd1d20238fdaba4cf3e641d80a029b5c7c9ee0e
parent 84aff721f85ba39854e60cc992c01da1611eb24c
5 files changed +100 -29
modified libpkg/pkg.h
@@ -15,11 +15,13 @@ struct pkg {
	const char *comment;
	const char *desc;
	struct pkg **deps; /* null-terminated */
+
	struct pkg **rdeps; /* null-terminated */
	unsigned char errors; /* PKGERR_* */
	size_t idx; /* index on pkgdb */
};

#define PKGDB_INIT_DEPS (1<<0)
+
#define PKGDB_INIT_RDEPS (1<<1)

struct pkgdb {
	struct pkg **pkgs; /* null-terminated */
modified libpkg/pkgdb.c
@@ -30,14 +30,25 @@ void
pkgdb_free(struct pkgdb *db)
{
	int fd;
-
	struct pkg *pkg;
+
	struct pkg *pkg, **deps;

	fd = cdb_fileno(&db->db);
	cdb_free(&db->db);
	close(fd);

-
	PKGDB_FOREACH(pkg, db)
-
		pkg_free(db, pkg);
+
	PKGDB_FOREACH(pkg, db) {
+
		if (db->flags & PKGDB_INIT_DEPS) {
+
			for (deps = pkg->deps; *deps != NULL; deps++)
+
				free(*deps);
+
			free(pkg->deps);
+
		}
+
		if (db->flags & PKGDB_INIT_RDEPS) {
+
			for (deps = pkg->rdeps; *deps != NULL; deps++)
+
				free(*deps);
+
			free(pkg->rdeps);
+
		}
+
		free(pkg);
+
	}

	free(db->pkgs);
}
modified libpkg/pkgdb_cache.c
@@ -179,6 +179,48 @@ pkg_get_deps(struct cdb *db, struct pkg *pkg)
	}
}

+
/* populate rdeps on package */
+
static void
+
pkg_get_rdeps(struct cdb *db, struct pkg *pkg, size_t count)
+
{
+
	size_t i, j;
+
	struct pkg *p, **deps;
+

+
	if (db == NULL || pkg == NULL)
+
		return;
+

+
	pkg->rdeps = calloc(count+1, sizeof(struct pkg *));
+

+
	for (i = 0, j = 0; i < count; i++) {
+

+
		if ((p = pkg_idx_query(db, i)) == NULL)
+
			continue;
+

+
		pkg_get_deps(db, p);
+

+
		for (deps = p->deps; *deps != NULL; deps++) {
+
			if (!((*deps)->errors & PKGERR_NOT_INSTALLED)
+
					&& strcmp((*deps)->name, pkg->name) == 0) {
+
				pkg->rdeps[j] = p;
+
				break;
+
			}
+
		}
+

+
		/* free deps */
+
		for (deps = p->deps; *deps != NULL; deps++)
+
			free(*deps);
+
		free(p->deps);
+

+
		if (pkg->rdeps[j] == p)
+
			j++;
+
		else
+
			free(p);
+
	}
+
	pkg->rdeps = realloc(pkg->rdeps, (j+1) * sizeof(struct pkg *));
+
	pkg->rdeps[j] = NULL;
+
	return;
+
}
+

/* open the pkgdb.cache */
static int
pkgdb_open(struct cdb *db, int flags)
@@ -369,13 +411,34 @@ pkg_cmp(void const *a, void const *b)
	return (strcmp((*pa)->name, (*pb)->name));
}

+
static int
+
pkg_match(struct pkg *pkg, const regex_t *re, const char *pattern, match_t match)
+
{
+
	int matched = 1;
+
	switch (match) {
+
		case MATCH_ALL:
+
			matched = 0;
+
			break;
+
		case MATCH_EXACT:
+
			matched = strcmp(pkg->name_version, pattern);
+
			break;
+
		case MATCH_GLOB:
+
			matched = fnmatch(pattern, pkg->name_version, 0);
+
			break;
+
		case MATCH_REGEX:
+
		case MATCH_EREGEX:
+
			matched = regexec(re, pkg->name_version, 0, NULL, 0);
+
			break;
+
	}
+
	return (matched);
+
}
+

void
pkgdb_cache_init(struct pkgdb *db, const char *pattern, match_t match, unsigned char flags)
{
	size_t count, i;
	struct pkg *pkg;
	regex_t re;
-
	int matched;

	db->count = 0;
	db->flags = flags;
@@ -414,26 +477,11 @@ pkgdb_cache_init(struct pkgdb *db, const char *pattern, match_t match, unsigned
		if ((pkg = pkg_idx_query(&db->db, i)) == NULL)
			continue;

-
		matched = 1; /* non zero is false */
-
		switch (match) {
-
			case MATCH_ALL:
-
				matched = 0;
-
				break;
-
			case MATCH_EXACT:
-
				matched = strcmp(pkg->name_version, pattern);
-
				break;
-
			case MATCH_GLOB:
-
				matched = fnmatch(pattern, pkg->name_version, 0);
-
				break;
-
			case MATCH_REGEX:
-
			case MATCH_EREGEX:
-
				matched = regexec(&re, pkg->name_version, 0, NULL, 0);
-
				break;
-
		}
-

-
		if (matched == 0) {
+
		if (pkg_match(pkg, &re, pattern, match) == 0) {
			if (db->flags & PKGDB_INIT_DEPS)
				pkg_get_deps(&db->db, pkg);
+
			if (db->flags & PKGDB_INIT_RDEPS)
+
				pkg_get_rdeps(&db->db, pkg, count);
			db->pkgs[db->count++] = pkg;
		}
		else
modified pkg/info.c
@@ -30,6 +30,7 @@ cmd_info(int argc, char **argv)
	match_t match = MATCH_EXACT;
	char ch;

+
	/* TODO: exclusive opts ? */
	while ((ch = getopt(argc, argv, "gxXdD")) != -1) {
		switch (ch) {
			case 'g':
@@ -43,7 +44,11 @@ cmd_info(int argc, char **argv)
				break;
			case 'd':
				flags |= PKGDB_INIT_DEPS;
-
				opt |= INFO_PRINT_DEPEND_LIST;
+
				opt |= INFO_PRINT_DEP;
+
				break;
+
			case 'D':
+
				flags |= PKGDB_INIT_RDEPS;
+
				opt |= INFO_PRINT_RDEP;
				break;
		}
	}
@@ -57,12 +62,16 @@ cmd_info(int argc, char **argv)

	PKGDB_FOREACH(pkg, &db) {

-
		if (opt & INFO_PRINT_DEPEND_LIST) {
-
			printf("Informations for %s\n\n", pkg->name_version);
-
			printf("Depends on:\n");
-
			for (deps = pkg->deps; *deps; deps++)
+
		if (opt & INFO_PRINT_DEP) {
+
			printf("%s depends on:\n", pkg->name_version);
+
			for (deps = pkg->deps; *deps != NULL; deps++)
+
				printf("%s\n", (*deps)->name_version);
+
		}
+

+
		else if (opt & INFO_PRINT_RDEP) {
+
			printf("%s is required for:\n", pkg->name_version);
+
			for (deps = pkg->rdeps; *deps != NULL; deps++)
				printf("%s\n", (*deps)->name_version);
-
			printf("\n\n");
		}

		else if (pkgdb_count(&db) == 1) {
modified pkg/info.h
@@ -1,7 +1,8 @@
#ifndef _INFO_H
#define _INFO_H

-
#define INFO_PRINT_DEPEND_LIST (1<<0)
+
#define INFO_PRINT_DEP (1<<0)
+
#define INFO_PRINT_RDEP (1<<1)

int cmd_info(int argc, char **argv);
#endif