1 /*
2 * Copyright (c) 2016, SUSE LLC.
3 *
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
6 */
7
8 /* weird SUSE stuff. better not use it for your projects. */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <string.h>
14
15 #include "solver.h"
16 #include "solver_private.h"
17 #include "bitmap.h"
18 #include "pool.h"
19 #include "poolvendor.h"
20 #include "util.h"
21
22 Offset
repo_fix_supplements(Repo * repo,Offset provides,Offset supplements,Offset freshens)23 repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens)
24 {
25 Pool *pool = repo->pool;
26 Id id, idp, idl;
27 char buf[1024], *p, *dep;
28 int i, l;
29
30 if (provides)
31 {
32 for (i = provides; repo->idarraydata[i]; i++)
33 {
34 id = repo->idarraydata[i];
35 if (ISRELDEP(id))
36 continue;
37 dep = (char *)pool_id2str(pool, id);
38 if (!strncmp(dep, "locale(", 7) && strlen(dep) < sizeof(buf) - 2)
39 {
40 idp = 0;
41 strcpy(buf + 2, dep);
42 dep = buf + 2 + 7;
43 if ((p = strchr(dep, ':')) != 0 && p != dep)
44 {
45 *p++ = 0;
46 idp = pool_str2id(pool, dep, 1);
47 dep = p;
48 }
49 id = 0;
50 while ((p = strchr(dep, ';')) != 0)
51 {
52 if (p == dep)
53 {
54 dep = p + 1;
55 continue;
56 }
57 *p++ = 0;
58 idl = pool_str2id(pool, dep, 1);
59 idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
60 if (id)
61 id = pool_rel2id(pool, id, idl, REL_OR, 1);
62 else
63 id = idl;
64 dep = p;
65 }
66 if (dep[0] && dep[1])
67 {
68 for (p = dep; *p && *p != ')'; p++)
69 ;
70 *p = 0;
71 idl = pool_str2id(pool, dep, 1);
72 idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
73 if (id)
74 id = pool_rel2id(pool, id, idl, REL_OR, 1);
75 else
76 id = idl;
77 }
78 if (idp)
79 id = pool_rel2id(pool, idp, id, REL_AND, 1);
80 if (id)
81 supplements = repo_addid_dep(repo, supplements, id, 0);
82 }
83 else if ((p = strchr(dep, ':')) != 0 && p != dep && p[1] == '/' && strlen(dep) < sizeof(buf))
84 {
85 strcpy(buf, dep);
86 p = buf + (p - dep);
87 *p++ = 0;
88 idp = pool_str2id(pool, buf, 1);
89 /* strip trailing slashes */
90 l = strlen(p);
91 while (l > 1 && p[l - 1] == '/')
92 p[--l] = 0;
93 id = pool_str2id(pool, p, 1);
94 id = pool_rel2id(pool, idp, id, REL_WITH, 1);
95 id = pool_rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1);
96 supplements = repo_addid_dep(repo, supplements, id, 0);
97 }
98 }
99 }
100 if (supplements)
101 {
102 for (i = supplements; repo->idarraydata[i]; i++)
103 {
104 id = repo->idarraydata[i];
105 if (ISRELDEP(id))
106 continue;
107 dep = (char *)pool_id2str(pool, id);
108 if (!strncmp(dep, "system:modalias(", 16))
109 dep += 7;
110 if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf))
111 {
112 strcpy(buf, dep);
113 p = strchr(buf + 9, ':');
114 if (p && p != buf + 9 && strchr(p + 1, ':'))
115 {
116 *p++ = 0;
117 idp = pool_str2id(pool, buf + 9, 1);
118 p[strlen(p) - 1] = 0;
119 id = pool_str2id(pool, p, 1);
120 id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
121 id = pool_rel2id(pool, idp, id, REL_AND, 1);
122 }
123 else
124 {
125 p = buf + 9;
126 p[strlen(p) - 1] = 0;
127 id = pool_str2id(pool, p, 1);
128 id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
129 }
130 if (id)
131 repo->idarraydata[i] = id;
132 }
133 else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf))
134 {
135 strcpy(buf, dep);
136 id = 0;
137 dep = buf + 11;
138 while ((p = strchr(dep, ':')) != 0)
139 {
140 if (p == dep)
141 {
142 dep = p + 1;
143 continue;
144 }
145 /* argh, allow pattern: prefix. sigh */
146 if (p - dep == 7 && !strncmp(dep, "pattern", 7))
147 {
148 p = strchr(p + 1, ':');
149 if (!p)
150 break;
151 }
152 *p++ = 0;
153 idp = pool_str2id(pool, dep, 1);
154 if (id)
155 id = pool_rel2id(pool, id, idp, REL_AND, 1);
156 else
157 id = idp;
158 dep = p;
159 }
160 if (dep[0] && dep[1])
161 {
162 dep[strlen(dep) - 1] = 0;
163 idp = pool_str2id(pool, dep, 1);
164 if (id)
165 id = pool_rel2id(pool, id, idp, REL_AND, 1);
166 else
167 id = idp;
168 }
169 if (id)
170 repo->idarraydata[i] = id;
171 }
172 else if (!strncmp(dep, "filesystem(", 11) && strlen(dep) < sizeof(buf))
173 {
174 strcpy(buf, dep + 11);
175 if ((p = strrchr(buf, ')')) != 0)
176 *p = 0;
177 id = pool_str2id(pool, buf, 1);
178 id = pool_rel2id(pool, NAMESPACE_FILESYSTEM, id, REL_NAMESPACE, 1);
179 repo->idarraydata[i] = id;
180 }
181 }
182 }
183 if (freshens && repo->idarraydata[freshens])
184 {
185 Id idsupp = 0, idfresh = 0;
186 if (!supplements || !repo->idarraydata[supplements])
187 return freshens;
188 for (i = supplements; repo->idarraydata[i]; i++)
189 {
190 if (!idsupp)
191 idsupp = repo->idarraydata[i];
192 else
193 idsupp = pool_rel2id(pool, idsupp, repo->idarraydata[i], REL_OR, 1);
194 }
195 for (i = freshens; repo->idarraydata[i]; i++)
196 {
197 if (!idfresh)
198 idfresh = repo->idarraydata[i];
199 else
200 idfresh = pool_rel2id(pool, idfresh, repo->idarraydata[i], REL_OR, 1);
201 }
202 if (!idsupp)
203 idsupp = idfresh;
204 else
205 idsupp = pool_rel2id(pool, idsupp, idfresh, REL_AND, 1);
206 supplements = repo_addid_dep(repo, 0, idsupp, 0);
207 }
208 return supplements;
209 }
210
211 Offset
repo_fix_conflicts(Repo * repo,Offset conflicts)212 repo_fix_conflicts(Repo *repo, Offset conflicts)
213 {
214 char buf[1024], *dep;
215 Pool *pool = repo->pool;
216 Id id;
217 int i;
218
219 if (!conflicts)
220 return conflicts;
221 for (i = conflicts; repo->idarraydata[i]; i++)
222 {
223 id = repo->idarraydata[i];
224 if (ISRELDEP(id))
225 continue;
226 dep = (char *)pool_id2str(pool, id);
227 if (!strncmp(dep, "otherproviders(", 15) && dep[15] && strlen(dep) < sizeof(buf) - 2)
228 {
229 strcpy(buf, dep + 15);
230 buf[strlen(buf) - 1] = 0;
231 id = pool_str2id(pool, buf, 1);
232 id = pool_rel2id(pool, NAMESPACE_OTHERPROVIDERS, id, REL_NAMESPACE, 1);
233 repo->idarraydata[i] = id;
234 }
235 }
236 return conflicts;
237 }
238
239 void
repo_rewrite_suse_deps(Solvable * s,Offset freshens)240 repo_rewrite_suse_deps(Solvable *s, Offset freshens)
241 {
242 s->supplements = repo_fix_supplements(s->repo, s->provides, s->supplements, freshens);
243 if (s->conflicts)
244 s->conflicts = repo_fix_conflicts(s->repo, s->conflicts);
245 }
246
247 /**********************************************************************************/
248
249 static inline Id
dep2name(Pool * pool,Id dep)250 dep2name(Pool *pool, Id dep)
251 {
252 while (ISRELDEP(dep))
253 {
254 Reldep *rd = GETRELDEP(pool, dep);
255 dep = rd->name;
256 }
257 return dep;
258 }
259
260 static int
providedbyinstalled_multiversion(Pool * pool,Map * installed,Id n,Id con)261 providedbyinstalled_multiversion(Pool *pool, Map *installed, Id n, Id con)
262 {
263 Id p, pp;
264 Solvable *sn = pool->solvables + n;
265
266 FOR_PROVIDES(p, pp, sn->name)
267 {
268 Solvable *s = pool->solvables + p;
269 if (s->name != sn->name || s->arch != sn->arch)
270 continue;
271 if (!MAPTST(installed, p))
272 continue;
273 if (pool_match_nevr(pool, pool->solvables + p, con))
274 continue;
275 return 1; /* found installed package that doesn't conflict */
276 }
277 return 0;
278 }
279
280 static inline int
providedbyinstalled(Pool * pool,Map * installed,Id dep,int ispatch,Map * multiversionmap)281 providedbyinstalled(Pool *pool, Map *installed, Id dep, int ispatch, Map *multiversionmap)
282 {
283 Id p, pp;
284 FOR_PROVIDES(p, pp, dep)
285 {
286 if (p == SYSTEMSOLVABLE)
287 return -1;
288 if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
289 continue;
290 if (ispatch && multiversionmap && multiversionmap->size && MAPTST(multiversionmap, p) && ISRELDEP(dep))
291 if (providedbyinstalled_multiversion(pool, installed, p, dep))
292 continue;
293 if (MAPTST(installed, p))
294 return 1;
295 }
296 return 0;
297 }
298
299 /* xmap:
300 * 1: installed
301 * 2: conflicts with installed
302 * 8: interesting (only true if installed)
303 * 16: undecided
304 */
305
306 static int
providedbyinstalled_multiversion_xmap(Pool * pool,unsigned char * map,Id n,Id con)307 providedbyinstalled_multiversion_xmap(Pool *pool, unsigned char *map, Id n, Id con)
308 {
309 Id p, pp;
310 Solvable *sn = pool->solvables + n;
311
312 FOR_PROVIDES(p, pp, sn->name)
313 {
314 Solvable *s = pool->solvables + p;
315 if (s->name != sn->name || s->arch != sn->arch)
316 continue;
317 if ((map[p] & 9) != 9)
318 continue;
319 if (pool_match_nevr(pool, pool->solvables + p, con))
320 continue;
321 return 1; /* found installed package that doesn't conflict */
322 }
323 return 0;
324 }
325
326
327 static inline int
providedbyinstalled_xmap(Pool * pool,unsigned char * map,Id dep,int ispatch,Map * multiversionmap)328 providedbyinstalled_xmap(Pool *pool, unsigned char *map, Id dep, int ispatch, Map *multiversionmap)
329 {
330 Id p, pp;
331 int r = 0;
332 FOR_PROVIDES(p, pp, dep)
333 {
334 if (p == SYSTEMSOLVABLE)
335 return 1; /* always boring, as never constraining */
336 if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
337 continue;
338 if (ispatch && multiversionmap && multiversionmap->size && MAPTST(multiversionmap, p) && ISRELDEP(dep))
339 if (providedbyinstalled_multiversion_xmap(pool, map, p, dep))
340 continue;
341 if ((map[p] & 9) == 9)
342 return 9;
343 r |= map[p] & 17;
344 }
345 return r;
346 }
347
348 /* FIXME: this mirrors policy_illegal_vendorchange */
349 static int
pool_illegal_vendorchange(Pool * pool,Solvable * s1,Solvable * s2)350 pool_illegal_vendorchange(Pool *pool, Solvable *s1, Solvable *s2)
351 {
352 Id v1, v2;
353 Id vendormask1, vendormask2;
354
355 if (pool->custom_vendorcheck)
356 return pool->custom_vendorcheck(pool, s1, s2);
357 /* treat a missing vendor as empty string */
358 v1 = s1->vendor ? s1->vendor : ID_EMPTY;
359 v2 = s2->vendor ? s2->vendor : ID_EMPTY;
360 if (v1 == v2)
361 return 0;
362 vendormask1 = pool_vendor2mask(pool, v1);
363 if (!vendormask1)
364 return 1; /* can't match */
365 vendormask2 = pool_vendor2mask(pool, v2);
366 if ((vendormask1 & vendormask2) != 0)
367 return 0;
368 return 1; /* no class matches */
369 }
370
371 /* check if this patch is relevant according to the vendor. To bad that patches
372 * don't have a vendor, so we need to do some careful repo testing. */
373 int
solvable_is_irrelevant_patch(Solvable * s,Map * installedmap)374 solvable_is_irrelevant_patch(Solvable *s, Map *installedmap)
375 {
376 Pool *pool = s->repo->pool;
377 Id con, *conp;
378 int hadpatchpackage = 0;
379 const char *status;
380
381 status = solvable_lookup_str(s, UPDATE_STATUS);
382 if (status && !strcmp(status, "retracted"))
383 return 1;
384 if (!s->conflicts)
385 return 0;
386 conp = s->repo->idarraydata + s->conflicts;
387 while ((con = *conp++) != 0)
388 {
389 Reldep *rd;
390 Id p, pp, p2, pp2;
391 if (!ISRELDEP(con))
392 continue;
393 rd = GETRELDEP(pool, con);
394 if (rd->flags != REL_LT)
395 continue;
396 FOR_PROVIDES(p, pp, con)
397 {
398 Solvable *si;
399 if (!MAPTST(installedmap, p))
400 continue;
401 si = pool->solvables + p;
402 if (!pool_match_nevr(pool, si, con))
403 continue;
404 FOR_PROVIDES(p2, pp2, rd->name)
405 {
406 Solvable *s2 = pool->solvables + p2;
407 if (!pool_match_nevr(pool, s2, rd->name))
408 continue;
409 if (pool_match_nevr(pool, s2, con))
410 continue; /* does not fulfill patch */
411 if (s2->repo == s->repo)
412 {
413 hadpatchpackage = 1;
414 /* ok, we have a package from the patch repo that solves the conflict. check vendor */
415 if (si->vendor == s2->vendor)
416 return 0;
417 if (!pool_illegal_vendorchange(pool, si, s2))
418 return 0;
419 /* vendor change was illegal, ignore conflict */
420 }
421 }
422 }
423 }
424 /* if we didn't find a patchpackage don't claim that the patch is irrelevant */
425 if (!hadpatchpackage)
426 return 0;
427 return 1;
428 }
429
430 /*
431 * solvable_trivial_installable_map - answers if a solvable is installable
432 * without any other installs/deinstalls.
433 * The packages considered to be installed are provided via the
434 * installedmap bitmap. A additional "conflictsmap" bitmap providing
435 * information about the conflicts of the installed packages can be
436 * used for extra speed up. Provide a NULL pointer if you do not
437 * have this information.
438 * Both maps can be created with pool_create_state_maps() or
439 * solver_create_state_maps().
440 *
441 * returns:
442 * 1: solvable is installable without any other package changes
443 * 0: solvable is not installable
444 * -1: solvable is installable, but doesn't constrain any installed packages
445 */
446 int
solvable_trivial_installable_map(Solvable * s,Map * installedmap,Map * conflictsmap,Map * multiversionmap)447 solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *multiversionmap)
448 {
449 Pool *pool = s->repo->pool;
450 Solvable *s2;
451 Id p, *dp;
452 Id *reqp, req;
453 Id *conp, con;
454 int r, interesting = 0;
455
456 if (conflictsmap && MAPTST(conflictsmap, s - pool->solvables))
457 return 0;
458 if (s->requires)
459 {
460 reqp = s->repo->idarraydata + s->requires;
461 while ((req = *reqp++) != 0)
462 {
463 if (req == SOLVABLE_PREREQMARKER)
464 continue;
465 r = providedbyinstalled(pool, installedmap, req, 0, 0);
466 if (!r)
467 return 0;
468 if (r > 0)
469 interesting = 1;
470 }
471 }
472 if (s->conflicts)
473 {
474 int ispatch = 0;
475
476 if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
477 ispatch = 1;
478 conp = s->repo->idarraydata + s->conflicts;
479 while ((con = *conp++) != 0)
480 {
481 if (providedbyinstalled(pool, installedmap, con, ispatch, multiversionmap))
482 {
483 if (ispatch && solvable_is_irrelevant_patch(s, installedmap))
484 return -1;
485 return 0;
486 }
487 if (!interesting && ISRELDEP(con))
488 {
489 con = dep2name(pool, con);
490 if (providedbyinstalled(pool, installedmap, con, ispatch, multiversionmap))
491 interesting = 1;
492 }
493 }
494 if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap))
495 interesting = 0;
496 }
497 if (!conflictsmap)
498 {
499 int i;
500
501 p = s - pool->solvables;
502 for (i = 1; i < pool->nsolvables; i++)
503 {
504 if (!MAPTST(installedmap, i))
505 continue;
506 s2 = pool->solvables + i;
507 if (!s2->conflicts)
508 continue;
509 conp = s2->repo->idarraydata + s2->conflicts;
510 while ((con = *conp++) != 0)
511 {
512 dp = pool_whatprovides_ptr(pool, con);
513 for (; *dp; dp++)
514 if (*dp == p)
515 return 0;
516 }
517 }
518 }
519 return interesting ? 1 : -1;
520 }
521
522 /*
523 * different interface for solvable_trivial_installable_map, where
524 * the information about the installed packages is provided
525 * by a queue.
526 */
527 int
solvable_trivial_installable_queue(Solvable * s,Queue * installed,Map * multiversionmap)528 solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *multiversionmap)
529 {
530 Pool *pool = s->repo->pool;
531 int i;
532 Id p;
533 Map installedmap;
534 int r;
535
536 map_init(&installedmap, pool->nsolvables);
537 for (i = 0; i < installed->count; i++)
538 {
539 p = installed->elements[i];
540 if (p > 0) /* makes it work with decisionq */
541 MAPSET(&installedmap, p);
542 }
543 r = solvable_trivial_installable_map(s, &installedmap, 0, multiversionmap);
544 map_free(&installedmap);
545 return r;
546 }
547
548 /*
549 * different interface for solvable_trivial_installable_map, where
550 * the information about the installed packages is provided
551 * by a repo containing the installed solvables.
552 */
553 int
solvable_trivial_installable_repo(Solvable * s,Repo * installed,Map * multiversionmap)554 solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *multiversionmap)
555 {
556 Pool *pool = s->repo->pool;
557 Id p;
558 Solvable *s2;
559 Map installedmap;
560 int r;
561
562 map_init(&installedmap, pool->nsolvables);
563 FOR_REPO_SOLVABLES(installed, p, s2)
564 MAPSET(&installedmap, p);
565 r = solvable_trivial_installable_map(s, &installedmap, 0, multiversionmap);
566 map_free(&installedmap);
567 return r;
568 }
569
570 /*
571 * pool_trivial_installable - calculate if a set of solvables is
572 * trivial installable without any other installs/deinstalls of
573 * packages not belonging to the set.
574 *
575 * the state is returned in the result queue:
576 * 1: solvable is installable without any other package changes
577 * 0: solvable is not installable
578 * -1: solvable is installable, but doesn't constrain any installed packages
579 */
580
581 void
pool_trivial_installable_multiversionmap(Pool * pool,Map * installedmap,Queue * pkgs,Queue * res,Map * multiversionmap)582 pool_trivial_installable_multiversionmap(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res, Map *multiversionmap)
583 {
584 int i, r, m, did;
585 Id p, *dp, con, *conp, req, *reqp;
586 unsigned char *map;
587 Solvable *s;
588
589 map = solv_calloc(pool->nsolvables, 1);
590 for (p = 1; p < pool->nsolvables; p++)
591 {
592 if (!MAPTST(installedmap, p))
593 continue;
594 map[p] |= 9;
595 s = pool->solvables + p;
596 if (!s->conflicts)
597 continue;
598 conp = s->repo->idarraydata + s->conflicts;
599 while ((con = *conp++) != 0)
600 {
601 dp = pool_whatprovides_ptr(pool, con);
602 for (; *dp; dp++)
603 map[p] |= 2; /* XXX: self conflict ? */
604 }
605 }
606 for (i = 0; i < pkgs->count; i++)
607 map[pkgs->elements[i]] = 16;
608
609 for (i = 0, did = 0; did < pkgs->count; i++, did++)
610 {
611 if (i == pkgs->count)
612 i = 0;
613 p = pkgs->elements[i];
614 if ((map[p] & 16) == 0)
615 continue;
616 if ((map[p] & 2) != 0)
617 {
618 map[p] = 2;
619 continue;
620 }
621 s = pool->solvables + p;
622 m = 1;
623 if (s->requires)
624 {
625 reqp = s->repo->idarraydata + s->requires;
626 while ((req = *reqp++) != 0)
627 {
628 if (req == SOLVABLE_PREREQMARKER)
629 continue;
630 r = providedbyinstalled_xmap(pool, map, req, 0, 0);
631 if (!r)
632 {
633 /* decided and miss */
634 map[p] = 2;
635 did = 0;
636 break;
637 }
638 if (r == 16)
639 break; /* undecided */
640 m |= r; /* 1 | 9 | 17 */
641 }
642 if (req)
643 continue;
644 if ((m & 9) == 9)
645 m = 9;
646 }
647 if (s->conflicts)
648 {
649 int ispatch = 0; /* see solver.c patch handling */
650
651 if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
652 ispatch = 1;
653 conp = s->repo->idarraydata + s->conflicts;
654 while ((con = *conp++) != 0)
655 {
656 if ((providedbyinstalled_xmap(pool, map, con, ispatch, multiversionmap) & 1) != 0)
657 {
658 map[p] = 2;
659 did = 0;
660 break;
661 }
662 if ((m == 1 || m == 17) && ISRELDEP(con))
663 {
664 con = dep2name(pool, con);
665 if ((providedbyinstalled_xmap(pool, map, con, ispatch, multiversionmap) & 1) != 0)
666 m = 9;
667 }
668 }
669 if (con)
670 continue; /* found a conflict */
671 }
672 if (m != map[p])
673 {
674 map[p] = m;
675 did = 0;
676 }
677 }
678 queue_free(res);
679 queue_init_clone(res, pkgs);
680 for (i = 0; i < pkgs->count; i++)
681 {
682 m = map[pkgs->elements[i]];
683 if ((m & 9) == 9)
684 r = 1;
685 else if (m & 1)
686 r = -1;
687 else
688 r = 0;
689 res->elements[i] = r;
690 }
691 free(map);
692 }
693
694 void
pool_trivial_installable(Pool * pool,Map * installedmap,Queue * pkgs,Queue * res)695 pool_trivial_installable(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res)
696 {
697 pool_trivial_installable_multiversionmap(pool, installedmap, pkgs, res, 0);
698 }
699
700 void
solver_trivial_installable(Solver * solv,Queue * pkgs,Queue * res)701 solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res)
702 {
703 Pool *pool = solv->pool;
704 Map installedmap;
705 int i;
706 pool_create_state_maps(pool, &solv->decisionq, &installedmap, 0);
707 pool_trivial_installable_multiversionmap(pool, &installedmap, pkgs, res, solv->multiversion.size ? &solv->multiversion : 0);
708 for (i = 0; i < res->count; i++)
709 if (res->elements[i] != -1)
710 {
711 Solvable *s = pool->solvables + pkgs->elements[i];
712 if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap))
713 res->elements[i] = -1;
714 }
715 map_free(&installedmap);
716 }
717
718 void
solver_printtrivial(Solver * solv)719 solver_printtrivial(Solver *solv)
720 {
721 Pool *pool = solv->pool;
722 Queue in, out;
723 Id p;
724 const char *n;
725 Solvable *s;
726 int i;
727
728 queue_init(&in);
729 for (p = 1, s = pool->solvables + p; p < solv->pool->nsolvables; p++, s++)
730 {
731 n = pool_id2str(pool, s->name);
732 if (strncmp(n, "patch:", 6) != 0 && strncmp(n, "pattern:", 8) != 0)
733 continue;
734 queue_push(&in, p);
735 }
736 if (!in.count)
737 {
738 queue_free(&in);
739 return;
740 }
741 queue_init(&out);
742 solver_trivial_installable(solv, &in, &out);
743 POOL_DEBUG(SOLV_DEBUG_RESULT, "trivial installable status:\n");
744 for (i = 0; i < in.count; i++)
745 POOL_DEBUG(SOLV_DEBUG_RESULT, " %s: %d\n", pool_solvid2str(pool, in.elements[i]), out.elements[i]);
746 POOL_DEBUG(SOLV_DEBUG_RESULT, "\n");
747 queue_free(&in);
748 queue_free(&out);
749 }
750
751
752