31 #include "xbps_api_impl.h"
50 TAILQ_ENTRY(pkgdep) pkgdep_entries;
55 static TAILQ_HEAD(pkgdep_head, pkgdep) pkgdep_list =
56 TAILQ_HEAD_INITIALIZER(pkgdep_list);
58 static struct pkgdep *
59 pkgdep_find(const
char *pkg)
61 struct pkgdep *pd = NULL, *pd_new = NULL;
62 const char *pkgver, *tract;
64 TAILQ_FOREACH_SAFE(pd, &pkgdep_list, pkgdep_entries, pd_new) {
69 prop_dictionary_get_cstring_nocopy(pd->d,
70 "transaction", &tract);
72 if (strcmp(tract,
"remove") == 0)
75 prop_dictionary_get_cstring_nocopy(pd->d,
"pkgver", &pkgver);
76 if (strcmp(pkgver, pkg) == 0)
91 pkgdep_find_idx(
const char *pkg)
93 struct pkgdep *pd, *pd_new;
95 const char *pkgver, *tract;
97 TAILQ_FOREACH_SAFE(pd, &pkgdep_list, pkgdep_entries, pd_new) {
103 prop_dictionary_get_cstring_nocopy(pd->d,
104 "transaction", &tract);
106 if (strcmp(tract,
"remove") == 0) {
111 prop_dictionary_get_cstring_nocopy(pd->d,
"pkgver", &pkgver);
112 if (strcmp(pkgver, pkg) == 0)
128 pkgdep_release(
struct pkgdep *pd)
135 static struct pkgdep *
136 pkgdep_alloc(prop_dictionary_t d,
const char *pkg)
140 pd = malloc(
sizeof(*pd));
143 pd->name = strdup(pkg);
149 pkgdep_end(prop_array_t sorted)
153 while ((pd = TAILQ_FIRST(&pkgdep_list)) != NULL) {
154 TAILQ_REMOVE(&pkgdep_list, pd, pkgdep_entries);
155 if (sorted != NULL && pd->d != NULL)
156 prop_array_add(sorted, pd->d);
165 prop_array_t pkg_rundeps,
166 prop_array_t unsorted)
168 prop_dictionary_t curpkgd;
169 struct pkgdep *lpd, *pdn;
170 const char *str, *tract;
171 ssize_t pkgdepidx, curpkgidx;
175 xbps_dbg_printf_append(xhp,
"\n");
176 curpkgidx = pkgdep_find_idx(pd->name);
179 for (i = idx; i < prop_array_count(pkg_rundeps); i++) {
180 prop_array_get_cstring_nocopy(pkg_rundeps, i, &str);
181 xbps_dbg_printf(xhp,
" Required dependency '%s': ", str);
183 pdn = pkgdep_find(str);
191 xbps_dbg_printf_append(xhp,
"installed.\n");
192 lpd = pkgdep_alloc(NULL, str);
193 TAILQ_INSERT_TAIL(&pkgdep_list, lpd, pkgdep_entries);
195 }
else if (pdn != NULL && pdn->d == NULL) {
200 xbps_dbg_printf_append(xhp,
"installed.\n");
203 if (((curpkgd = xbps_find_pkg_in_array(unsorted, str)) == NULL) &&
204 ((curpkgd = xbps_find_virtualpkg_in_array(xhp, unsorted, str)) == NULL)) {
208 prop_dictionary_get_cstring_nocopy(curpkgd,
209 "transaction", &tract);
211 lpd = pkgdep_alloc(curpkgd, str);
218 TAILQ_INSERT_TAIL(&pkgdep_list, lpd, pkgdep_entries);
220 xbps_dbg_printf_append(xhp,
"added into the tail, "
221 "checking again...\n");
227 pkgdepidx = pkgdep_find_idx(str);
232 if (pkgdepidx < curpkgidx) {
233 xbps_dbg_printf_append(xhp,
"already sorted.\n");
240 TAILQ_REMOVE(&pkgdep_list, pdn, pkgdep_entries);
242 TAILQ_INSERT_BEFORE(pd, lpd, pkgdep_entries);
243 xbps_dbg_printf_append(xhp,
244 "added before `%s'.\n", pd->name);
254 prop_array_t provides, sorted, unsorted, rundeps;
257 size_t i, j, ndeps = 0, cnt = 0;
258 const char *pkgname, *pkgver, *tract, *vpkgdep;
262 if ((sorted = prop_array_create()) == NULL)
267 if (!prop_dictionary_set(xhp->
transd,
"packages", sorted)) {
274 unsorted = prop_dictionary_get(xhp->
transd,
"unsorted_deps");
275 if (prop_array_count(unsorted) == 0) {
276 prop_dictionary_set(xhp->
transd,
"packages", sorted);
277 prop_object_release(sorted);
284 ndeps = prop_array_count(unsorted);
289 for (i = 0; i < ndeps; i++) {
291 obj = prop_array_get(unsorted, i);
292 prop_dictionary_get_cstring_nocopy(obj,
"pkgname", &pkgname);
293 prop_dictionary_get_cstring_nocopy(obj,
"pkgver", &pkgver);
294 prop_dictionary_get_cstring_nocopy(obj,
"transaction", &tract);
295 provides = prop_dictionary_get(obj,
"provides");
296 xbps_dbg_printf(xhp,
"Sorting package '%s' (%s): ", pkgver, tract);
304 for (j = 0; j < prop_array_count(provides); j++) {
305 prop_array_get_cstring_nocopy(provides,
307 pd = pkgdep_find(vpkgdep);
309 xbps_dbg_printf_append(xhp,
"already "
310 "sorted via `%s' vpkg.", vpkgdep);
316 if (!vpkg_found && (pd = pkgdep_find(pkgver)) == NULL) {
320 pd = pkgdep_alloc(obj, pkgver);
326 if (strcmp(tract,
"remove") == 0) {
327 xbps_dbg_printf_append(xhp,
"added into head.\n");
328 TAILQ_INSERT_HEAD(&pkgdep_list, pd,
333 xbps_dbg_printf_append(xhp,
"added into tail.");
334 TAILQ_INSERT_TAIL(&pkgdep_list, pd,
342 rundeps = prop_dictionary_get(obj,
"run_depends");
343 if (rundeps == NULL || prop_array_count(rundeps) == 0) {
344 xbps_dbg_printf_append(xhp,
"\n");
351 if ((rv = sort_pkg_rundeps(xhp, pd, rundeps, unsorted)) != 0) {
367 assert(cnt == prop_array_count(unsorted));
372 prop_dictionary_remove(xhp->
transd,
"unsorted_deps");
375 prop_dictionary_remove(xhp->
transd,
"packages");
377 prop_object_release(sorted);