]>
git.saurik.com Git - apt.git/blob - apt-pkg/cacheset.cc
1 // -*- mode: cpp; mode: fold -*-
3 /* ######################################################################
5 Simple wrapper around a std::set to provide a similar interface to
6 a set of cache structures as to the complete set of all structures
7 in the pkgCache. Currently only Package is supported.
9 ##################################################################### */
11 // Include Files /*{{{*/
12 #include <apt-pkg/aptconfiguration.h>
13 #include <apt-pkg/cachefilter.h>
14 #include <apt-pkg/cacheset.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/strutl.h>
17 #include <apt-pkg/versionmatch.h>
26 // FromTask - Return all packages in the cache from a specific task /*{{{*/
27 PackageSet
PackageSet :: FromTask ( pkgCacheFile
& Cache
, std :: string pattern
, CacheSetHelper
& helper
) {
28 size_t const archfound
= pattern
. find_last_of ( ':' );
29 std :: string arch
= "native" ;
30 if ( archfound
!= std :: string :: npos
) {
31 arch
= pattern
. substr ( archfound
+ 1 );
32 pattern
. erase ( archfound
);
35 if ( pattern
[ pattern
. length () - 1 ] != '^' )
36 return APT :: PackageSet ( TASK
);
37 pattern
. erase ( pattern
. length ()- 1 );
39 if ( unlikely ( Cache
. GetPkgCache () == 0 || Cache
. GetDepCache () == 0 ))
40 return APT :: PackageSet ( TASK
);
42 PackageSet
pkgset ( TASK
);
44 pkgRecords
Recs ( Cache
);
46 // build regexp for the task
49 snprintf ( S
, sizeof ( S
), "^Task:.*[, ] %s ([, ]|$)" , pattern
. c_str ());
50 if ( regcomp (& Pattern
, S
, REG_EXTENDED
| REG_NOSUB
| REG_NEWLINE
) != 0 ) {
51 _error
-> Error ( "Failed to compile task regexp" );
55 for ( pkgCache :: GrpIterator Grp
= Cache
-> GrpBegin (); Grp
. end () == false ; ++ Grp
) {
56 pkgCache :: PkgIterator Pkg
= Grp
. FindPkg ( arch
);
57 if ( Pkg
. end () == true )
59 pkgCache :: VerIterator ver
= Cache
[ Pkg
]. CandidateVerIter ( Cache
);
63 pkgRecords :: Parser
& parser
= Recs
. Lookup ( ver
. FileList ());
64 const char * start
, * end
;
65 parser
. GetRec ( start
, end
);
66 unsigned int const length
= end
- start
;
68 strncpy ( buf
, start
, length
);
70 if ( regexec (& Pattern
, buf
, 0 , 0 , 0 ) != 0 )
77 if ( pkgset
. empty () == true )
78 return helper
. canNotFindTask ( Cache
, pattern
);
80 helper
. showTaskSelection ( pkgset
, pattern
);
84 // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
85 PackageSet
PackageSet :: FromRegEx ( pkgCacheFile
& Cache
, std :: string pattern
, CacheSetHelper
& helper
) {
86 static const char * const isregex
= ".?+*|[^$" ;
87 if ( pattern
. find_first_of ( isregex
) == std :: string :: npos
)
88 return PackageSet ( REGEX
);
90 size_t archfound
= pattern
. find_last_of ( ':' );
91 std :: string arch
= "native" ;
92 if ( archfound
!= std :: string :: npos
) {
93 arch
= pattern
. substr ( archfound
+ 1 );
94 if ( arch
. find_first_of ( isregex
) == std :: string :: npos
)
95 pattern
. erase ( archfound
);
100 if ( unlikely ( Cache
. GetPkgCache () == 0 ))
101 return PackageSet ( REGEX
);
103 APT :: CacheFilter :: PackageNameMatchesRegEx
regexfilter ( pattern
);
105 PackageSet
pkgset ( REGEX
);
106 for ( pkgCache :: GrpIterator Grp
= Cache
. GetPkgCache ()-> GrpBegin (); Grp
. end () == false ; ++ Grp
) {
107 if ( regexfilter ( Grp
) == false )
109 pkgCache :: PkgIterator Pkg
= Grp
. FindPkg ( arch
);
110 if ( Pkg
. end () == true ) {
111 if ( archfound
== std :: string :: npos
) {
112 std :: vector
< std :: string
> archs
= APT :: Configuration :: getArchitectures ();
113 for ( std :: vector
< std :: string
>:: const_iterator a
= archs
. begin ();
114 a
!= archs
. end () && Pkg
. end () != true ; ++ a
)
115 Pkg
= Grp
. FindPkg (* a
);
117 if ( Pkg
. end () == true )
124 if ( pkgset
. empty () == true )
125 return helper
. canNotFindRegEx ( Cache
, pattern
);
127 helper
. showRegExSelection ( pkgset
, pattern
);
131 // FromName - Returns the package defined by this string /*{{{*/
132 pkgCache :: PkgIterator
PackageSet :: FromName ( pkgCacheFile
& Cache
,
133 std :: string
const & str
, CacheSetHelper
& helper
) {
134 std :: string pkg
= str
;
135 size_t archfound
= pkg
. find_last_of ( ':' );
137 if ( archfound
!= std :: string :: npos
) {
138 arch
= pkg
. substr ( archfound
+ 1 );
139 pkg
. erase ( archfound
);
142 if ( Cache
. GetPkgCache () == 0 )
143 return pkgCache :: PkgIterator ( Cache
, 0 );
145 pkgCache :: PkgIterator
Pkg ( Cache
, 0 );
146 if ( arch
. empty () == true ) {
147 pkgCache :: GrpIterator Grp
= Cache
. GetPkgCache ()-> FindGrp ( pkg
);
148 if ( Grp
. end () == false )
149 Pkg
= Grp
. FindPreferredPkg ();
151 Pkg
= Cache
. GetPkgCache ()-> FindPkg ( pkg
, arch
);
153 if ( Pkg
. end () == true )
154 return helper
. canNotFindPkgName ( Cache
, str
);
158 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
159 std :: map
< unsigned short , PackageSet
> PackageSet :: GroupedFromCommandLine (
160 pkgCacheFile
& Cache
, const char ** cmdline
,
161 std :: list
< PackageSet :: Modifier
> const & mods
,
162 unsigned short const & fallback
, CacheSetHelper
& helper
) {
163 std :: map
< unsigned short , PackageSet
> pkgsets
;
164 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
) {
165 unsigned short modID
= fallback
;
166 std :: string str
= * I
;
167 bool modifierPresent
= false ;
168 for ( std :: list
< PackageSet :: Modifier
>:: const_iterator mod
= mods
. begin ();
169 mod
!= mods
. end (); ++ mod
) {
170 size_t const alength
= strlen ( mod
-> Alias
);
172 case PackageSet :: Modifier :: POSTFIX
:
173 if ( str
. compare ( str
. length () - alength
, alength
,
174 mod
-> Alias
, 0 , alength
) != 0 )
176 str
. erase ( str
. length () - alength
);
179 case PackageSet :: Modifier :: PREFIX
:
181 case PackageSet :: Modifier :: NONE
:
184 modifierPresent
= true ;
187 if ( modifierPresent
== true ) {
188 bool const errors
= helper
. showErrors ( false );
189 pkgCache :: PkgIterator Pkg
= FromName ( Cache
, * I
, helper
);
190 helper
. showErrors ( errors
);
191 if ( Pkg
. end () == false ) {
192 pkgsets
[ fallback
]. insert ( Pkg
);
196 pkgsets
[ modID
]. insert ( PackageSet :: FromString ( Cache
, str
, helper
));
201 // FromCommandLine - Return all packages specified on commandline /*{{{*/
202 PackageSet
PackageSet :: FromCommandLine ( pkgCacheFile
& Cache
, const char ** cmdline
, CacheSetHelper
& helper
) {
204 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
) {
205 PackageSet pset
= FromString ( Cache
, * I
, helper
);
206 pkgset
. insert ( pset
. begin (), pset
. end ());
211 // FromString - Return all packages matching a specific string /*{{{*/
212 PackageSet
PackageSet :: FromString ( pkgCacheFile
& Cache
, std :: string
const & str
, CacheSetHelper
& helper
) {
213 _error
-> PushToStack ();
216 pkgCache :: PkgIterator Pkg
= FromName ( Cache
, str
, helper
);
217 if ( Pkg
. end () == false )
220 pkgset
= FromTask ( Cache
, str
, helper
);
221 if ( pkgset
. empty () == true ) {
222 pkgset
= FromRegEx ( Cache
, str
, helper
);
223 if ( pkgset
. empty () == true )
224 pkgset
= helper
. canNotFindPackage ( Cache
, str
);
228 if ( pkgset
. empty () == false )
229 _error
-> RevertToStack ();
231 _error
-> MergeWithStack ();
235 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
236 std :: map
< unsigned short , VersionSet
> VersionSet :: GroupedFromCommandLine (
237 pkgCacheFile
& Cache
, const char ** cmdline
,
238 std :: list
< VersionSet :: Modifier
> const & mods
,
239 unsigned short const & fallback
, CacheSetHelper
& helper
) {
240 std :: map
< unsigned short , VersionSet
> versets
;
241 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
) {
242 unsigned short modID
= fallback
;
243 VersionSet :: Version select
= VersionSet :: NEWEST
;
244 std :: string str
= * I
;
245 bool modifierPresent
= false ;
246 for ( std :: list
< VersionSet :: Modifier
>:: const_iterator mod
= mods
. begin ();
247 mod
!= mods
. end (); ++ mod
) {
248 if ( modID
== fallback
&& mod
-> ID
== fallback
)
249 select
= mod
-> SelectVersion
;
250 size_t const alength
= strlen ( mod
-> Alias
);
252 case VersionSet :: Modifier :: POSTFIX
:
253 if ( str
. compare ( str
. length () - alength
, alength
,
254 mod
-> Alias
, 0 , alength
) != 0 )
256 str
. erase ( str
. length () - alength
);
258 select
= mod
-> SelectVersion
;
260 case VersionSet :: Modifier :: PREFIX
:
262 case VersionSet :: Modifier :: NONE
:
265 modifierPresent
= true ;
269 if ( modifierPresent
== true ) {
270 bool const errors
= helper
. showErrors ( false );
271 VersionSet
const vset
= VersionSet :: FromString ( Cache
, std :: string (* I
), select
, helper
, true );
272 helper
. showErrors ( errors
);
273 if ( vset
. empty () == false ) {
274 versets
[ fallback
]. insert ( vset
);
278 versets
[ modID
]. insert ( VersionSet :: FromString ( Cache
, str
, select
, helper
));
283 // FromCommandLine - Return all versions specified on commandline /*{{{*/
284 APT :: VersionSet
VersionSet :: FromCommandLine ( pkgCacheFile
& Cache
, const char ** cmdline
,
285 APT :: VersionSet :: Version
const & fallback
, CacheSetHelper
& helper
) {
287 for ( const char ** I
= cmdline
; * I
!= 0 ; ++ I
)
288 verset
. insert ( VersionSet :: FromString ( Cache
, * I
, fallback
, helper
));
292 // FromString - Returns all versions spedcified by a string /*{{{*/
293 APT :: VersionSet
VersionSet :: FromString ( pkgCacheFile
& Cache
, std :: string pkg
,
294 APT :: VersionSet :: Version
const & fallback
, CacheSetHelper
& helper
,
295 bool const & onlyFromName
) {
297 bool verIsRel
= false ;
298 size_t const vertag
= pkg
. find_last_of ( "/=" );
299 if ( vertag
!= string :: npos
) {
300 ver
= pkg
. substr ( vertag
+ 1 );
301 verIsRel
= ( pkg
[ vertag
] == '/' );
305 if ( onlyFromName
== false )
306 pkgset
= PackageSet :: FromString ( Cache
, pkg
, helper
);
308 pkgset
. insert ( PackageSet :: FromName ( Cache
, pkg
, helper
));
313 if ( pkgset
. getConstructor () != PackageSet :: UNKNOWN
)
314 errors
= helper
. showErrors ( false );
315 for ( PackageSet :: const_iterator P
= pkgset
. begin ();
316 P
!= pkgset
. end (); ++ P
) {
317 if ( vertag
== string :: npos
) {
318 verset
. insert ( VersionSet :: FromPackage ( Cache
, P
, fallback
, helper
));
321 pkgCache :: VerIterator V
;
322 if ( ver
== "installed" )
323 V
= getInstalledVer ( Cache
, P
, helper
);
324 else if ( ver
== "candidate" )
325 V
= getCandidateVer ( Cache
, P
, helper
);
326 else if ( ver
== "newest" ) {
327 if ( P
-> VersionList
!= 0 )
330 V
= helper
. canNotFindNewestVer ( Cache
, P
);
332 pkgVersionMatch
Match ( ver
, ( verIsRel
== true ? pkgVersionMatch :: Release
:
333 pkgVersionMatch :: Version
));
335 if ( V
. end () == true ) {
336 if ( verIsRel
== true )
337 _error
-> Error ( _ ( "Release ' %s ' for ' %s ' was not found" ),
338 ver
. c_str (), P
. FullName ( true ). c_str ());
340 _error
-> Error ( _ ( "Version ' %s ' for ' %s ' was not found" ),
341 ver
. c_str (), P
. FullName ( true ). c_str ());
347 helper
. showSelectedVersion ( P
, V
, ver
, verIsRel
);
350 if ( pkgset
. getConstructor () != PackageSet :: UNKNOWN
)
351 helper
. showErrors ( errors
);
355 // FromPackage - versions from package based on fallback /*{{{*/
356 VersionSet
VersionSet :: FromPackage ( pkgCacheFile
& Cache
, pkgCache :: PkgIterator
const & P
,
357 VersionSet :: Version
const & fallback
, CacheSetHelper
& helper
) {
359 pkgCache :: VerIterator V
;
362 case VersionSet :: ALL
:
363 if ( P
-> VersionList
!= 0 )
364 for ( V
= P
. VersionList (); V
. end () != true ; ++ V
)
367 verset
. insert ( helper
. canNotFindAllVer ( Cache
, P
));
369 case VersionSet :: CANDANDINST
:
370 verset
. insert ( getInstalledVer ( Cache
, P
, helper
));
371 verset
. insert ( getCandidateVer ( Cache
, P
, helper
));
373 case VersionSet :: CANDIDATE
:
374 verset
. insert ( getCandidateVer ( Cache
, P
, helper
));
376 case VersionSet :: INSTALLED
:
377 verset
. insert ( getInstalledVer ( Cache
, P
, helper
));
379 case VersionSet :: CANDINST
:
380 showErrors
= helper
. showErrors ( false );
381 V
= getCandidateVer ( Cache
, P
, helper
);
383 V
= getInstalledVer ( Cache
, P
, helper
);
384 helper
. showErrors ( showErrors
);
385 if ( V
. end () == false )
388 verset
. insert ( helper
. canNotFindInstCandVer ( Cache
, P
));
390 case VersionSet :: INSTCAND
:
391 showErrors
= helper
. showErrors ( false );
392 V
= getInstalledVer ( Cache
, P
, helper
);
394 V
= getCandidateVer ( Cache
, P
, helper
);
395 helper
. showErrors ( showErrors
);
396 if ( V
. end () == false )
399 verset
. insert ( helper
. canNotFindInstCandVer ( Cache
, P
));
401 case VersionSet :: NEWEST
:
402 if ( P
-> VersionList
!= 0 )
403 verset
. insert ( P
. VersionList ());
405 verset
. insert ( helper
. canNotFindNewestVer ( Cache
, P
));
411 // getCandidateVer - Returns the candidate version of the given package /*{{{*/
412 pkgCache :: VerIterator
VersionSet :: getCandidateVer ( pkgCacheFile
& Cache
,
413 pkgCache :: PkgIterator
const & Pkg
, CacheSetHelper
& helper
) {
414 pkgCache :: VerIterator Cand
;
415 if ( Cache
. IsPolicyBuilt () == true || Cache
. IsDepCacheBuilt () == false )
417 if ( unlikely ( Cache
. GetPolicy () == 0 ))
418 return pkgCache :: VerIterator ( Cache
);
419 Cand
= Cache
. GetPolicy ()-> GetCandidateVer ( Pkg
);
421 Cand
= Cache
[ Pkg
]. CandidateVerIter ( Cache
);
423 if ( Cand
. end () == true )
424 return helper
. canNotFindCandidateVer ( Cache
, Pkg
);
428 // getInstalledVer - Returns the installed version of the given package /*{{{*/
429 pkgCache :: VerIterator
VersionSet :: getInstalledVer ( pkgCacheFile
& Cache
,
430 pkgCache :: PkgIterator
const & Pkg
, CacheSetHelper
& helper
) {
431 if ( Pkg
-> CurrentVer
== 0 )
432 return helper
. canNotFindInstalledVer ( Cache
, Pkg
);
433 return Pkg
. CurrentVer ();
436 // canNotFindPkgName - handle the case no package has this name /*{{{*/
437 pkgCache :: PkgIterator
CacheSetHelper :: canNotFindPkgName ( pkgCacheFile
& Cache
,
438 std :: string
const & str
) {
439 if ( ShowError
== true )
440 _error
-> Insert ( ErrorType
, _ ( "Unable to locate package %s " ), str
. c_str ());
441 return pkgCache :: PkgIterator ( Cache
, 0 );
444 // canNotFindTask - handle the case no package is found for a task /*{{{*/
445 PackageSet
CacheSetHelper :: canNotFindTask ( pkgCacheFile
& Cache
, std :: string pattern
) {
446 if ( ShowError
== true )
447 _error
-> Insert ( ErrorType
, _ ( "Couldn't find task ' %s '" ), pattern
. c_str ());
451 // canNotFindRegEx - handle the case no package is found by a regex /*{{{*/
452 PackageSet
CacheSetHelper :: canNotFindRegEx ( pkgCacheFile
& Cache
, std :: string pattern
) {
453 if ( ShowError
== true )
454 _error
-> Insert ( ErrorType
, _ ( "Couldn't find any package by regex ' %s '" ), pattern
. c_str ());
458 // canNotFindPackage - handle the case no package is found from a string/*{{{*/
459 PackageSet
CacheSetHelper :: canNotFindPackage ( pkgCacheFile
& Cache
, std :: string
const & str
) {
463 // canNotFindAllVer /*{{{*/
464 VersionSet
CacheSetHelper :: canNotFindAllVer ( pkgCacheFile
& Cache
,
465 pkgCache :: PkgIterator
const & Pkg
) {
466 if ( ShowError
== true )
467 _error
-> Insert ( ErrorType
, _ ( "Can't select versions from package ' %s ' as it purely virtual" ), Pkg
. FullName ( true ). c_str ());
471 // canNotFindInstCandVer /*{{{*/
472 VersionSet
CacheSetHelper :: canNotFindInstCandVer ( pkgCacheFile
& Cache
,
473 pkgCache :: PkgIterator
const & Pkg
) {
474 if ( ShowError
== true )
475 _error
-> Insert ( ErrorType
, _ ( "Can't select installed nor candidate version from package ' %s ' as it has neither of them" ), Pkg
. FullName ( true ). c_str ());
479 // canNotFindInstCandVer /*{{{*/
480 VersionSet
CacheSetHelper :: canNotFindCandInstVer ( pkgCacheFile
& Cache
,
481 pkgCache :: PkgIterator
const & Pkg
) {
482 if ( ShowError
== true )
483 _error
-> Insert ( ErrorType
, _ ( "Can't select installed nor candidate version from package ' %s ' as it has neither of them" ), Pkg
. FullName ( true ). c_str ());
487 // canNotFindNewestVer /*{{{*/
488 pkgCache :: VerIterator
CacheSetHelper :: canNotFindNewestVer ( pkgCacheFile
& Cache
,
489 pkgCache :: PkgIterator
const & Pkg
) {
490 if ( ShowError
== true )
491 _error
-> Insert ( ErrorType
, _ ( "Can't select newest version from package ' %s ' as it is purely virtual" ), Pkg
. FullName ( true ). c_str ());
492 return pkgCache :: VerIterator ( Cache
, 0 );
495 // canNotFindCandidateVer /*{{{*/
496 pkgCache :: VerIterator
CacheSetHelper :: canNotFindCandidateVer ( pkgCacheFile
& Cache
,
497 pkgCache :: PkgIterator
const & Pkg
) {
498 if ( ShowError
== true )
499 _error
-> Insert ( ErrorType
, _ ( "Can't select candidate version from package %s as it has no candidate" ), Pkg
. FullName ( true ). c_str ());
500 return pkgCache :: VerIterator ( Cache
, 0 );
503 // canNotFindInstalledVer /*{{{*/
504 pkgCache :: VerIterator
CacheSetHelper :: canNotFindInstalledVer ( pkgCacheFile
& Cache
,
505 pkgCache :: PkgIterator
const & Pkg
) {
506 if ( ShowError
== true )
507 _error
-> Insert ( ErrorType
, _ ( "Can't select installed version from package %s as it is not installed" ), Pkg
. FullName ( true ). c_str ());
508 return pkgCache :: VerIterator ( Cache
, 0 );