[pacman-dev] CVS update of pacman-lib/lib/libalpm (6 files)

Aaron Griffin aaron at archlinux.org
Thu Mar 1 02:03:05 EST 2007


    Date: Thursday, March 1, 2007 @ 02:03:05
  Author: aaron
    Path: /home/cvs-pacman/pacman-lib/lib/libalpm

Modified: add.c (1.120 -> 1.121) alpm_list.c (1.6 -> 1.7)
          alpm_list.h (1.5 -> 1.6) deps.c (1.71 -> 1.72)
          provide.c (1.11 -> 1.12) versioncmp.c (1.14 -> 1.15)

* Switched some functions to alpm_pkg_get_* usage as I came across them
* Added some provision switching hackery.  This could probably use some
  refactoring,.. it solves the following case:

    pkg1 and pkg2 provide 'foo' and are both installed
    pkg3 depends on 'foo' and so lists 'pkg1' in the REQUIREDBY db section
    pkg1 is upgraded and no longer provides 'foo'
    ** This code ensures that the REQUIREDBY of pkg3 is updated to require pkg2
       now instead of pkg1


--------------+
 add.c        |   30 ++++++++++++++++++++++++
 alpm_list.c  |   27 +++++++++++++++++++++
 alpm_list.h  |    1 
 deps.c       |   71 ++++++++++++++++++++++++++++++++++++++++++---------------
 provide.c    |    2 -
 versioncmp.c |    2 -
 6 files changed, 113 insertions(+), 20 deletions(-)


Index: pacman-lib/lib/libalpm/add.c
diff -u pacman-lib/lib/libalpm/add.c:1.120 pacman-lib/lib/libalpm/add.c:1.121
--- pacman-lib/lib/libalpm/add.c:1.120	Mon Feb 26 03:38:48 2007
+++ pacman-lib/lib/libalpm/add.c	Thu Mar  1 02:03:05 2007
@@ -343,6 +343,7 @@
 			oldpkg = _alpm_pkg_new(local->name, local->version);
 			if(oldpkg) {
 				oldpkg->backup = alpm_list_strdup(alpm_pkg_get_backup(local));
+				oldpkg->provides = alpm_list_strdup(alpm_pkg_get_provides(local));
 				strncpy(oldpkg->name, local->name, PKG_NAME_LEN);
 				strncpy(oldpkg->version, local->version, PKG_VERSION_LEN);
 			} else {
@@ -749,6 +750,35 @@
 		 * looking for packages depending on the package to add */
 		_alpm_pkg_update_requiredby(newpkg);
 
+		/* special case: if our provides list has changed from oldpkg to newpkg AND
+		 * we get here, we need to make sure we find the actual provision that
+		 * still satisfies this case, and update its 'requiredby' field... ugh */
+		alpm_list_t *provdiff, *prov;
+		provdiff = alpm_list_diff(alpm_pkg_get_provides(oldpkg),
+														 	alpm_pkg_get_provides(newpkg),
+															_alpm_str_cmp);
+		for(prov = provdiff; prov; prov = prov->next) {
+			const char *provname = prov->data;
+			_alpm_log(PM_LOG_DEBUG, _("provision '%s' has been removed from package %s (%s => %s)"),
+								provname, oldpkg->name, oldpkg->version, newpkg->version);
+
+			alpm_list_t *p = _alpm_db_whatprovides(handle->db_local, provname);
+			if(p) {
+				/* we now have all the provisions in the local DB for this virtual
+				 * package... seeing as we can't really determine which is the 'correct'
+				 * provision, we'll use the FIRST for now.
+				 * TODO figure out a way to find a "correct" provision */
+				pmpkg_t *provpkg = p->data;
+				_alpm_log(PM_LOG_DEBUG, _("updating '%s' due to provision change (%s)"), provpkg->name, provname);
+				_alpm_pkg_update_requiredby(provpkg);
+				if(_alpm_db_write(db, provpkg, INFRQ_DEPENDS)) {
+					_alpm_log(PM_LOG_ERROR, _("could not update provision '%s' from '%s'"), provname, provpkg->name);
+					alpm_logaction(_("could not update provision '%s' from '%s'"), provname, provpkg->name);
+					RET_ERR(PM_ERR_DB_WRITE, -1);
+				}
+			}
+		}
+
 		/* make an install date (in UTC) */
 		time_t t = time(NULL);
 		strncpy(newpkg->installdate, asctime(gmtime(&t)), PKG_DATE_LEN);
Index: pacman-lib/lib/libalpm/alpm_list.c
diff -u pacman-lib/lib/libalpm/alpm_list.c:1.6 pacman-lib/lib/libalpm/alpm_list.c:1.7
--- pacman-lib/lib/libalpm/alpm_list.c:1.6	Tue Jan 30 02:47:20 2007
+++ pacman-lib/lib/libalpm/alpm_list.c	Thu Mar  1 02:03:05 2007
@@ -457,6 +457,33 @@
 	return(0);
 }
 
+/** 
+ * Calculate the items in list `lhs` that are not present in list `rhs`
+ * @note Entries are not duplicated
+ * @param lhs the first list
+ * @param rhs the second list
+ * @param fn the comparisson function
+ * @return a list containing all items in lhs not present in rhs
+ */
+alpm_list_t *alpm_list_diff(alpm_list_t *lhs, alpm_list_t *rhs, alpm_list_fn_cmp fn)
+{
+	alpm_list_t *i, *j, *ret = NULL;
+	for(i = lhs; i; i = i->next) {
+		int found = 0;
+		for(j = rhs; j; j = j->next) {
+			if(fn(i->data, j->data) == 0) {
+				found = 1;
+				break;
+			}
+		}
+		if(!found) {
+			ret = alpm_list_add(ret, i->data);
+		}
+	}
+
+	return(ret);
+}
+
 /** @} */
 
 /* vim: set ts=2 sw=2 noet: */
Index: pacman-lib/lib/libalpm/alpm_list.h
diff -u pacman-lib/lib/libalpm/alpm_list.h:1.5 pacman-lib/lib/libalpm/alpm_list.h:1.6
--- pacman-lib/lib/libalpm/alpm_list.h:1.5	Fri Feb 16 17:41:51 2007
+++ pacman-lib/lib/libalpm/alpm_list.h	Thu Mar  1 02:03:05 2007
@@ -65,6 +65,7 @@
 int alpm_list_count(const alpm_list_t *list);
 int alpm_list_find(alpm_list_t *haystack, const void *needle);
 int alpm_list_find_str(alpm_list_t *haystack,const char *needle);
+alpm_list_t *alpm_list_diff(alpm_list_t *lhs, alpm_list_t *rhs, alpm_list_fn_cmp fn);
 
 #endif /* _ALPM_LIST_H */
 
Index: pacman-lib/lib/libalpm/deps.c
diff -u pacman-lib/lib/libalpm/deps.c:1.71 pacman-lib/lib/libalpm/deps.c:1.72
--- pacman-lib/lib/libalpm/deps.c:1.71	Tue Feb 27 23:00:21 2007
+++ pacman-lib/lib/libalpm/deps.c	Thu Mar  1 02:03:05 2007
@@ -198,7 +198,7 @@
                              alpm_list_t *packages)
 {
 	pmdepend_t depend;
-	alpm_list_t *i, *j, *k;
+	alpm_list_t *i, *j, *k, *l;
 	int found = 0;
 	alpm_list_t *baddeps = NULL;
 	pmdepmissing_t *miss = NULL;
@@ -214,19 +214,18 @@
 		 * listed in the requiredby field.
 		 */
 		for(i = packages; i; i = i->next) {
-			pmpkg_t *tp = i->data;
+			pmpkg_t *newpkg = i->data;
 			pmpkg_t *oldpkg;
-			if(tp == NULL) {
+			if(newpkg == NULL) {
 				_alpm_log(PM_LOG_DEBUG, _("null package found in package list"));
 				continue;
 			}
 
-			if((oldpkg = _alpm_db_get_pkgfromcache(db, tp->name)) == NULL) {
-				_alpm_log(PM_LOG_DEBUG, _("cannot find package installed '%s'"), tp->name);
+			if((oldpkg = _alpm_db_get_pkgfromcache(db, newpkg->name)) == NULL) {
+				_alpm_log(PM_LOG_DEBUG, _("cannot find package installed '%s'"), newpkg->name);
 				continue;
 			}
-			_alpm_db_read(db, oldpkg, INFRQ_DEPENDS);
-			for(j = oldpkg->requiredby; j; j = j->next) {
+			for(j = alpm_pkg_get_requiredby(oldpkg); j; j = j->next) {
 				pmpkg_t *p;
 				found = 0;
 				if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) {
@@ -237,19 +236,55 @@
 					/* this package also in the upgrade list, so don't worry about it */
 					continue;
 				}
-				_alpm_db_read(db, p, INFRQ_DEPENDS);
-				for(k = p->depends; k; k = k->next) {
+				for(k = alpm_pkg_get_depends(p); k; k = k->next) {
 					/* don't break any existing dependencies (possible provides) */
 					_alpm_splitdep(k->data, &depend);					
-					if(_alpm_depcmp(oldpkg, &depend) && !_alpm_depcmp(tp, &depend)) {
-						_alpm_log(PM_LOG_DEBUG, _("checkdeps: updated '%s' won't satisfy a dependency of '%s'"),
-										oldpkg->name, p->name);
-						miss = _alpm_depmiss_new(p->name, PM_DEP_TYPE_REQUIRED, depend.mod,
-									 depend.name, depend.version);
-						if(!_alpm_depmiss_isin(miss, baddeps)) {
-							baddeps = alpm_list_add(baddeps, miss);
-						} else {
-							FREE(miss);
+
+					/* if oldpkg satisfied this dep, and newpkg doesn't */
+					if(_alpm_depcmp(oldpkg, &depend) && !_alpm_depcmp(newpkg, &depend)) {
+						/* we've found a dep that was removed... see if any other package
+						 * still contains/provides the dep */
+						int satisfied = 0;
+						for(l = packages; l; l = l->next) {
+							pmpkg_t *pkg = l->data;
+
+							if(_alpm_depcmp(pkg, &depend)) {
+								_alpm_log(PM_LOG_DEBUG, _("checkdeps: dependency '%s' has moved from '%s' to '%s'"),
+													depend.name, oldpkg->name, pkg->name);
+								satisfied = 1;
+								break;
+							}
+						}
+
+						if(!satisfied) {
+							/* worst case... check installed packages to see if anything else
+							 * satisfies this... */
+							for(l = _alpm_db_get_pkgcache(db, INFRQ_DEPENDS); l; l = l->next) {
+								pmpkg_t *pkg = l->data;
+
+								if(strcmp(pkg->name, oldpkg->name) == 0) {
+									/* well, we know this one fails... skip it */
+									continue;
+								}
+								if(_alpm_depcmp(pkg, &depend)) {
+									_alpm_log(PM_LOG_DEBUG, _("checkdeps: dependency '%s' satisfied by installed package '%s'"),
+														depend.name, pkg->name);
+									satisfied = 1;
+									break;
+								}
+							}
+						}
+
+						if(!satisfied) {
+							_alpm_log(PM_LOG_DEBUG, _("checkdeps: updated '%s' won't satisfy a dependency of '%s'"),
+												oldpkg->name, p->name);
+							miss = _alpm_depmiss_new(p->name, PM_DEP_TYPE_REQUIRED, depend.mod,
+																			 depend.name, depend.version);
+							if(!_alpm_depmiss_isin(miss, baddeps)) {
+								baddeps = alpm_list_add(baddeps, miss);
+							} else {
+								FREE(miss);
+							}
 						}
 					}
 				}
Index: pacman-lib/lib/libalpm/provide.c
diff -u pacman-lib/lib/libalpm/provide.c:1.11 pacman-lib/lib/libalpm/provide.c:1.12
--- pacman-lib/lib/libalpm/provide.c:1.11	Mon Feb 26 03:38:48 2007
+++ pacman-lib/lib/libalpm/provide.c	Thu Mar  1 02:03:05 2007
@@ -45,7 +45,7 @@
 	for(lp = _alpm_db_get_pkgcache(db, INFRQ_DEPENDS); lp; lp = lp->next) {
 		pmpkg_t *info = lp->data;
 
-		if(alpm_list_find_str(info->provides, package)) {
+		if(alpm_list_find_str(alpm_pkg_get_provides(info), package)) {
 			pkgs = alpm_list_add(pkgs, info);
 		}
 	}
Index: pacman-lib/lib/libalpm/versioncmp.c
diff -u pacman-lib/lib/libalpm/versioncmp.c:1.14 pacman-lib/lib/libalpm/versioncmp.c:1.15
--- pacman-lib/lib/libalpm/versioncmp.c:1.14	Sun Feb 18 13:29:29 2007
+++ pacman-lib/lib/libalpm/versioncmp.c	Thu Mar  1 02:03:05 2007
@@ -252,7 +252,7 @@
 	ALPM_LOG_FUNC;
 
   if(strcmp(pkg->name, dep->name) == 0
-	    || alpm_list_find_str(pkg->provides, dep->name)) {
+	    || alpm_list_find_str(alpm_pkg_get_provides(pkg), dep->name)) {
 		if(dep->mod == PM_DEP_MOD_ANY) {
 			equal = 1;
 		} else {




More information about the pacman-dev mailing list