From 2aa7e69da91c1d7a18473cf05df98c92bd1dc747 Mon Sep 17 00:00:00 2001 From: Nagy Gabor Date: Sun, 18 Nov 2007 14:25:43 +0100 Subject: Add the pmconflict_t type. pmdepmissing_t was used for two totally different things : missing dependencies, and dependency conflicts. So this patch simply adds a type for dep conflicts, and convert the code to use it. This fix the TODO in conflict.c : /* TODO WTF is a 'depmissing' doing indicating a conflict? */ Additionally, the code in conflict.c now eliminates the duplicated conflicts. If pkg1 conflicts with pkg2, and pkg2 conflicts with pkg1, only one of them will be stored. However the conflict handling in sync_prepare (sync.c) is still very asymetrical, and very ugly too. This should be improved in the future (there is already a pending patch from Nagy that cleans it a lot). Signed-off-by: Chantry Xavier --- lib/libalpm/add.c | 4 +-- lib/libalpm/alpm.h | 10 +++----- lib/libalpm/conflict.c | 68 +++++++++++++++++++++++++++++++++++++++++++----- lib/libalpm/conflict.h | 7 +++++ lib/libalpm/deps.c | 29 +++++---------------- lib/libalpm/deps.h | 6 ++--- lib/libalpm/sync.c | 70 +++++++++++++++++++++++++------------------------- src/pacman/add.c | 5 ++-- src/pacman/sync.c | 5 ++-- 9 files changed, 122 insertions(+), 82 deletions(-) diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index fbdf4ea4..e6efe2d7 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -163,10 +163,10 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) _alpm_log(PM_LOG_DEBUG, "looking for conflicts\n"); lp = _alpm_checkconflicts(db, trans->packages); for(i = lp; i; i = i->next) { - pmdepmissing_t *miss = i->data; + pmconflict_t *conflict = i->data; _alpm_log(PM_LOG_ERROR, _("replacing packages with -A and -U is not supported yet\n")); - _alpm_log(PM_LOG_ERROR, _("please remove '%s' first, using -Rd\n"), miss->depend.name); + _alpm_log(PM_LOG_ERROR, _("please remove '%s' first, using -Rd\n"), conflict->package2); RET_ERR(PM_ERR_CONFLICTING_DEPS, -1); /* Attempt to resolve conflicts */ diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index a28c912a..658eca70 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -52,6 +52,7 @@ typedef struct __pmtrans_t pmtrans_t; typedef struct __pmsyncpkg_t pmsyncpkg_t; typedef struct __pmdepend_t pmdepend_t; typedef struct __pmdepmissing_t pmdepmissing_t; +typedef struct __pmconflict_t pmconflict_t; typedef struct __pmfileconflict_t pmfileconflict_t; typedef struct __pmgraph_t pmgraph_t; @@ -367,20 +368,17 @@ typedef enum _pmdepmod_t { PM_DEP_MOD_LE } pmdepmod_t; -typedef enum _pmdeptype_t { - PM_DEP_TYPE_DEPEND = 1, - PM_DEP_TYPE_CONFLICT -} pmdeptype_t; - pmdepend_t *alpm_splitdep(const char *depstring); int alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep); alpm_list_t *alpm_checkdeps(pmdb_t *db, pmtranstype_t op, alpm_list_t *packages); const char *alpm_miss_get_target(const pmdepmissing_t *miss); -pmdeptype_t alpm_miss_get_type(const pmdepmissing_t *miss); pmdepend_t *alpm_miss_get_dep(pmdepmissing_t *miss); +const char *alpm_conflict_get_package1(pmconflict_t *conflict); +const char *alpm_conflict_get_package2(pmconflict_t *conflict); + pmdepmod_t alpm_dep_get_mod(const pmdepend_t *dep); const char *alpm_dep_get_name(const pmdepend_t *dep); const char *alpm_dep_get_version(const pmdepend_t *dep); diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index d72dd97a..7268275e 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -43,6 +43,40 @@ #include "cache.h" #include "deps.h" +pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2) +{ + pmconflict_t *conflict; + + ALPM_LOG_FUNC; + + MALLOC(conflict, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL)); + + strncpy(conflict->package1, package1, PKG_NAME_LEN); + strncpy(conflict->package2, package2, PKG_NAME_LEN); + + return(conflict); +} + +int _alpm_conflict_isin(pmconflict_t *needle, alpm_list_t *haystack) +{ + alpm_list_t *i; + + ALPM_LOG_FUNC; + + for(i = haystack; i; i = i->next) { + pmconflict_t *conflict = i->data; + char *cpkg1 = conflict->package1; + char *cpkg2 = conflict->package2; + char *npkg1 = needle->package1; + char *npkg2 = needle->package2; + if((!strcmp(cpkg1, npkg1) && !strcmp(cpkg2, npkg2)) + || (!strcmp(cpkg1, npkg2) && !strcmp(cpkg2, npkg1))) { + return(1); + } + } + + return(0); +} /** Check if pkg1 conflicts with pkg2 * @param pkg1 package we are looking at @@ -71,16 +105,14 @@ static int does_conflict(pmpkg_t *pkg1, const char *conflict, pmpkg_t *pkg2) * @param pkg1 first package * @param pkg2 package causing conflict */ -/* TODO WTF is a 'depmissing' doing indicating a conflict? */ static void add_conflict(alpm_list_t **baddeps, const char *pkg1, const char *pkg2) { - pmdepmissing_t *miss = _alpm_depmiss_new(pkg1, PM_DEP_TYPE_CONFLICT, - PM_DEP_MOD_ANY, pkg2, NULL); - if(miss && !_alpm_depmiss_isin(miss, *baddeps)) { - *baddeps = alpm_list_add(*baddeps, miss); + pmconflict_t *conflict = _alpm_conflict_new(pkg1, pkg2); + if(conflict && !_alpm_conflict_isin(conflict, *baddeps)) { + *baddeps = alpm_list_add(*baddeps, conflict); } else { - FREE(miss); + FREE(conflict); } } @@ -130,7 +162,7 @@ static void check_conflict(alpm_list_t *list1, alpm_list_t *list2, } } -/* Returns a alpm_list_t* of pmdepmissing_t pointers. */ +/* Returns a alpm_list_t* of pmconflict_t pointers. */ alpm_list_t *_alpm_checkconflicts(pmdb_t *db, alpm_list_t *packages) { alpm_list_t *baddeps = NULL; @@ -418,6 +450,28 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, char *roo return(conflicts); } +const char SYMEXPORT *alpm_conflict_get_package1(pmconflict_t *conflict) +{ + ALPM_LOG_FUNC; + + /* Sanity checks */ + ASSERT(handle != NULL, return(NULL)); + ASSERT(conflict != NULL, return(NULL)); + + return conflict->package1; +} + +const char SYMEXPORT *alpm_conflict_get_package2(pmconflict_t *conflict) +{ + ALPM_LOG_FUNC; + + /* Sanity checks */ + ASSERT(handle != NULL, return(NULL)); + ASSERT(conflict != NULL, return(NULL)); + + return conflict->package2; +} + const char SYMEXPORT *alpm_fileconflict_get_target(pmfileconflict_t *conflict) { ALPM_LOG_FUNC; diff --git a/lib/libalpm/conflict.h b/lib/libalpm/conflict.h index f8aebbf1..89695353 100644 --- a/lib/libalpm/conflict.h +++ b/lib/libalpm/conflict.h @@ -27,6 +27,11 @@ #define CONFLICT_FILE_LEN 512 +struct __pmconflict_t { + char package1[PKG_NAME_LEN]; + char package2[PKG_NAME_LEN]; +}; + struct __pmfileconflict_t { char target[PKG_NAME_LEN]; pmfileconflicttype_t type; @@ -34,6 +39,8 @@ struct __pmfileconflict_t { char ctarget[PKG_NAME_LEN]; }; +pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2); +int _alpm_conflict_isin(pmconflict_t *needle, alpm_list_t *haystack); alpm_list_t *_alpm_checkconflicts(pmdb_t *db, alpm_list_t *packages); alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, char *root); diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 6aaf4bd8..5d88c37d 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -61,9 +61,8 @@ static void _alpm_graph_free(void *data) free(graph); } -pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdeptype_t type, - pmdepmod_t depmod, const char *depname, - const char *depversion) +pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepmod_t depmod, + const char *depname, const char *depversion) { pmdepmissing_t *miss; @@ -72,7 +71,6 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdeptype_t type, MALLOC(miss, sizeof(pmdepmissing_t), RET_ERR(PM_ERR_MEMORY, NULL)); strncpy(miss->target, target, PKG_NAME_LEN); - miss->type = type; miss->depend.mod = depmod; strncpy(miss->depend.name, depname, PKG_NAME_LEN); if(depversion) { @@ -92,8 +90,7 @@ int _alpm_depmiss_isin(pmdepmissing_t *needle, alpm_list_t *haystack) for(i = haystack; i; i = i->next) { pmdepmissing_t *miss = i->data; - if(needle->type == miss->type && - !strcmp(needle->target, miss->target) && + if(!strcmp(needle->target, miss->target) && needle->depend.mod == miss->depend.mod && !strcmp(needle->depend.name, miss->depend.name) && !strcmp(needle->depend.version, miss->depend.version)) { @@ -328,8 +325,7 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, if(!satisfied) { _alpm_log(PM_LOG_DEBUG, "checkdeps: updated '%s' won't satisfy a dependency of '%s'\n", alpm_pkg_get_name(oldpkg), alpm_pkg_get_name(p)); - miss = _alpm_depmiss_new(p->name, PM_DEP_TYPE_DEPEND, depend->mod, - depend->name, depend->version); + miss = _alpm_depmiss_new(p->name, depend->mod, depend->name, depend->version); if(!_alpm_depmiss_isin(miss, baddeps)) { baddeps = alpm_list_add(baddeps, miss); } else { @@ -375,8 +371,8 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, if(!found) { _alpm_log(PM_LOG_DEBUG, "missing dependency '%s' for package '%s'\n", (char*)j->data, alpm_pkg_get_name(tp)); - miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), PM_DEP_TYPE_DEPEND, depend->mod, - depend->name, depend->version); + miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend->mod, + depend->name, depend->version); if(!_alpm_depmiss_isin(miss, baddeps)) { baddeps = alpm_list_add(baddeps, miss); } else { @@ -430,8 +426,7 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, _alpm_log(PM_LOG_DEBUG, "checkdeps: found %s which requires %s\n", alpm_pkg_get_name(p), alpm_pkg_get_name(rmpkg)); miss = _alpm_depmiss_new(alpm_pkg_get_name(p), - PM_DEP_TYPE_DEPEND, depend->mod, depend->name, - depend->version); + depend->mod, depend->name, depend->version); if(!_alpm_depmiss_isin(miss, baddeps)) { baddeps = alpm_list_add(baddeps, miss); } else { @@ -765,16 +760,6 @@ const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss) return miss->target; } -pmdeptype_t SYMEXPORT alpm_miss_get_type(const pmdepmissing_t *miss) -{ - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(miss != NULL, return(-1)); - - return miss->type; -} - pmdepend_t SYMEXPORT *alpm_miss_get_dep(pmdepmissing_t *miss) { ALPM_LOG_FUNC; diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h index 1d656910..a736f705 100644 --- a/lib/libalpm/deps.h +++ b/lib/libalpm/deps.h @@ -38,7 +38,6 @@ struct __pmdepend_t { /* Missing dependency */ struct __pmdepmissing_t { char target[PKG_NAME_LEN]; - pmdeptype_t type; pmdepend_t depend; }; @@ -51,9 +50,8 @@ struct __pmgraph_t { alpm_list_t *childptr; /* points to a child in children list */ }; -pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdeptype_t type, - pmdepmod_t depmod, const char *depname, - const char *depversion); +pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepmod_t depmod, + const char *depname, const char *depversion); int _alpm_depmiss_isin(pmdepmissing_t *needle, alpm_list_t *haystack); alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode); alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 3075100a..e4a7799e 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -464,18 +464,18 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync alpm_list_t *asked = NULL; for(i = deps; i && !errorout; i = i->next) { - pmdepmissing_t *miss = i->data; + pmconflict_t *conflict = i->data; pmsyncpkg_t *sync; pmpkg_t *found = NULL; _alpm_log(PM_LOG_DEBUG, "package '%s' conflicts with '%s'\n", - miss->target, miss->depend.name); + conflict->package1, conflict->package2); /* check if the conflicting package is about to be removed/replaced. * if so, then just ignore it. */ for(j = trans->packages; j && !found; j = j->next) { sync = j->data; if(sync->type == PM_SYNC_TYPE_REPLACE) { - found = _alpm_pkg_find(miss->depend.name, sync->data); + found = _alpm_pkg_find(conflict->package2, sync->data); } } if(found) { @@ -484,24 +484,24 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync continue; } - sync = _alpm_sync_find(trans->packages, miss->target); + sync = _alpm_sync_find(trans->packages, conflict->package1); if(sync == NULL) { _alpm_log(PM_LOG_DEBUG, "'%s' not found in transaction set -- skipping\n", - miss->target); + conflict->package1); continue; } - pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, miss->depend.name); + pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, conflict->package2); /* check if this package provides the package it's conflicting with */ if(alpm_list_find_str(alpm_pkg_get_provides(sync->pkg), - miss->depend.name)) { + conflict->package2)) { /* treat like a replaces item so requiredby fields are * inherited properly. */ _alpm_log(PM_LOG_DEBUG, "package '%s' provides its own conflict\n", - miss->target); + conflict->package1); if(!local) { char *rmpkg = NULL; int target, depend; - /* hmmm, depend.name isn't installed, so it must be conflicting + /* hmmm, package2 isn't installed, so it must be conflicting * with another package in our final list. For example: * * pacman -S blackbox xfree86 @@ -514,22 +514,22 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync /* figure out which one was requested in targets. If they both * were, then it's still an unresolvable conflict. */ - target = alpm_list_find_str(trans->targets, miss->target); - depend = alpm_list_find_str(trans->targets, miss->depend.name); + target = alpm_list_find_str(trans->targets, conflict->package1); + depend = alpm_list_find_str(trans->targets, conflict->package2); if(depend && !target) { _alpm_log(PM_LOG_DEBUG, "'%s' is in the target list -- keeping it\n", - miss->depend.name); - /* remove miss->target */ - rmpkg = miss->target; + conflict->package2); + /* remove conflict->package1 */ + rmpkg = conflict->package1; } else if(target && !depend) { _alpm_log(PM_LOG_DEBUG, "'%s' is in the target list -- keeping it\n", - miss->target); - /* remove miss->depend.name */ - rmpkg = miss->depend.name; + conflict->package1); + /* remove conflict->package2 */ + rmpkg = conflict->package2; } else { - /* miss->depend.name is not needed, miss->target already provides + /* miss->target2 is not needed, miss->target already provides * it, let's resolve the conflict */ - rmpkg = miss->depend.name; + rmpkg = conflict->package2; } if(rmpkg) { pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages, rmpkg); @@ -545,13 +545,13 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync } /* It's a conflict -- see if they want to remove it */ _alpm_log(PM_LOG_DEBUG, "resolving package '%s' conflict\n", - miss->target); + conflict->package1); if(local) { int doremove = 0; - if(!alpm_list_find_str(asked, miss->depend.name)) { - QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target, - miss->depend.name, NULL, &doremove); - asked = alpm_list_add(asked, strdup(miss->depend.name)); + if(!alpm_list_find_str(asked, conflict->package2)) { + QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, conflict->package1, + conflict->package2, NULL, &doremove); + asked = alpm_list_add(asked, strdup(conflict->package2)); if(doremove) { pmpkg_t *q = _alpm_pkg_dup(local); if(sync->type != PM_SYNC_TYPE_REPLACE) { @@ -562,16 +562,16 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync } /* append to the replaces list */ _alpm_log(PM_LOG_DEBUG, "electing '%s' for removal\n", - miss->depend.name); + conflict->package2); sync->data = alpm_list_add(sync->data, q); /* see if the package is in the current target list */ pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages, - miss->depend.name); + conflict->package2); if(rsync) { /* remove it from the target list */ void *vpkg; _alpm_log(PM_LOG_DEBUG, "removing '%s' from target list\n", - miss->depend.name); + conflict->package2); trans->packages = alpm_list_remove(trans->packages, rsync, syncpkg_cmp, &vpkg); _alpm_sync_free(vpkg); @@ -581,15 +581,15 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync _alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n")); errorout = 1; if(data) { - if((miss = malloc(sizeof(pmdepmissing_t))) == NULL) { - _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %zd bytes\n"), sizeof(pmdepmissing_t)); + if((conflict = malloc(sizeof(pmconflict_t))) == NULL) { + _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %zd bytes\n"), sizeof(pmconflict_t)); FREELIST(*data); pm_errno = PM_ERR_MEMORY; ret = -1; goto cleanup; } - *miss = *(pmdepmissing_t *)i->data; - *data = alpm_list_add(*data, miss); + *conflict = *(pmconflict_t *)i->data; + *data = alpm_list_add(*data, conflict); } } } @@ -597,15 +597,15 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync _alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n")); errorout = 1; if(data) { - if((miss = malloc(sizeof(pmdepmissing_t))) == NULL) { - _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %zd bytes\n"), sizeof(pmdepmissing_t)); + if((conflict = malloc(sizeof(pmconflict_t))) == NULL) { + _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %zd bytes\n"), sizeof(pmconflict_t)); FREELIST(*data); pm_errno = PM_ERR_MEMORY; ret = -1; goto cleanup; } - *miss = *(pmdepmissing_t *)i->data; - *data = alpm_list_add(*data, miss); + *conflict = *(pmconflict_t *)i->data; + *data = alpm_list_add(*data, conflict); } } } diff --git a/src/pacman/add.c b/src/pacman/add.c index f685cc70..7d187495 100644 --- a/src/pacman/add.c +++ b/src/pacman/add.c @@ -147,10 +147,9 @@ int pacman_add(alpm_list_t *targets) break; case PM_ERR_CONFLICTING_DEPS: for(i = data; i; i = alpm_list_next(i)) { - pmdepmissing_t *miss = alpm_list_getdata(i); - pmdepend_t *dep = alpm_miss_get_dep(miss); + pmconflict_t *conflict = alpm_list_getdata(i); printf(_(":: %s: conflicts with %s"), - alpm_miss_get_target(miss), alpm_dep_get_name(dep)); + alpm_conflict_get_package1(conflict), alpm_conflict_get_package2(conflict)); } break; case PM_ERR_FILE_CONFLICTS: diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 2d30e641..41d18a9a 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -620,10 +620,9 @@ int sync_trans(alpm_list_t *targets, int sync_only) break; case PM_ERR_CONFLICTING_DEPS: for(i = data; i; i = alpm_list_next(i)) { - pmdepmissing_t *miss = alpm_list_getdata(i); - pmdepend_t *dep = alpm_miss_get_dep(miss); + pmconflict_t *conflict = alpm_list_getdata(i); printf(_(":: %s: conflicts with %s"), - alpm_miss_get_target(miss), alpm_dep_get_name(dep)); + alpm_conflict_get_package1(conflict), alpm_conflict_get_package2(conflict)); } break; default: -- cgit v1.2.3-24-g4f1b