diff options
Diffstat (limited to 'lib/libalpm/deps.c')
-rw-r--r-- | lib/libalpm/deps.c | 451 |
1 files changed, 251 insertions, 200 deletions
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index b967243d..ab027074 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -30,37 +30,21 @@ #include "alpm_list.h" #include "util.h" #include "log.h" -#include "error.h" +#include "graph.h" #include "package.h" #include "db.h" #include "cache.h" #include "handle.h" -static pmgraph_t *_alpm_graph_new(void) +void _alpm_dep_free(pmdepend_t *dep) { - pmgraph_t *graph = NULL; - - MALLOC(graph, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL)); - - if(graph) { - graph->state = 0; - graph->data = NULL; - graph->parent = NULL; - graph->children = NULL; - graph->childptr = NULL; - } - return(graph); -} - -static void _alpm_graph_free(void *data) -{ - pmgraph_t *graph = data; - alpm_list_free(graph->children); - free(graph); + FREE(dep->name); + FREE(dep->version); + FREE(dep); } -pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepmod_t depmod, - const char *depname, const char *depversion) +pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepend_t *dep, + const char *causingpkg) { pmdepmissing_t *miss; @@ -68,26 +52,29 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepmod_t depmod, MALLOC(miss, sizeof(pmdepmissing_t), RET_ERR(PM_ERR_MEMORY, NULL)); - strncpy(miss->target, target, PKG_NAME_LEN); - miss->depend.mod = depmod; - strncpy(miss->depend.name, depname, PKG_NAME_LEN); - if(depversion) { - strncpy(miss->depend.version, depversion, PKG_VERSION_LEN); - } else { - miss->depend.version[0] = 0; - } + STRDUP(miss->target, target, RET_ERR(PM_ERR_MEMORY, NULL)); + miss->depend = _alpm_dep_dup(dep); + STRDUP(miss->causingpkg, causingpkg, RET_ERR(PM_ERR_MEMORY, NULL)); return(miss); } +void _alpm_depmiss_free(pmdepmissing_t *miss) +{ + _alpm_dep_free(miss->depend); + FREE(miss->target); + FREE(miss->causingpkg); + FREE(miss); +} + /* Convert a list of pmpkg_t * to a graph structure, * with a edge for each dependency. * Returns a list of vertices (one vertex = one package) * (used by alpm_sortbydeps) */ -static alpm_list_t *_alpm_graph_init(alpm_list_t *targets) +static alpm_list_t *dep_graph_init(alpm_list_t *targets) { - alpm_list_t *i, *j, *k; + alpm_list_t *i, *j; alpm_list_t *vertices = NULL; /* We create the vertices */ for(i = targets; i; i = i->next) { @@ -104,12 +91,7 @@ static alpm_list_t *_alpm_graph_init(alpm_list_t *targets) for(j = vertices; j; j = j->next) { pmgraph_t *vertex_j = j->data; pmpkg_t *p_j = vertex_j->data; - int child = 0; - for(k = alpm_pkg_get_depends(p_i); k && !child; k = k->next) { - pmdepend_t *depend = k->data; - child = alpm_depcmp(p_j, depend); - } - if(child) { + if(_alpm_dep_edge(p_i, p_j)) { vertex_i->children = alpm_list_add(vertex_i->children, vertex_j); } @@ -121,20 +103,19 @@ static alpm_list_t *_alpm_graph_init(alpm_list_t *targets) /* Re-order a list of target packages with respect to their dependencies. * - * Example (PM_TRANS_TYPE_ADD): + * Example (reverse == 0): * A depends on C * B depends on A * Target order is A,B,C,D * * Should be re-ordered to C,A,B,D * - * mode should be either PM_TRANS_TYPE_ADD or PM_TRANS_TYPE_REMOVE. This - * affects the dependency order sortbydeps() will use. + * if reverse is > 0, the dependency order will be reversed. * * This function returns the new alpm_list_t* target list. * */ -alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode) +alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) { alpm_list_t *newtargs = NULL; alpm_list_t *vertices = NULL; @@ -149,7 +130,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode) _alpm_log(PM_LOG_DEBUG, "started sorting dependencies\n"); - vertices = _alpm_graph_init(targets); + vertices = dep_graph_init(targets); vptr = vertices; vertex = vertices->data; @@ -169,7 +150,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode) pmpkg_t *vertexpkg = vertex->data; pmpkg_t *childpkg = nextchild->data; _alpm_log(PM_LOG_WARNING, _("dependency cycle detected:\n")); - if(mode == PM_TRANS_TYPE_REMOVE) { + if(reverse) { _alpm_log(PM_LOG_WARNING, _("%s will be removed after its %s dependency\n"), vertexpkg->name, childpkg->name); } else { _alpm_log(PM_LOG_WARNING, _("%s will be installed before its %s dependency\n"), vertexpkg->name, childpkg->name); @@ -194,8 +175,8 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode) _alpm_log(PM_LOG_DEBUG, "sorting dependencies finished\n"); - if(mode == PM_TRANS_TYPE_REMOVE) { - /* we're removing packages, so reverse the order */ + if(reverse) { + /* reverse the order */ alpm_list_t *tmptargs = alpm_list_reverse(newtargs); /* free the old one */ alpm_list_free(newtargs); @@ -208,10 +189,68 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode) return(newtargs); } -/* Little helper function for alpm_list_find */ -static int satisfycmp(const void *pkg, const void *depend) +pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep) +{ + alpm_list_t *i; + + for(i = pkgs; i; i = alpm_list_next(i)) { + pmpkg_t *pkg = i->data; + if(alpm_depcmp(pkg, dep)) { + return(pkg); + } + } + return(NULL); +} + +alpm_list_t *_alpm_find_dep_satisfiers(alpm_list_t *pkgs, pmdepend_t *dep) +{ + alpm_list_t *i, *ret = NULL; + + for(i = pkgs; i; i = alpm_list_next(i)) { + pmpkg_t *pkg = i->data; + if(alpm_depcmp(pkg, dep)) { + ret = alpm_list_add(ret, pkg); + } + } + return(ret); +} + +/** Find packages in a list that provide a given package. + * @param pkgs an alpm_list_t* of package to search + * @param pkgname the name of the package + * @return an alpm_list_t* of packages that provide pkgname + */ +alpm_list_t SYMEXPORT *alpm_find_pkg_satisfiers(alpm_list_t *pkgs, const char *pkgname) { - return(!alpm_depcmp((pmpkg_t*) pkg, (pmdepend_t*) depend)); + pmdepend_t *dep = _alpm_splitdep(pkgname); + alpm_list_t *res = _alpm_find_dep_satisfiers(pkgs, dep); + _alpm_dep_free(dep); + return(res); +} + +/** Checks dependencies and returns missing ones in a list. + * Dependencies can include versions with depmod operators. + * @param db pointer to the local package database + * @param targets an alpm_list_t* of dependencies strings to satisfy + * @return an alpm_list_t* of missing dependencies strings + */ +alpm_list_t SYMEXPORT *alpm_deptest(pmdb_t *db, alpm_list_t *targets) +{ + alpm_list_t *i, *ret = NULL; + + for(i = targets; i; i = alpm_list_next(i)) { + pmdepend_t *dep; + char *target; + + target = alpm_list_getdata(i); + dep = _alpm_splitdep(target); + + if(!_alpm_find_dep_satisfier(_alpm_db_get_pkgcache(db), dep)) { + ret = alpm_list_add(ret, target); + } + _alpm_dep_free(dep); + } + return(ret); } /** Checks dependencies and returns missing ones in a list. @@ -257,15 +296,14 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps, pmdepend_t *depend = j->data; /* 1. we check the upgrade list */ /* 2. we check database for untouched satisfying packages */ - if(!alpm_list_find(upgrade, depend, satisfycmp) && - !alpm_list_find(dblist, depend, satisfycmp)) { + if(!_alpm_find_dep_satisfier(upgrade, depend) && + !_alpm_find_dep_satisfier(dblist, depend)) { /* Unsatisfied dependency in the upgrade list */ char *missdepstring = alpm_dep_get_string(depend); _alpm_log(PM_LOG_DEBUG, "checkdeps: missing dependency '%s' for package '%s'\n", missdepstring, alpm_pkg_get_name(tp)); free(missdepstring); - miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend->mod, - depend->name, depend->version); + miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend, ""); baddeps = alpm_list_add(baddeps, miss); } } @@ -278,18 +316,18 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps, pmpkg_t *lp = i->data; for(j = alpm_pkg_get_depends(lp); j; j = j->next) { pmdepend_t *depend = j->data; + pmpkg_t *causingpkg = _alpm_find_dep_satisfier(modified, depend); /* we won't break this depend, if it is already broken, we ignore it */ /* 1. check upgrade list for satisfiers */ /* 2. check dblist for satisfiers */ - if(alpm_list_find(modified, depend, satisfycmp) && - !alpm_list_find(upgrade, depend, satisfycmp) && - !alpm_list_find(dblist, depend, satisfycmp)) { + if(causingpkg && + !_alpm_find_dep_satisfier(upgrade, depend) && + !_alpm_find_dep_satisfier(dblist, depend)) { char *missdepstring = alpm_dep_get_string(depend); _alpm_log(PM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n", missdepstring, alpm_pkg_get_name(lp)); free(missdepstring); - miss = _alpm_depmiss_new(lp->name, depend->mod, - depend->name, depend->version); + miss = _alpm_depmiss_new(lp->name, depend, alpm_pkg_get_name(causingpkg)); baddeps = alpm_list_add(baddeps, miss); } } @@ -309,7 +347,7 @@ static int dep_vercmp(const char *version1, pmdepmod_t mod, if(mod == PM_DEP_MOD_ANY) { equal = 1; } else { - int cmp = _alpm_versioncmp(version1, version2); + int cmp = alpm_pkg_vercmp(version1, version2); switch(mod) { case PM_DEP_MOD_EQ: equal = (cmp == 0); break; case PM_DEP_MOD_GE: equal = (cmp >= 0); break; @@ -356,7 +394,7 @@ int SYMEXPORT alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep) return(satisfy); } -pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring) +pmdepend_t *_alpm_splitdep(const char *depstring) { pmdepend_t *depend; char *ptr = NULL; @@ -365,9 +403,9 @@ pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring) if(depstring == NULL) { return(NULL); } - newstr = strdup(depstring); + STRDUP(newstr, depstring, RET_ERR(PM_ERR_MEMORY, NULL)); - MALLOC(depend, sizeof(pmdepend_t), return(NULL)); + CALLOC(depend, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL)); /* Find a version comparator if one exists. If it does, set the type and * increment the ptr accordingly so we can copy the right strings. */ @@ -391,25 +429,36 @@ pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring) depend->mod = PM_DEP_MOD_GT; *ptr = '\0'; ptr += 1; - } else { - /* no version specified - copy in the name and return it */ + /* no version specified - copy the name and return it */ depend->mod = PM_DEP_MOD_ANY; - strncpy(depend->name, newstr, PKG_NAME_LEN); - depend->version[0] = '\0'; + STRDUP(depend->name, newstr, RET_ERR(PM_ERR_MEMORY, NULL)); + depend->version = NULL; free(newstr); return(depend); } /* if we get here, we have a version comparator, copy the right parts * to the right places */ - strncpy(depend->name, newstr, PKG_NAME_LEN); - strncpy(depend->version, ptr, PKG_VERSION_LEN); + STRDUP(depend->name, newstr, RET_ERR(PM_ERR_MEMORY, NULL)); + STRDUP(depend->version, ptr, RET_ERR(PM_ERR_MEMORY, NULL)); free(newstr); return(depend); } +pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep) +{ + pmdepend_t *newdep; + CALLOC(newdep, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL)); + + STRDUP(newdep->name, dep->name, RET_ERR(PM_ERR_MEMORY, NULL)); + STRDUP(newdep->version, dep->version, RET_ERR(PM_ERR_MEMORY, NULL)); + newdep->mod = dep->mod; + + return(newdep); +} + /* These parameters are messy. We check if this package, given a list of * targets and a db is safe to remove. We do NOT remove it if it is in the * target list, or if if the package was explictly installed and @@ -417,9 +466,9 @@ pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring) static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets, int include_explicit) { - alpm_list_t *i, *requiredby; + alpm_list_t *i; - if(_alpm_pkg_find(alpm_pkg_get_name(pkg), targets)) { + if(_alpm_pkg_find(targets, alpm_pkg_get_name(pkg))) { return(0); } @@ -439,15 +488,12 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets, * if checkdeps detected it would break something */ /* see if other packages need it */ - requiredby = alpm_pkg_compute_requiredby(pkg); - for(i = requiredby; i; i = i->next) { - pmpkg_t *reqpkg = _alpm_db_get_pkgfromcache(db, i->data); - if(reqpkg && !_alpm_pkg_find(alpm_pkg_get_name(reqpkg), targets)) { - FREELIST(requiredby); + for(i = _alpm_db_get_pkgcache(db); i; i = i->next) { + pmpkg_t *lpkg = i->data; + if(_alpm_dep_edge(lpkg, pkg) && !_alpm_pkg_find(targets, lpkg->name)) { return(0); } } - FREELIST(requiredby); /* it's ok to remove */ return(1); @@ -465,7 +511,7 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets, */ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit) { - alpm_list_t *i, *j, *k; + alpm_list_t *i, *j; ALPM_LOG_FUNC; @@ -475,159 +521,151 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit) for(i = targs; i; i = i->next) { pmpkg_t *pkg = i->data; - for(j = alpm_pkg_get_depends(pkg); j; j = j->next) { - pmdepend_t *depend = j->data; + for(j = _alpm_db_get_pkgcache(db); j; j = j->next) { + pmpkg_t *deppkg = j->data; + if(_alpm_dep_edge(pkg, deppkg) + && can_remove_package(db, deppkg, targs, include_explicit)) { + _alpm_log(PM_LOG_DEBUG, "adding '%s' to the targets\n", + alpm_pkg_get_name(deppkg)); + /* add it to the target list */ + targs = alpm_list_add(targs, _alpm_pkg_dup(deppkg)); + } + } + } +} - for(k = _alpm_db_get_pkgcache(db); k; k = k->next) { - pmpkg_t *deppkg = k->data; - if(alpm_depcmp(deppkg,depend) - && can_remove_package(db, deppkg, targs, include_explicit)) { - _alpm_log(PM_LOG_DEBUG, "adding '%s' to the targets\n", - alpm_pkg_get_name(deppkg)); - /* add it to the target list */ - targs = alpm_list_add(targs, _alpm_pkg_dup(deppkg)); +/* helper function for resolvedeps: search for dep satisfier in dbs */ +pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, pmpkg_t *tpkg) +{ + alpm_list_t *i, *j; + /* 1. literals */ + for(i = dbs; i; i = i->next) { + pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name); + if(pkg && alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) { + if(_alpm_pkg_should_ignore(pkg)) { + int install; + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, + tpkg, NULL, &install); + if(!install) { + continue; } } + return(pkg); } } + /* 2. satisfiers (skip literals here) */ + for(i = dbs; i; i = i->next) { + for(j = _alpm_db_get_pkgcache(i->data); j; j = j->next) { + pmpkg_t *pkg = j->data; + if(alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) && + !_alpm_pkg_find(excluding, pkg->name)) { + if(_alpm_pkg_should_ignore(pkg)) { + int install; + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, + tpkg, NULL, &install); + if(!install) { + continue; + } + } + return(pkg); + } + } + } + return(NULL); } -/* populates *list with packages that need to be installed to satisfy all - * dependencies (recursive) for syncpkg +/* populates list with packages that need to be installed to satisfy all + * dependencies of packages in list * * @param remove contains packages elected for removal - * make sure **list is already initialized */ -int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg, - alpm_list_t **list, alpm_list_t *remove, pmtrans_t *trans, alpm_list_t **data) +int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list, + alpm_list_t *remove, alpm_list_t **data) { - alpm_list_t *i, *j, *k; + alpm_list_t *i, *j; alpm_list_t *targ; alpm_list_t *deps = NULL; ALPM_LOG_FUNC; - if(local == NULL || dbs_sync == NULL || syncpkg == NULL || list == NULL) { + if(local == NULL || dbs_sync == NULL) { return(-1); } _alpm_log(PM_LOG_DEBUG, "started resolving dependencies\n"); - targ = alpm_list_add(NULL, syncpkg); - deps = alpm_checkdeps(local, 0, remove, targ); - alpm_list_free(targ); - - if(deps == NULL) { - return(0); - } - - for(i = deps; i; i = i->next) { - int found = 0; - pmdepmissing_t *miss = i->data; - pmdepend_t *missdep = &(miss->depend); - pmpkg_t *sync = NULL; - - /* check if one of the packages in *list already satisfies this dependency */ - for(j = *list; j && !found; j = j->next) { - pmpkg_t *sp = j->data; - if(alpm_depcmp(sp, missdep)) { - char *missdepstring = alpm_dep_get_string(missdep); - _alpm_log(PM_LOG_DEBUG, "%s satisfies dependency %s -- skipping\n", - alpm_pkg_get_name(sp), missdepstring); - free(missdepstring); - found = 1; - } - } - if(found) { - continue; - } - - /* find the package in one of the repositories */ - /* check literals */ - for(j = dbs_sync; j && !found; j = j->next) { - sync = _alpm_db_get_pkgfromcache(j->data, missdep->name); - if(!sync) { + for(i = list; i; i = i->next) { + pmpkg_t *tpkg = i->data; + targ = alpm_list_add(NULL, tpkg); + deps = alpm_checkdeps(local, 0, remove, targ); + alpm_list_free(targ); + for(j = deps; j; j = j->next) { + pmdepmissing_t *miss = j->data; + pmdepend_t *missdep = alpm_miss_get_dep(miss); + /* check if one of the packages in list already satisfies this dependency */ + if(_alpm_find_dep_satisfier(list, missdep)) { continue; } - found = alpm_depcmp(sync, missdep) && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove); - if(!found) { - continue; - } - /* If package is in the ignorepkg list, ask before we pull it */ - if(_alpm_pkg_should_ignore(sync)) { - pmpkg_t *dummypkg = _alpm_pkg_new(miss->target, NULL); - QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, dummypkg, sync, NULL, &found); - _alpm_pkg_free(dummypkg); - } - } - /*TODO this autoresolves the first 'satisfier' package... we should fix this - * somehow */ - /* check provides */ - /* we don't check literals again to avoid duplicated PM_TRANS_CONV_INSTALL_IGNOREPKG messages */ - for(j = dbs_sync; j && !found; j = j->next) { - for(k = _alpm_db_get_pkgcache(j->data); k && !found; k = k->next) { - sync = k->data; - if(!sync) { - continue; - } - found = alpm_depcmp(sync, missdep) && strcmp(sync->name, missdep->name) - && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove); - if(!found) { - continue; - } - if(_alpm_pkg_should_ignore(sync)) { - pmpkg_t *dummypkg = _alpm_pkg_new(miss->target, NULL); - QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, dummypkg, sync, NULL, &found); - _alpm_pkg_free(dummypkg); + /* find a satisfier package in the given repositories */ + pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, list, tpkg); + if(!spkg) { + pm_errno = PM_ERR_UNSATISFIED_DEPS; + char *missdepstring = alpm_dep_get_string(missdep); + _alpm_log(PM_LOG_ERROR, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), + missdepstring, tpkg->name); + free(missdepstring); + if(data) { + pmdepmissing_t *missd = _alpm_depmiss_new(miss->target, + miss->depend, miss->causingpkg); + if(missd) { + *data = alpm_list_add(*data, missd); + } } + alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free); + alpm_list_free(deps); + return(-1); + } else { + _alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n", + alpm_pkg_get_name(spkg), alpm_pkg_get_name(tpkg)); + list = alpm_list_add(list, spkg); } } + alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free); + alpm_list_free(deps); + } + _alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n"); + return(0); +} - if(!found) { - char *missdepstring = alpm_dep_get_string(missdep); - _alpm_log(PM_LOG_ERROR, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), - missdepstring, miss->target); - free(missdepstring); - if(data) { - MALLOC(miss, sizeof(pmdepmissing_t),/*nothing*/); - if(!miss) { - pm_errno = PM_ERR_MEMORY; - FREELIST(*data); - goto error; - } - *miss = *(pmdepmissing_t *)i->data; - *data = alpm_list_add(*data, miss); - } - pm_errno = PM_ERR_UNSATISFIED_DEPS; - goto error; - } else { - _alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n", - alpm_pkg_get_name(sync), alpm_pkg_get_name(syncpkg)); - *list = alpm_list_add(*list, sync); - if(_alpm_resolvedeps(local, dbs_sync, sync, list, remove, trans, data)) { - goto error; - } +/* Does pkg1 depend on pkg2, ie. does pkg2 satisfy a dependency of pkg1? */ +int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2) +{ + alpm_list_t *i; + for(i = alpm_pkg_get_depends(pkg1); i; i = i->next) { + if(alpm_depcmp(pkg2, i->data)) { + return(1); } } + return(0); +} - _alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n"); - - FREELIST(deps); +const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss) +{ + ALPM_LOG_FUNC; - return(0); + /* Sanity checks */ + ASSERT(miss != NULL, return(NULL)); -error: - FREELIST(deps); - return(-1); + return(miss->target); } -const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss) +const char SYMEXPORT *alpm_miss_get_causingpkg(const pmdepmissing_t *miss) { ALPM_LOG_FUNC; /* Sanity checks */ ASSERT(miss != NULL, return(NULL)); - return miss->target; + return miss->causingpkg; } pmdepend_t SYMEXPORT *alpm_miss_get_dep(pmdepmissing_t *miss) @@ -637,7 +675,7 @@ pmdepend_t SYMEXPORT *alpm_miss_get_dep(pmdepmissing_t *miss) /* Sanity checks */ ASSERT(miss != NULL, return(NULL)); - return &(miss->depend); + return(miss->depend); } pmdepmod_t SYMEXPORT alpm_dep_get_mod(const pmdepend_t *dep) @@ -647,7 +685,7 @@ pmdepmod_t SYMEXPORT alpm_dep_get_mod(const pmdepend_t *dep) /* Sanity checks */ ASSERT(dep != NULL, return(-1)); - return dep->mod; + return(dep->mod); } const char SYMEXPORT *alpm_dep_get_name(const pmdepend_t *dep) @@ -657,7 +695,7 @@ const char SYMEXPORT *alpm_dep_get_name(const pmdepend_t *dep) /* Sanity checks */ ASSERT(dep != NULL, return(NULL)); - return dep->name; + return(dep->name); } const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep) @@ -667,7 +705,7 @@ const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep) /* Sanity checks */ ASSERT(dep != NULL, return(NULL)); - return dep->version; + return(dep->version); } /** Reverse of splitdep; make a dep string from a pmdepend_t struct. @@ -677,7 +715,7 @@ const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep) */ char SYMEXPORT *alpm_dep_get_string(const pmdepend_t *dep) { - char *opr, *str = NULL; + char *name, *opr, *ver, *str = NULL; size_t len; ALPM_LOG_FUNC; @@ -685,6 +723,12 @@ char SYMEXPORT *alpm_dep_get_string(const pmdepend_t *dep) /* Sanity checks */ ASSERT(dep != NULL, return(NULL)); + if(dep->name) { + name = dep->name; + } else { + name = ""; + } + switch(dep->mod) { case PM_DEP_MOD_ANY: opr = ""; @@ -709,11 +753,18 @@ char SYMEXPORT *alpm_dep_get_string(const pmdepend_t *dep) break; } + if(dep->version) { + ver = dep->version; + } else { + ver = ""; + } + /* we can always compute len and print the string like this because opr - * and ver will be empty when PM_DEP_MOD_ANY is the depend type */ - len = strlen(dep->name) + strlen(opr) + strlen(dep->version) + 1; + * and ver will be empty when PM_DEP_MOD_ANY is the depend type. the + * reassignments above also ensure we do not do a strlen(NULL). */ + len = strlen(name) + strlen(opr) + strlen(ver) + 1; MALLOC(str, len, RET_ERR(PM_ERR_MEMORY, NULL)); - snprintf(str, len, "%s%s%s", dep->name, opr, dep->version); + snprintf(str, len, "%s%s%s", name, opr, ver); return(str); } |