libopkg: avoid aggregating multiple identical providers
[oweals/opkg-lede.git] / libopkg / pkg_depends.c
index d741c4ae3f645ede3d42ca51054105e0a347bee7..38ac1b6cbc14fe9160105f14cb8b24dbc00a730b 100644 (file)
@@ -26,7 +26,7 @@
 #include "hash_table.h"
 #include "libbb/libbb.h"
 
-static int parseDepends(compound_depend_t * compound_depend, char *depend_str);
+static int parseDepends(compound_depend_t * compound_depend, char *depend_str, enum depend_type type);
 static depend_t *depend_init(void);
 static char **add_unresolved_dep(pkg_t * pkg, char **the_lost, int ref_ndx);
 static char **merge_unresolved(char **oldstuff, char **newstuff);
@@ -59,9 +59,10 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied,
 {
        pkg_t *satisfier_entry_pkg;
        int i, j, k;
-       int count, found;
+       int found;
        char **the_lost;
        abstract_pkg_t *ab_pkg;
+       compound_depend_t *compound_depend;
 
        /*
         * this is a setup to check for redundant/cyclic dependency checks,
@@ -78,11 +79,10 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied,
        } else {
                ab_pkg->dependencies_checked = 1;       /* mark it for subsequent visits */
        }
-        /**/
-           count =
-           pkg->pre_depends_count + pkg->depends_count +
-           pkg->recommends_count + pkg->suggests_count;
-       if (!count) {
+
+       compound_depend = pkg_get_ptr(pkg, PKG_DEPENDS);
+
+       if (!compound_depend || !compound_depend->type) {
                *unresolved = NULL;
                return 0;
        }
@@ -90,8 +90,7 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied,
        the_lost = NULL;
 
        /* foreach dependency */
-       for (i = 0; i < count; i++) {
-               compound_depend_t *compound_depend = &pkg->depends[i];
+       for (i = 0; compound_depend && compound_depend->type; compound_depend++, i++) {
                depend_t **possible_satisfiers =
                    compound_depend->possibilities;;
                found = 0;
@@ -322,34 +321,30 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied,
 */
 static int is_pkg_a_replaces(pkg_t * pkg_scout, pkg_t * pkg)
 {
-       int i;
-       int replaces_count = pkg->replaces_count;
-       abstract_pkg_t **replaces;
+       abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES);
 
-       if (pkg->replaces_count == 0)   // No replaces, it's surely a conflict
+       if (!replaces || !*replaces)
                return 0;
 
-       replaces = pkg->replaces;
-
-       for (i = 0; i < replaces_count; i++) {
-               if (strcmp(pkg_scout->name, pkg->replaces[i]->name) == 0) {     // Found
+       while (*replaces) {
+               if (strcmp(pkg_scout->name, (*replaces)->name) == 0) {  // Found
                        opkg_msg(DEBUG2, "Seems I've found a replace %s %s\n",
-                                pkg_scout->name, pkg->replaces[i]->name);
+                                pkg_scout->name, (*replaces)->name);
                        return 1;
                }
+               replaces++;
        }
-       return 0;
 
+       return 0;
 }
 
 pkg_vec_t *pkg_hash_fetch_conflicts(pkg_t * pkg)
 {
        pkg_vec_t *installed_conflicts, *test_vec;
-       compound_depend_t *conflicts;
+       compound_depend_t *conflicts, *conflict;
        depend_t **possible_satisfiers;
        depend_t *possible_satisfier;
-       int i, j, k;
-       int count;
+       int j, k;
        abstract_pkg_t *ab_pkg;
        pkg_t **pkg_scouts;
        pkg_t *pkg_scout;
@@ -364,17 +359,14 @@ pkg_vec_t *pkg_hash_fetch_conflicts(pkg_t * pkg)
                return (pkg_vec_t *) NULL;
        }
 
-       conflicts = pkg->conflicts;
+       conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS);
        if (!conflicts) {
                return (pkg_vec_t *) NULL;
        }
        installed_conflicts = pkg_vec_alloc();
 
-       count = pkg->conflicts_count;
-
        /* foreach conflict */
-       for (i = 0; i < pkg->conflicts_count; i++) {
-
+       for (conflict = conflicts; conflict->type; conflict++ ) {
                possible_satisfiers = conflicts->possibilities;
 
                /* foreach possible satisfier */
@@ -518,10 +510,10 @@ static int is_pkg_in_pkg_vec(pkg_vec_t * vec, pkg_t * pkg)
        int i;
        char *arch1, *arch2;
        pkg_t **pkgs = vec->pkgs;
-       arch1 = pkg_get_string(pkg, PKG_ARCHITECTURE);
+       arch1 = pkg_get_architecture(pkg);
 
        for (i = 0; i < vec->len; i++) {
-               arch2 = pkg_get_string(*(pkgs + i), PKG_ARCHITECTURE);
+               arch2 = pkg_get_architecture(*(pkgs + i));
 
                if ((strcmp(pkg->name, (*(pkgs + i))->name) == 0)
                    && (pkg_compare_versions(pkg, *(pkgs + i)) == 0)
@@ -537,17 +529,15 @@ static int is_pkg_in_pkg_vec(pkg_vec_t * vec, pkg_t * pkg)
  */
 int pkg_replaces(pkg_t * pkg, pkg_t * replacee)
 {
-       abstract_pkg_t **replaces = pkg->replaces;
-       int replaces_count = pkg->replaces_count;
-       int replacee_provides_count = replacee->provides_count;
-       int i, j;
-       for (i = 0; i < replaces_count; i++) {
-               abstract_pkg_t *abstract_replacee = replaces[i];
-               for (j = 0; j < replacee_provides_count; j++) {
-                       if (replacee->provides[j] == abstract_replacee)
+       abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES);
+       abstract_pkg_t **provides = pkg_get_ptr(replacee, PKG_PROVIDES);
+       abstract_pkg_t **r, **p;
+
+       for (r = replaces; r && *r; r++)
+               for (p = provides; p && *p; p++)
+                       if (*r == *p)
                                return 1;
-               }
-       }
+
        return 0;
 }
 
@@ -557,12 +547,14 @@ int pkg_replaces(pkg_t * pkg, pkg_t * replacee)
  */
 int pkg_conflicts_abstract(pkg_t * pkg, abstract_pkg_t * conflictee)
 {
-       compound_depend_t *conflicts = pkg->conflicts;
-       int conflicts_count = pkg->conflicts_count;
-       int i, j;
-       for (i = 0; i < conflicts_count; i++) {
-               int possibility_count = conflicts[i].possibility_count;
-               struct depend **possibilities = conflicts[i].possibilities;
+       compound_depend_t *conflicts, *conflict;
+
+       conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS);
+
+       int j;
+       for (conflict = conflicts; conflict->type; conflict++) {
+               int possibility_count = conflict->possibility_count;
+               struct depend **possibilities = conflict->possibilities;
                for (j = 0; j < possibility_count; j++) {
                        if (possibilities[j]->pkg == conflictee) {
                                return 1;
@@ -578,22 +570,22 @@ int pkg_conflicts_abstract(pkg_t * pkg, abstract_pkg_t * conflictee)
  */
 int pkg_conflicts(pkg_t * pkg, pkg_t * conflictee)
 {
-       compound_depend_t *conflicts = pkg->conflicts;
-       int conflicts_count = pkg->conflicts_count;
-       abstract_pkg_t **conflictee_provides = conflictee->provides;
-       int conflictee_provides_count = conflictee->provides_count;
-       int i, j, k;
+       int j;
        int possibility_count;
        struct depend **possibilities;
-       abstract_pkg_t *possibility;
+       compound_depend_t *conflicts, *conflict;
+       abstract_pkg_t **conflictee_provides, **provider, *possibility;
+
+       conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS);
+       conflictee_provides = pkg_get_ptr(conflictee, PKG_PROVIDES);
 
-       for (i = 0; i < conflicts_count; i++) {
-               possibility_count = conflicts[i].possibility_count;
-               possibilities = conflicts[i].possibilities;
+       for (conflict = conflicts; conflict->type; conflict++) {
+               possibility_count = conflict->possibility_count;
+               possibilities = conflict->possibilities;
                for (j = 0; j < possibility_count; j++) {
                        possibility = possibilities[j]->pkg;
-                       for (k = 0; k < conflictee_provides_count; k++) {
-                               if (possibility == conflictee_provides[k]) {
+                       for (provider = conflictee_provides; provider && *provider; provider++) {
+                               if (possibility == *provider) {
                                        return 1;
                                }
                        }
@@ -647,8 +639,167 @@ 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;
+       abstract_pkg_t **provides = pkg_get_ptr(pkg, PKG_PROVIDES);
+
+       if (!provides) {
+               provides = calloc(2, sizeof(abstract_pkg_t *));
+
+               if (!provides) {
+                       if (count)
+                               *count = 0;
+
+                       return NULL;
+               }
+
+               ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
+
+               if (!ab_pkg->pkgs)
+                       ab_pkg->pkgs = pkg_vec_alloc();
+
+               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;
+
+               if (count)
+                       *count = 2;
+
+               pkg_set_ptr(pkg, PKG_PROVIDES, provides);
+       }
+       else if (count) {
+               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;
+}
+
+void parse_providelist(pkg_t *pkg, char *list)
+{
+       int count = 0;
+       char *item, *tok;
+       abstract_pkg_t *ab_pkg, *provided_abpkg, **tmp, **provides;
+
+       provides = init_providelist(pkg, &count);
+       ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
+
+       if (!provides || !ab_pkg)
+               return;
+
+       for (item = strtok_r(list, ", ", &tok); item;
+            count++, item = strtok_r(NULL, ", ", &tok)) {
+               tmp = realloc(provides, sizeof(abstract_pkg_t *) * (count + 1));
+
+               if (!tmp)
+                       break;
+
+               provided_abpkg = ensure_abstract_pkg_by_name(item);
+
+               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;
+       }
+
+       provides[count - 1] = NULL;
+
+       pkg_set_ptr(pkg, PKG_PROVIDES, provides);
+}
+
+void parse_replacelist(pkg_t *pkg, char *list)
+{
+       int count;
+       char *item, *tok;
+       abstract_pkg_t *ab_pkg, *old_abpkg, **tmp, **replaces = NULL;
+
+       ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
+
+       if (!ab_pkg->pkgs)
+               ab_pkg->pkgs = pkg_vec_alloc();
+
+       abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
+
+       for (count = 1, item = strtok_r(list, ", ", &tok);
+            item;
+            count++, item = strtok_r(NULL, ", ", &tok), count++) {
+               tmp = realloc(replaces, sizeof(abstract_pkg_t *) * (count + 1));
+
+               if (!tmp)
+                       break;
+
+               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();
+
+               /* if a package pkg both replaces and conflicts old_abpkg,
+                * then add it to the replaced_by vector so that old_abpkg
+                * will be upgraded to ab_pkg automatically */
+               if (pkg_conflicts_abstract(pkg, old_abpkg))
+                       abstract_pkg_vec_insert(old_abpkg->replaced_by, ab_pkg);
+
+               replaces = tmp;
+               replaces[count - 1] = old_abpkg;
+       }
+
+       if (!replaces)
+               return;
+
+       replaces[count - 1] = NULL;
+
+       pkg_set_ptr(pkg, PKG_REPLACES, replaces);
+}
+
 void buildProvides(abstract_pkg_t * ab_pkg, pkg_t * pkg)
 {
+#if 0
        int i;
 
        /* every pkg provides itself */
@@ -656,7 +807,6 @@ void buildProvides(abstract_pkg_t * ab_pkg, pkg_t * pkg)
        abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
        pkg->provides = xcalloc(pkg->provides_count, sizeof(abstract_pkg_t *));
        pkg->provides[0] = ab_pkg;
-
        for (i = 1; i < pkg->provides_count; i++) {
                abstract_pkg_t *provided_abpkg =
                    ensure_abstract_pkg_by_name(pkg->provides_str[i - 1]);
@@ -668,12 +818,14 @@ void buildProvides(abstract_pkg_t * ab_pkg, pkg_t * pkg)
        }
        if (pkg->provides_str)
                free(pkg->provides_str);
+#endif
 }
 
 void buildConflicts(pkg_t * pkg)
 {
+       /*
        int i;
-       compound_depend_t *conflicts;
+       compound_depend_t *conflicts, *conflict;
 
        if (!pkg->conflicts_count)
                return;
@@ -688,10 +840,12 @@ void buildConflicts(pkg_t * pkg)
        }
        if (pkg->conflicts_str)
                free(pkg->conflicts_str);
+               */
 }
 
 void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg)
 {
+#if 0
        int i;
 
        if (!pkg->replaces_count)
@@ -717,10 +871,60 @@ void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg)
 
        if (pkg->replaces_str)
                free(pkg->replaces_str);
+#endif
+}
+
+void parse_deplist(pkg_t *pkg, enum depend_type type, char *list)
+{
+       int id, count;
+       char *item, *tok;
+       compound_depend_t *tmp, *deps;
+
+       switch (type)
+       {
+       case DEPEND:
+       case PREDEPEND:
+       case RECOMMEND:
+       case SUGGEST:
+       case GREEDY_DEPEND:
+               id = PKG_DEPENDS;
+               break;
+
+       case CONFLICTS:
+               id = PKG_CONFLICTS;
+               break;
+
+       default:
+               return;
+       }
+
+       deps = pkg_get_ptr(pkg, id);
+
+       for (tmp = deps, count = 1; tmp && tmp->type; tmp++)
+               count++;
+
+       for (item = strtok_r(list, ",", &tok); item; item = strtok_r(NULL, ",", &tok), count++) {
+               tmp = realloc(deps, sizeof(compound_depend_t) * (count + 1));
+
+               if (!tmp)
+                       break;
+
+               deps = tmp;
+
+               memset(deps + count - 1, 0, sizeof(compound_depend_t));
+               parseDepends(deps + count - 1, item, type);
+       }
+
+       if (!deps)
+               return;
+
+       memset(deps + count - 1, 0, sizeof(compound_depend_t));
+       pkg_set_ptr(pkg, id, deps);
 }
 
 void buildDepends(pkg_t * pkg)
 {
+#if 0
        unsigned int count;
        int i;
        compound_depend_t *depends;
@@ -767,6 +971,8 @@ void buildDepends(pkg_t * pkg)
        }
        if (pkg->suggests_str)
                free(pkg->suggests_str);
+
+#endif
 }
 
 const char *constraint_to_str(enum version_constraint c)
@@ -798,11 +1004,19 @@ char *pkg_depend_str(pkg_t * pkg, int idx)
        int i;
        unsigned int len;
        char *str;
-       compound_depend_t *cdep;
+       compound_depend_t *cdep = NULL, *p;
        depend_t *dep;
 
+       for (i = 0, p = pkg_get_ptr(pkg, PKG_DEPENDS); p && p->type; i++, p++)
+               if (i == idx) {
+                       cdep = p;
+                       break;
+               }
+
+       if (!cdep)
+               return NULL;
+
        len = 0;
-       cdep = &pkg->depends[idx];
 
        /* calculate string length */
        for (i = 0; i < cdep->possibility_count; i++) {
@@ -846,16 +1060,12 @@ char *pkg_depend_str(pkg_t * pkg, int idx)
 void buildDependedUponBy(pkg_t * pkg, abstract_pkg_t * ab_pkg)
 {
        compound_depend_t *depends;
-       int count, othercount;
-       int i, j;
+       int othercount;
+       int j;
        abstract_pkg_t *ab_depend;
        abstract_pkg_t **temp;
 
-       count = pkg->pre_depends_count +
-           pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
-
-       for (i = 0; i < count; i++) {
-               depends = &pkg->depends[i];
+       for (depends = pkg_get_ptr(pkg, PKG_DEPENDS); depends && depends->type; depends++) {
                if (depends->type != PREDEPEND
                    && depends->type != DEPEND && depends->type != RECOMMEND)
                        continue;
@@ -896,99 +1106,79 @@ static depend_t *depend_init(void)
        return d;
 }
 
-static int parseDepends(compound_depend_t * compound_depend, char *depend_str)
+static int parseDepends(compound_depend_t * compound_depend, char *depend_str, enum depend_type type)
 {
-       char *pkg_name, buffer[2048];
-       unsigned int num_of_ors = 0;
        int i;
-       char *src, *dest;
-       depend_t **possibilities;
+       char *depend, *name, *vstr, *rest, *tok = NULL;
+       depend_t **possibilities = NULL, **tmp;
 
-       /* first count the number of ored possibilities for satisfying dependency */
-       src = depend_str;
-       while (*src)
-               if (*src++ == '|')
-                       num_of_ors++;
+       compound_depend->type = type;
 
-       compound_depend->type = DEPEND;
+       for (i = 0, depend = strtok_r(depend_str, "|", &tok); depend; i++, depend = strtok_r(NULL, "|", &tok)) {
+               name = strtok(depend, " ");
+               rest = strtok(NULL, "\n");
 
-       compound_depend->possibility_count = num_of_ors + 1;
-       possibilities = xcalloc((num_of_ors + 1), sizeof(depend_t *));
-       compound_depend->possibilities = possibilities;
+               tmp = realloc(possibilities, sizeof(tmp) * (i + 1));
+
+               if (!tmp)
+                       return -1;
 
-       src = depend_str;
-       for (i = 0; i < num_of_ors + 1; i++) {
+               possibilities = tmp;
                possibilities[i] = depend_init();
-               /* gobble up just the name first */
-               dest = buffer;
-               while (*src &&
-                      !isspace(*src) &&
-                      (*src != '(') && (*src != '*') && (*src != '|'))
-                       *dest++ = *src++;
-               *dest = '\0';
-               pkg_name = trim_xstrdup(buffer);
-
-               /* now look at possible version info */
-
-               /* skip to next chars */
-               if (isspace(*src))
-                       while (*src && isspace(*src))
-                               src++;
-
-               /* extract constraint and version */
-               if (*src == '(') {
-                       src++;
-                       if (!strncmp(src, "<<", 2)) {
+               possibilities[i]->pkg = ensure_abstract_pkg_by_name(name);
+
+               if (rest && *rest == '(') {
+                       vstr = strtok(rest + 1, ")");
+
+                       if (!strncmp(vstr, "<<", 2)) {
                                possibilities[i]->constraint = EARLIER;
-                               src += 2;
-                       } else if (!strncmp(src, "<=", 2)) {
+                               vstr += 2;
+                       } else if (!strncmp(vstr, "<=", 2)) {
                                possibilities[i]->constraint = EARLIER_EQUAL;
-                               src += 2;
-                       } else if (!strncmp(src, ">=", 2)) {
+                               vstr += 2;
+                       } else if (!strncmp(vstr, ">=", 2)) {
                                possibilities[i]->constraint = LATER_EQUAL;
-                               src += 2;
-                       } else if (!strncmp(src, ">>", 2)) {
+                               vstr += 2;
+                       } else if (!strncmp(vstr, ">>", 2)) {
                                possibilities[i]->constraint = LATER;
-                               src += 2;
-                       } else if (!strncmp(src, "=", 1)) {
+                               vstr += 2;
+                       } else if (!strncmp(vstr, "=", 1)) {
                                possibilities[i]->constraint = EQUAL;
-                               src++;
+                               vstr++;
                        }
                        /* should these be here to support deprecated designations; dpkg does */
-                       else if (!strncmp(src, "<", 1)) {
+                       else if (!strncmp(vstr, "<", 1)) {
                                possibilities[i]->constraint = EARLIER_EQUAL;
-                               src++;
-                       } else if (!strncmp(src, ">", 1)) {
+                               vstr++;
+                       } else if (!strncmp(vstr, ">", 1)) {
                                possibilities[i]->constraint = LATER_EQUAL;
-                               src++;
+                               vstr++;
                        }
 
-                       /* now we have any constraint, pass space to version string */
-                       while (isspace(*src))
-                               src++;
-
-                       /* this would be the version string */
-                       dest = buffer;
-                       while (*src && *src != ')')
-                               *dest++ = *src++;
-                       *dest = '\0';
-
-                       possibilities[i]->version = trim_xstrdup(buffer);
+                       possibilities[i]->version = trim_xstrdup(vstr);
+                       rest = strtok(NULL, " ");
+               }
+               else {
+                       rest = strtok(rest, " ");
                }
-               /* hook up the dependency to its abstract pkg */
-               possibilities[i]->pkg = ensure_abstract_pkg_by_name(pkg_name);
-
-               free(pkg_name);
 
-               /* now get past the ) and any possible | chars */
-               while (*src &&
-                      (isspace(*src) || (*src == ')') || (*src == '|')))
-                       src++;
-               if (*src == '*') {
+               if (rest && *rest == '*')
                        compound_depend->type = GREEDY_DEPEND;
-                       src++;
-               }
        }
 
+       compound_depend->possibility_count = i;
+       compound_depend->possibilities = possibilities;
+
        return 0;
 }
+
+compound_depend_t *pkg_get_depends(pkg_t *pkg, enum depend_type type)
+{
+       compound_depend_t *dep;
+
+       for (dep = pkg_get_ptr(pkg, PKG_DEPENDS); dep && dep->type; dep++)
+               if (type == UNSPEC || dep->type == type)
+                       return dep;
+
+       return NULL;
+}