Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Use dependencies formula in solver
Vsevolod Stakhov committed 9 years ago
commit b0ea8d3da704d694c6870fb88ccaf5ecd62b0600
parent 1df5d36
5 files changed +88 -39
modified libpkg/pkg.c
@@ -3,8 +3,9 @@
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2012 Bryan Drewery <bryan@shatow.net>
 * Copyright (c) 2013 Matthew Seaman <matthew@FreeBSD.org>
+
 * Copyright (c) 2017 Vsevolod Stakhov <vsevolod@FreeBSD.org>
 * All rights reserved.
-
 * 
+
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
@@ -14,7 +15,7 @@
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
-
 * 
+
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@@ -608,6 +609,20 @@ pkg_addgroup(struct pkg *pkg, const char *name)
int
pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *version, bool locked)
{
+
	if (pkg_adddep_chain(NULL, pkg, name, origin, version, locked) == NULL) {
+
		return (EPKG_FATAL);
+
	}
+

+
	return (EPKG_OK);
+
}
+

+
struct pkg_dep *
+
pkg_adddep_chain(struct pkg_dep *chain,
+
		struct pkg *pkg,
+
		const char *name,
+
		const char *origin,
+
		const char *version, bool locked)
+
{
	struct pkg_dep *d = NULL;

	assert(pkg != NULL);
@@ -619,11 +634,11 @@ pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *ve
		if (developer_mode) {
			pkg_emit_error("%s: duplicate dependency listing: %s, fatal (developer mode)",
			    pkg->name, name);
-
			return (EPKG_FATAL);
+
			return (NULL);
		} else {
			pkg_emit_error("%s-%s: duplicate dependency listing: %s, ignoring",
			    pkg->name, pkg->version, name);
-
			return (EPKG_OK);
+
			return (NULL);
		}
	}

@@ -636,9 +651,16 @@ pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *ve
	d->locked = locked;

	kh_add(pkg_deps, pkg->depshash, d, d->name, pkg_dep_free);
-
	LL_APPEND(pkg->depends, d);

-
	return (EPKG_OK);
+
	if (chain == NULL) {
+
		DL_APPEND(pkg->depends, d);
+
		chain = pkg->depends;
+
	}
+
	else {
+
		DL_APPEND2(chain, d, alt_prev, alt_next);
+
	}
+

+
	return (chain);
}

int
@@ -661,7 +683,7 @@ pkg_addrdep(struct pkg *pkg, const char *name, const char *origin, const char *v
	d->locked = locked;

	kh_add(pkg_deps, pkg->rdepshash, d, d->name, pkg_dep_free);
-
	LL_APPEND(pkg->rdepends, d);
+
	LL_PREPEND(pkg->rdepends, d);

	return (EPKG_OK);
}
@@ -1253,15 +1275,22 @@ pkg_list_count(const struct pkg *pkg, pkg_list list)
	case PKG_LICENSES:
		return (kh_count(pkg->licenses));
	}
-
	
+

	return (0);
}

void
pkg_list_free(struct pkg *pkg, pkg_list list)  {
+
	struct pkg_dep *cur;
+

	switch (list) {
	case PKG_DEPS:
-
		LL_FREE(pkg->depends, pkg_dep_free);
+
		DL_FOREACH (pkg->depends, cur) {
+
			if (cur->alt_next) {
+
				DL_FREE2(cur->alt_next, pkg_dep_free, alt_prev, alt_next);
+
			}
+
		}
+
		DL_FREE(pkg->depends, pkg_dep_free);
		kh_destroy_pkg_deps(pkg->depshash);
		pkg->flags &= ~PKG_LOAD_DEPS;
		break;
@@ -1578,7 +1607,7 @@ pkg_recompute(struct pkgdb *db, struct pkg *pkg)

		if (regular)
			flatsize += st.st_size;
-
		
+

		if (strcmp(sum, f->sum) != 0)
			pkgdb_file_set_cksum(db, f, sum);
		free(sum);
modified libpkg/pkg_deps.c
@@ -1,5 +1,5 @@
/*-
-
 * Copyright (c) 2015, Vsevolod Stakhov
+
 * Copyright (c) 2015-2017, Vsevolod Stakhov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
modified libpkg/pkg_solve.c
@@ -1,5 +1,5 @@
/*-
-
 * Copyright (c) 2013-2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
+
 * Copyright (c) 2013-2017 Vsevolod Stakhov <vsevolod@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -357,15 +357,10 @@ pkg_solve_add_depend_rule(struct pkg_solve_problem *problem,
	struct pkg_solve_variable *depvar, *curvar;
	struct pkg_solve_rule *rule = NULL;
	struct pkg_solve_item *it = NULL;
-
	int cnt;
+
	int cnt = 0;
+
	struct pkg_dep *cur;

-
	uid = dep->uid;
-
	HASH_FIND_STR(problem->variables_by_uid, uid, depvar);
-
	if (depvar == NULL) {
-
		pkg_debug(2, "cannot find variable dependency %s", uid);
-
		return (EPKG_END);
-
	}
-
	/* Dependency rule: (!A | B) */
+
	/* Dependency rule: (!A | B1 | B2 | B3...) */
	rule = pkg_solve_rule_new(PKG_RULE_DEPEND);
	if (rule == NULL)
		return (EPKG_FATAL);
@@ -378,23 +373,40 @@ pkg_solve_add_depend_rule(struct pkg_solve_problem *problem,

	it->inverse = -1;
	RULE_ITEM_APPEND(rule, it);
-
	/* B1 | B2 | ... */
-
	cnt = 1;
-
	LL_FOREACH(depvar, curvar) {
-
		/* Propagate reponame */
-
		if (curvar->assumed_reponame == NULL) {
-
			curvar->assumed_reponame = reponame;
+

+
	LL_FOREACH2(dep, cur, alt_next) {
+
		uid = cur->uid;
+
		HASH_FIND_STR(problem->variables_by_uid, uid, depvar);
+
		if (depvar == NULL) {
+
			pkg_debug(2, "cannot find variable dependency %s", uid);
+
			continue;
		}

-
		it = pkg_solve_item_new(curvar);
-
		if (it == NULL) {
-
			pkg_solve_rule_free(rule);
-
			return (EPKG_FATAL);
+
		/* B1 | B2 | ... */
+
		cnt = 1;
+
		LL_FOREACH(depvar, curvar) {
+
			/* Propagate reponame */
+
			if (curvar->assumed_reponame == NULL) {
+
				curvar->assumed_reponame = reponame;
+
			}
+

+
			it = pkg_solve_item_new(curvar);
+
			if (it == NULL) {
+
				pkg_solve_rule_free(rule);
+
				return (EPKG_FATAL);
+
			}
+

+
			it->inverse = 1;
+
			RULE_ITEM_APPEND(rule, it);
+
			cnt ++;
		}
+
	}

-
		it->inverse = 1;
-
		RULE_ITEM_APPEND(rule, it);
-
		cnt ++;
+
	if (cnt == 0) {
+
		pkg_debug(2, "cannot find any suitable dependency for %s", var->uid);
+
		pkg_solve_rule_free(rule);
+

+
		return (EPKG_FATAL);
	}

	kv_prepend(typeof(rule), problem->rules, rule);
modified libpkg/pkgdb_iterator.c
@@ -7,7 +7,7 @@
 * Copyright (c) 2012-2014 Matthew Seaman <matthew@FreeBSD.org>
 * Copyright (c) 2012 Bryan Drewery <bryan@shatow.net>
 * Copyright (c) 2013 Gerald Pfeifer <gerald@pfeifer.com>
-
 * Copyright (c) 2013-2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
+
 * Copyright (c) 2013-2017 Vsevolod Stakhov <vsevolod@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -213,6 +213,7 @@ pkgdb_load_deps(sqlite3 *sqlite, struct pkg *pkg)
{
	sqlite3_stmt	*stmt = NULL, *opt_stmt = NULL;
	int		 ret = EPKG_OK;
+
	struct pkg_dep *chain = NULL;
	struct pkg_dep_formula *f;
	struct pkg_dep_formula_item *fit;
	struct pkg_dep_option_item *optit;
@@ -288,6 +289,8 @@ pkgdb_load_deps(sqlite3 *sqlite, struct pkg *pkg)
					}

					/* Fetch matching packages */
+
					chain = NULL;
+

					while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
						/*
						 * Load options for a package and check
@@ -333,7 +336,8 @@ pkgdb_load_deps(sqlite3 *sqlite, struct pkg *pkg)
						}

						if (options_match) {
-
							pkg_adddep(pkg, sqlite3_column_text(stmt, 1),
+
							chain = pkg_adddep_chain(chain, pkg,
+
									sqlite3_column_text(stmt, 1),
									sqlite3_column_text(stmt, 2),
									sqlite3_column_text(stmt, 3),
									sqlite3_column_int64(stmt, 4));
modified libpkg/private/pkg.h
@@ -2,9 +2,9 @@
 * Copyright (c) 2011-2016 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2013 Matthew Seaman <matthew@FreeBSD.org>
-
 * Copyright (c) 2013 Vsevolod Stakhov <vsevolod@FreeBSD.org>
+
 * Copyright (c) 2013-2017 Vsevolod Stakhov <vsevolod@FreeBSD.org>
 * All rights reserved.
-
 * 
+
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
@@ -14,7 +14,7 @@
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
-
 * 
+
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@@ -320,7 +320,8 @@ struct pkg_dep {
	char		*version;
	char		*uid;
	bool		 locked;
-
	struct pkg_dep	*next;
+
	struct pkg_dep		*alt_next, *alt_prev; /* Chain of alternatives */
+
	struct pkg_dep	*next, *prev;
};

typedef enum {
@@ -816,5 +817,8 @@ int pkg_set_from_fileat(int fd, struct pkg *pkg, pkg_attr attr, const char *file
void pkg_rollback_cb(void *);
void pkg_rollback_pkg(struct pkg *);
int pkg_add_fromdir(struct pkg *, const char *);
+
struct pkg_dep* pkg_adddep_chain(struct pkg_dep *chain,
+
		struct pkg *pkg, const char *name, const char *origin, const
+
		char *version, bool locked);

#endif