summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile2
-rw-r--r--src/add.c14
-rw-r--r--src/apk_solver.h2
-rw-r--r--src/fix.c38
-rw-r--r--src/solver.c43
5 files changed, 51 insertions, 48 deletions
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 <stdio.h>
#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,