From c6d9962d818abd557cf25a686ea96fcf1315bc8c Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Tue, 13 Sep 2011 11:47:34 +0300 Subject: solver: add per-name specific flags, and fix the fix applet --- src/Makefile | 2 +- src/add.c | 14 +++++++++----- src/apk_solver.h | 2 ++ src/fix.c | 38 ++++++++++---------------------------- src/solver.c | 43 +++++++++++++++++++++++++++++-------------- 5 files changed, 51 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index eae7150..45f3415 100644 --- a/src/Makefile +++ b/src/Makefile @@ -19,7 +19,7 @@ $(error Build dependencies are not met) endif progs-y += apk -apk-objs := apk.o add.o del.o update.o info.o \ +apk-objs := apk.o add.o del.o fix.o update.o info.o \ search.o upgrade.o cache.o ver.o index.o fetch.o \ audit.o verify.o dot.o diff --git a/src/add.c b/src/add.c index a572c74..057d6cf 100644 --- a/src/add.c +++ b/src/add.c @@ -112,15 +112,19 @@ static int add_main(void *ctx, struct apk_database *db, int argc, char **argv) return -1; } - if (virtpkg) - apk_deps_add(&virtpkg->depends, &dep); - else + if (virtpkg == NULL) { apk_deps_add(&world, &dep); + apk_solver_set_name_flags(dep.name, actx->solver_flags); + } else { + apk_deps_add(&virtpkg->depends, &dep); + } } - if (virtpkg) + if (virtpkg) { apk_deps_add(&world, &virtdep); + apk_solver_set_name_flags(virtdep.name, actx->solver_flags); + } - r = apk_solver_commit(db, actx->solver_flags, world); + r = apk_solver_commit(db, 0, world); apk_dependency_array_free(&world); return r; diff --git a/src/apk_solver.h b/src/apk_solver.h index 03a2de5..4323f93 100644 --- a/src/apk_solver.h +++ b/src/apk_solver.h @@ -26,6 +26,8 @@ struct apk_changeset { #define APK_SOLVERF_AVAILABLE 0x0002 #define APK_SOLVERF_REINSTALL 0x0004 +void apk_solver_set_name_flags(struct apk_name *name, + unsigned short solver_flags); int apk_solver_solve(struct apk_database *db, unsigned short solver_flags, struct apk_dependency_array *world, diff --git a/src/fix.c b/src/fix.c index e345134..043fa3f 100644 --- a/src/fix.c +++ b/src/fix.c @@ -13,13 +13,13 @@ #include #include "apk_applet.h" #include "apk_database.h" -#include "apk_state.h" #include "apk_print.h" +#include "apk_solver.h" /* FIXME: reimplement fix applet */ struct fix_ctx { - unsigned int reinstall : 1; + unsigned short solver_flags; }; static int fix_parse(void *pctx, struct apk_db_options *dbopts, @@ -28,10 +28,10 @@ static int fix_parse(void *pctx, struct apk_db_options *dbopts, struct fix_ctx *ctx = (struct fix_ctx *) pctx; switch (optch) { case 'u': - apk_flags |= APK_UPGRADE; + ctx->solver_flags |= APK_SOLVERF_UPGRADE; break; case 'r': - ctx->reinstall = 1; + ctx->solver_flags |= APK_SOLVERF_REINSTALL; break; default: return -1; @@ -42,17 +42,13 @@ static int fix_parse(void *pctx, struct apk_db_options *dbopts, static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv) { struct fix_ctx *ctx = (struct fix_ctx *) pctx; - struct apk_state *state = NULL; struct apk_name *name; struct apk_package *pkg; - struct apk_dependency *deps; int r = 0, i, j; - state = apk_state_new(db); - if (state == NULL) - return -1; + if (!ctx->solver_flags) + ctx->solver_flags = APK_SOLVERF_REINSTALL; - deps = alloca(sizeof(struct apk_dependency) * argc); for (i = 0; i < argc; i++) { pkg = NULL; if (strstr(argv[i], ".apk") != NULL) { @@ -66,12 +62,9 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv) apk_error("%s: %s", argv[i], apk_error_str(r)); goto err; } - apk_dep_from_pkg(&deps[i], db, pkg); - name = deps[i].name; + name = pkg->name; } else { - apk_dep_from_blob(&deps[i], db, APK_BLOB_STR(argv[i])); - name = deps[i].name; - + name = apk_db_get_name(db, APK_BLOB_STR(argv[i])); for (j = 0; j < name->pkgs->num; j++) { if (name->pkgs->item[j]->ipkg != NULL) { pkg = name->pkgs->item[j]; @@ -83,22 +76,11 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv) apk_error("%s is not installed", name->name); goto err; } - if (ctx->reinstall) - name->flags |= APK_NAME_REINSTALL; + apk_solver_set_name_flags(name, ctx->solver_flags); } - for (i = 0; i < argc; i++) - r |= apk_state_lock_dependency(state, &deps[i]); - - if (r == 0 || (apk_flags & APK_FORCE)) - r = apk_state_commit(state); - else - apk_state_print_errors(state); + r = apk_solver_commit(db, 0, db->world); err: - if (r != 0 && i < argc) - apk_error("Error while processing '%s'", argv[i]); - if (state != NULL) - apk_state_unref(state); return r; } diff --git a/src/solver.c b/src/solver.c index 0e338b6..ce7a408 100644 --- a/src/solver.c +++ b/src/solver.c @@ -215,10 +215,10 @@ static void prepare_name(struct apk_solver_state *ss, struct apk_name *name, /* if package is needed for (re-)install */ if ((pkg->ipkg == NULL) || - (ns->solver_flags & APK_SOLVERF_REINSTALL)) { + ((ns->solver_flags | ss->solver_flags) & APK_SOLVERF_REINSTALL)) { /* and it's not available, we can't use it */ if (!pkg_available(ss->db, pkg)) - ps->conflicts++; + ps->conflicts = 1024; } } @@ -236,6 +236,7 @@ static void foreach_dependency(struct apk_solver_state *ss, struct apk_dependenc static int get_pkg_expansion_flags(struct apk_solver_state *ss, struct apk_package *pkg) { struct apk_name *name = pkg->name; + struct apk_name_state *ns = name_to_ns(name); int i, options = 0; /* check if the suggested package is the most preferred one of @@ -250,7 +251,9 @@ static int get_pkg_expansion_flags(struct apk_solver_state *ss, struct apk_packa ps0->conflicts != 0) continue; - if (ss->solver_flags & APK_SOLVERF_AVAILABLE) { + options++; + + if ((ns->solver_flags | ss->solver_flags) & APK_SOLVERF_AVAILABLE) { /* pkg available, pkg0 not */ if (pkg->repos != 0 && pkg0->repos == 0) continue; @@ -259,16 +262,19 @@ static int get_pkg_expansion_flags(struct apk_solver_state *ss, struct apk_packa return APK_PKGSTF_NOINSTALL | APK_PKGSTF_BRANCH; } - if (!(ss->solver_flags & APK_SOLVERF_UPGRADE)) { - /* not upgrading, prefer the installed package */ - if (pkg->ipkg == NULL && pkg0->ipkg != NULL) + if ((ns->solver_flags | ss->solver_flags) & APK_SOLVERF_UPGRADE) { + /* upgrading, or neither of the package is installed, so + * we just fall back comparing to versions */ + switch (apk_pkg_version_compare(pkg0, pkg)) { + case APK_VERSION_GREATER: return APK_PKGSTF_NOINSTALL | APK_PKGSTF_BRANCH; + case APK_VERSION_LESS: + continue; + } } - /* upgrading, or neither of the package is installed, so - * we just fall back comparing to versions */ - options++; - if (apk_pkg_version_compare(pkg0, pkg) == APK_VERSION_GREATER) + /* not upgrading, prefer the installed package */ + if (pkg->ipkg == NULL && pkg0->ipkg != NULL) return APK_PKGSTF_NOINSTALL | APK_PKGSTF_BRANCH; } @@ -670,7 +676,8 @@ static int compare_change(const void *p1, const void *p2) static int generate_changeset(struct apk_database *db, struct apk_package_array *solution, - struct apk_changeset *changeset) + struct apk_changeset *changeset, + unsigned short solver_flags) { struct apk_name *name; struct apk_name_state *ns; @@ -682,7 +689,7 @@ static int generate_changeset(struct apk_database *db, for (i = 0; i < solution->num; i++) { pkg = solution->item[i]; if ((pkg->ipkg == NULL) || - (name_to_ns(pkg->name)->solver_flags & APK_SOLVERF_REINSTALL)) + ((solver_flags | name_to_ns(pkg->name)->solver_flags) & APK_SOLVERF_REINSTALL)) num_installs++; } list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) { @@ -707,7 +714,7 @@ static int generate_changeset(struct apk_database *db, name = pkg->name; if ((pkg->ipkg == NULL) || - (name_to_ns(name)->solver_flags & APK_SOLVERF_REINSTALL)) { + ((solver_flags | name_to_ns(name)->solver_flags) & APK_SOLVERF_REINSTALL)) { for (j = 0; j < name->pkgs->num; j++) { pkg0 = name->pkgs->item[j]; if (pkg0->ipkg == NULL) @@ -738,6 +745,13 @@ static int free_state(apk_hash_item item, void *ctx) return 0; } +void apk_solver_set_name_flags(struct apk_name *name, + unsigned short solver_flags) +{ + struct apk_name_state *ns = name_to_ns(name); + ns->solver_flags = solver_flags; +} + int apk_solver_solve(struct apk_database *db, unsigned short solver_flags, struct apk_dependency_array *world, @@ -787,7 +801,8 @@ int apk_solver_solve(struct apk_database *db, if (r == 0 && ss->cur_unsatisfiable == 0) { record_solution(ss); if (changeset != NULL) - generate_changeset(db, ss->best_solution, changeset); + generate_changeset(db, ss->best_solution, changeset, + ss->solver_flags); r = 0; } else { qsort(ss->best_solution->item, ss->best_solution->num, -- cgit v1.2.3-60-g2f50