2 * dselect - Debian GNU/Linux package maintenance user interface
3 * pkgsublist.cc - status modification and recursive package list handling
5 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.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
9 * published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This is distributed in the hope that it will be useful, but
13 * 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
18 * License along with this; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 void packagelist::add(pkginfo
*pkg
) {
37 if (debug
) fprintf(debug
,"packagelist[%p]::add(pkginfo %s)\n",this,pkg
->name
);
38 if (!recursive
|| // never add things to top level
39 !pkg
->clientdata
|| // don't add pure virtual packages
40 pkg
->clientdata
->uprec
) // don't add ones already in the recursive list
42 if (debug
) fprintf(debug
,"packagelist[%p]::add(pkginfo %s) adding\n",this,pkg
->name
);
43 perpackagestate
*state
= &datatable
[nitems
];
45 state
->direct
= state
->original
= pkg
->clientdata
->selected
;
46 state
->suggested
= state
->selected
= pkg
->clientdata
->selected
;
47 state
->spriority
= sp_inherit
; state
->dpriority
= dp_none
;
48 state
->uprec
= pkg
->clientdata
;
49 state
->relations
.init();
50 pkg
->clientdata
= state
;
55 void packagelist::add(pkginfo
*pkg
, pkginfo::pkgwant nw
) {
56 if (debug
) fprintf(debug
,"packagelist[%p]::add(pkginfo %s, %s)\n",
57 this,pkg
->name
,wantstrings
[nw
]);
58 add(pkg
); if (!pkg
->clientdata
) return;
59 pkg
->clientdata
->direct
= nw
;
61 np
= would_like_to_install(nw
,pkg
) ? sp_selecting
: sp_deselecting
;
62 if (pkg
->clientdata
->spriority
> np
) return;
63 if (debug
) fprintf(debug
,"packagelist[%p]::add(pkginfo %s, %s) setting\n",
64 this,pkg
->name
,wantstrings
[nw
]);
65 pkg
->clientdata
->suggested
= pkg
->clientdata
->selected
= nw
;
66 pkg
->clientdata
->spriority
= np
;
70 void packagelist::add(pkginfo
*pkg
, const char *extrainfo
, showpriority showimp
) {
72 fprintf(debug
,"packagelist[%p]::add(pkginfo %s, \"...\", showpriority %d)\n",
73 this,pkg
->name
,showimp
);
74 add(pkg
); if (!pkg
->clientdata
) return;
75 if (pkg
->clientdata
->dpriority
< showimp
) pkg
->clientdata
->dpriority
= showimp
;
76 pkg
->clientdata
->relations(extrainfo
);
77 pkg
->clientdata
->relations
.terminate();
80 int packagelist::alreadydone(doneent
**done
, void *check
) {
83 for (search
= *done
; search
&& search
->dep
!= check
; 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(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
!= deppossi::dvr_none
) {
126 switch (possi
->verrel
) {
127 case deppossi::dvr_earlierequal
: info(" (<= "); break;
128 case deppossi::dvr_laterequal
: info(" (>= "); break;
129 case deppossi::dvr_earlierstrict
: info(" (<< "); break;
130 case deppossi::dvr_laterstrict
: info(" (>> "); break;
131 case deppossi::dvr_exact
: info(" (= "); break;
132 default: internerr("unknown verrel");
134 info(versiondescribe(&possi
->version
,vdew_never
));
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
== deppossi::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 newl
= sub
->display();
171 if (debug
) fprintf(debug
,"repeatedlydisplay(packagelist[%p]) newl\n",sub
);
172 kb
= sub
->bindings
; delete sub
;
173 sub
= new packagelist(kb
,newl
);
174 if (sub
->resolvesuggest() <= 1) break;
175 if (!sub
->deletelessimp_anyleft(dp_must
)) break;
176 if (debug
) fprintf(debug
,"repeatedlydisplay(packagelist[%p]) again\n",sub
);
178 if (unredisplay
) unredisplay
->startdisplay();
181 if (debug
) fprintf(debug
,"repeatedlydisplay(packagelist[%p]) done\n",sub
);
184 int packagelist::deletelessimp_anyleft(showpriority than
) {
186 fprintf(debug
,"packagelist[%p]::dli_al(%d): nitems=%d\n",this,than
,nitems
);
188 for (runthr
=0, insat
=0;
191 if (table
[runthr
]->dpriority
< than
) {
192 table
[runthr
]->free(recursive
);
194 if (insat
!= runthr
) table
[insat
]= table
[runthr
];
199 if (debug
) fprintf(debug
,"packagelist[%p]::dli_al(%d) done; nitems=%d\n",