libopkg: avoid aggregating multiple identical providers
[oweals/opkg-lede.git] / libopkg / pkg_depends.c
index 06519e1b3f3827308df8f30950aa4f1a1668c469..38ac1b6cbc14fe9160105f14cb8b24dbc00a730b 100644 (file)
@@ -639,6 +639,30 @@ char **add_unresolved_dep(pkg_t * pkg, char **the_lost, int ref_ndx)
        return resized;
 }
 
+static void flag_related_packages(pkg_t *pkg, int state_flags)
+{
+       int i, j;
+       compound_depend_t *deps;
+
+       for (deps = pkg_get_ptr(pkg, PKG_DEPENDS), i = 0; deps && deps[i].type; i++)
+               for (j = 0; j < deps[i].possibility_count; j++) {
+                       if ((deps[i].possibilities[j]->pkg->state_flag & state_flags) != state_flags) {
+                               opkg_msg(DEBUG, "propagating pkg flag to dependent abpkg %s\n",
+                                        deps[i].possibilities[j]->pkg->name);
+                               deps[i].possibilities[j]->pkg->state_flag |= state_flags;
+                       }
+               }
+
+       for (deps = pkg_get_ptr(pkg, PKG_CONFLICTS), i = 0; deps && deps[i].type; i++)
+               for (j = 0; j < deps[i].possibility_count; j++) {
+                       if ((deps[i].possibilities[j]->pkg->state_flag & state_flags) != state_flags) {
+                               opkg_msg(DEBUG, "propagating pkg flag to conflicting abpkg %s\n",
+                                        deps[i].possibilities[j]->pkg->name);
+                               deps[i].possibilities[j]->pkg->state_flag |= state_flags;
+                       }
+               }
+}
+
 abstract_pkg_t **init_providelist(pkg_t *pkg, int *count)
 {
        abstract_pkg_t *ab_pkg;
@@ -659,7 +683,8 @@ abstract_pkg_t **init_providelist(pkg_t *pkg, int *count)
                if (!ab_pkg->pkgs)
                        ab_pkg->pkgs = pkg_vec_alloc();
 
-               abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
+               if (!abstract_pkg_vec_contains(ab_pkg->provided_by, ab_pkg))
+                       abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
 
                provides[0] = ab_pkg;
                provides[1] = NULL;
@@ -670,10 +695,20 @@ abstract_pkg_t **init_providelist(pkg_t *pkg, int *count)
                pkg_set_ptr(pkg, PKG_PROVIDES, provides);
        }
        else if (count) {
-               for (*count = 1; *provides; provides++)
+               for (*count = 1; *provides; provides++) {
+                       if (pkg->state_flag & SF_NEED_DETAIL) {
+                               if (!((*provides)->state_flag & SF_NEED_DETAIL)) {
+                                       opkg_msg(DEBUG, "propagating pkg flag to provided abpkg %s\n",
+                                                (*provides)->name);
+                                       (*provides)->state_flag |= SF_NEED_DETAIL;
+                               }
+                       }
                        (*count)++;
+               }
        }
 
+       flag_related_packages(pkg, SF_NEED_DETAIL);
+
        return provides;
 }
 
@@ -698,7 +733,8 @@ void parse_providelist(pkg_t *pkg, char *list)
 
                provided_abpkg = ensure_abstract_pkg_by_name(item);
 
-               abstract_pkg_vec_insert(provided_abpkg->provided_by, ab_pkg);
+               if (!abstract_pkg_vec_contains(provided_abpkg->provided_by, ab_pkg))
+                       abstract_pkg_vec_insert(provided_abpkg->provided_by, ab_pkg);
 
                provides = tmp;
                provides[count - 1] = provided_abpkg;
@@ -732,6 +768,14 @@ void parse_replacelist(pkg_t *pkg, char *list)
 
                old_abpkg = ensure_abstract_pkg_by_name(item);
 
+               if (pkg->state_flag & SF_NEED_DETAIL) {
+                       if (!(old_abpkg->state_flag & SF_NEED_DETAIL)) {
+                               opkg_msg(DEBUG, "propagating pkg flag to replaced abpkg %s\n",
+                                        old_abpkg->name);
+                               old_abpkg->state_flag |= SF_NEED_DETAIL;
+                       }
+               }
+
                if (!old_abpkg->replaced_by)
                        old_abpkg->replaced_by = abstract_pkg_vec_alloc();