2 * dselect - Debian package maintenance user interface
3 * pkgsublist.cc - status modification and recursive package list handling
5 * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
7 * This is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include <dpkg/i18n.h>
29 #include <dpkg/dpkg.h>
30 #include <dpkg/dpkg-db.h>
35 void packagelist::add(pkginfo
*pkg
) {
36 if (debug
) fprintf(debug
,"packagelist[%p]::add(pkginfo %s)\n",this,pkg
->name
);
37 if (!recursive
|| // never add things to top level
38 !pkg
->clientdata
|| // don't add pure virtual packages
39 pkg
->clientdata
->uprec
) // don't add ones already in the recursive list
41 if (debug
) fprintf(debug
,"packagelist[%p]::add(pkginfo %s) adding\n",this,pkg
->name
);
42 perpackagestate
*state
= &datatable
[nitems
];
44 state
->direct
= state
->original
= pkg
->clientdata
->selected
;
45 state
->suggested
= state
->selected
= pkg
->clientdata
->selected
;
46 state
->spriority
= sp_inherit
; state
->dpriority
= dp_none
;
47 state
->uprec
= pkg
->clientdata
;
48 state
->relations
.init();
49 pkg
->clientdata
= state
;
54 void packagelist::add(pkginfo
*pkg
, pkginfo::pkgwant nw
) {
55 if (debug
) fprintf(debug
,"packagelist[%p]::add(pkginfo %s, %s)\n",
56 this, pkg
->name
, wantstrings
[nw
]);
57 add(pkg
); if (!pkg
->clientdata
) return;
58 pkg
->clientdata
->direct
= nw
;
60 np
= would_like_to_install(nw
,pkg
) ? sp_selecting
: sp_deselecting
;
61 if (pkg
->clientdata
->spriority
> np
) return;
62 if (debug
) fprintf(debug
,"packagelist[%p]::add(pkginfo %s, %s) setting\n",
63 this, pkg
->name
, wantstrings
[nw
]);
64 pkg
->clientdata
->suggested
= pkg
->clientdata
->selected
= nw
;
65 pkg
->clientdata
->spriority
= np
;
69 void packagelist::add(pkginfo
*pkg
, const char *extrainfo
, showpriority showimp
) {
71 fprintf(debug
,"packagelist[%p]::add(pkginfo %s, \"...\", showpriority %d)\n",
72 this,pkg
->name
,showimp
);
73 add(pkg
); if (!pkg
->clientdata
) return;
74 if (pkg
->clientdata
->dpriority
< showimp
) pkg
->clientdata
->dpriority
= showimp
;
75 pkg
->clientdata
->relations(extrainfo
);
76 pkg
->clientdata
->relations
.terminate();
79 int packagelist::alreadydone(doneent
**done
, void *check
) {
80 doneent
*search
= *done
;
82 while (search
&& search
->dep
!= check
)
83 search
= search
->next
;
85 if (debug
) fprintf(debug
,"packagelist[%p]::alreadydone(%p,%p) new\n",
94 void packagelist::addunavailable(deppossi
*possi
) {
95 if (debug
) fprintf(debug
,"packagelist[%p]::addunavail(%p)\n",this,possi
);
97 if (!recursive
) return;
98 if (alreadydone(&unavdone
,possi
)) return;
100 assert(possi
->up
->up
->clientdata
);
101 assert(possi
->up
->up
->clientdata
->uprec
);
103 varbuf
& vb
= possi
->up
->up
->clientdata
->relations
;
105 vb(_(" does not appear to be available\n"));
108 int packagelist::add(dependency
*depends
, showpriority displayimportance
) {
109 if (debug
) fprintf(debug
,"packagelist[%p]::add(dependency[%p])\n",this,depends
);
111 if (alreadydone(&depsdone
,depends
)) return 0;
113 const char *comma
= "";
115 info(depends
->up
->name
);
117 info(gettext(relatestrings
[depends
->type
]));
120 for (possi
=depends
->list
;
122 possi
=possi
->next
, comma
=(possi
&& possi
->next
? ", " : _(" or "))) {
124 info(possi
->ed
->name
);
125 if (possi
->verrel
!= dvr_none
) {
126 switch (possi
->verrel
) {
127 case dvr_earlierequal
: info(" (<= "); break;
128 case dvr_laterequal
: info(" (>= "); break;
129 case dvr_earlierstrict
: info(" (<< "); break;
130 case dvr_laterstrict
: info(" (>> "); break;
131 case dvr_exact
: info(" (= "); break;
132 default: internerr("unknown verrel");
134 info(versiondescribe(&possi
->version
, vdew_nonambig
));
139 add(depends
->up
,info
.string(),displayimportance
);
140 for (possi
=depends
->list
; possi
; possi
=possi
->next
) {
141 add(possi
->ed
,info
.string(),displayimportance
);
142 if (possi
->verrel
== dvr_none
&& depends
->type
!= dep_provides
) {
143 // providers aren't relevant if a version was specified, or
144 // if we're looking at a provider relationship already
146 for (provider
= possi
->ed
->available
.valid
? possi
->ed
->available
.depended
: 0;
148 provider
=provider
->nextrev
) {
149 if (provider
->up
->type
!= dep_provides
) continue;
150 add(provider
->up
->up
,info
.string(),displayimportance
);
151 add(provider
->up
,displayimportance
);
158 void repeatedlydisplay(packagelist
*sub
,
159 showpriority initial
,
160 packagelist
*unredisplay
) {
164 if (debug
) fprintf(debug
,"repeatedlydisplay(packagelist[%p])\n",sub
);
165 if (sub
->resolvesuggest() != 0 && sub
->deletelessimp_anyleft(initial
)) {
166 if (debug
) fprintf(debug
,"repeatedlydisplay(packagelist[%p]) once\n",sub
);
167 if (unredisplay
) unredisplay
->enddisplay();
169 manual_install
= 0; /* Remove flag now that resolvesuggest has seen it. */
170 newl
= sub
->display();
172 if (debug
) fprintf(debug
,"repeatedlydisplay(packagelist[%p]) newl\n",sub
);
173 kb
= sub
->bindings
; delete sub
;
174 sub
= new packagelist(kb
,newl
);
175 if (sub
->resolvesuggest() <= 1) break;
176 if (!sub
->deletelessimp_anyleft(dp_must
)) break;
177 if (debug
) fprintf(debug
,"repeatedlydisplay(packagelist[%p]) again\n",sub
);
179 if (unredisplay
) unredisplay
->startdisplay();
182 if (debug
) fprintf(debug
,"repeatedlydisplay(packagelist[%p]) done\n",sub
);
185 int packagelist::deletelessimp_anyleft(showpriority than
) {
187 fprintf(debug
,"packagelist[%p]::dli_al(%d): nitems=%d\n",this,than
,nitems
);
189 for (runthr
=0, insat
=0;
192 if (table
[runthr
]->dpriority
< than
) {
193 table
[runthr
]->free(recursive
);
195 if (insat
!= runthr
) table
[insat
]= table
[runthr
];
200 if (debug
) fprintf(debug
,"packagelist[%p]::dli_al(%d) done; nitems=%d\n",