LTP GCOV extension - code coverage report
Current view: directory - ept/core - apt.h
Test: lcov.info
Date: 2008-08-14 Instrumented lines: 173
Code covered: 79.8 % Executed lines: 138

       1                 : // -*- C++ -*-
       2                 : 
       3                 : #include <string>
       4                 : #include <wibble/test.h>
       5                 : 
       6                 : #include <ept/token.h>
       7                 : #include <ept/core/source.h>
       8                 : 
       9                 : #include <iostream>
      10                 : #include <wibble/exception.h>
      11                 : 
      12                 : #include <apt-pkg/pkgcache.h>
      13                 : #include <apt-pkg/sourcelist.h>
      14                 : #include <apt-pkg/error.h>
      15                 : #include <apt-pkg/policy.h>
      16                 : #include <apt-pkg/cachefile.h>
      17                 : #include <apt-pkg/progress.h>
      18                 : #include <apt-pkg/pkgcachegen.h>
      19                 : #include <apt-pkg/init.h>
      20                 : 
      21                 : #ifndef EPT_APT_H
      22                 : #define EPT_APT_H
      23                 : 
      24                 : namespace ept {
      25                 : namespace core {
      26                 : 
      27               0 : struct AptException : wibble::exception::Generic {
      28               0 :     std::string desc() const throw () {
      29               0 :         return "APT Error";
      30                 :     }
      31                 : 
      32               0 :     AptException( const std::string &ctx ) : Generic( ctx ) {
      33               0 :         while ( !_error->empty() ) {
      34               0 :             std::string err;
      35               0 :             _error->PopMessage( err );
      36               0 :             std::cerr << err << std::endl;
      37               0 :             addContext( err );
      38                 :         }
      39               0 :     }
      40                 : };
      41                 : 
      42                 : struct PackageState {
      43                 :     enum Query {
      44                 :         Install = 1 << 0,
      45                 :         Upgrade = 1 << 1,
      46                 :         Keep = 1 << 2,
      47                 :         Remove = 1 << 3,
      48                 :         Installed = 1 << 4,
      49                 :         Upgradable = 1 << 5,
      50                 :         NowBroken = 1 << 6,
      51                 :         WillBreak = 1 << 7,
      52                 :         ReInstall = 1 << 8,
      53                 :         Purge = 1 << 9,
      54                 :         Hold = 1 << 10,
      55                 :         Valid = 1 << 11
      56                 :     };
      57                 : 
      58                 :     typedef unsigned state;
      59                 :     
      60            3786 :     operator unsigned() { return m_state; };
      61                 :     
      62                 :     PackageState &operator=( unsigned i ) {
      63                 :         m_state = i;
      64                 :         return *this;
      65                 :     }
      66                 :     
      67            5218 :     PackageState &operator|=( const PackageState &s ) {
      68            5218 :         m_state |= s.m_state;
      69            5218 :         return *this;
      70                 :     }
      71                 :     
      72            9003 :     PackageState( unsigned a ) {
      73            9003 :         m_state = a;
      74            9003 :     }
      75                 :     
      76               1 :     PackageState() : m_state( 0 ) {}
      77                 : 
      78                 :     // FIXME this probably needs to be used consistently in core and out of core
      79               2 :     bool isValid() const { return m_state & Valid; }
      80                 :     // FIXME compatibility API for non-core apt
      81               1 :     bool isInstalled() const { return installed(); }
      82                 : 
      83               2 :     bool install() const { return m_state & Install; }
      84                 :     // reinstall() implies install()
      85                 :     bool reinstall() const { return m_state & ReInstall; }
      86                 :     bool remove() const { return m_state & Remove; }
      87                 :     // purge() implies remove()
      88            3775 :     bool purge() const { return m_state & Purge; }
      89            3780 :     bool keep() const { return m_state & Keep; }
      90                 :     bool willBreak() const { return m_state & WillBreak; }
      91                 :     // upgrade() implies install()
      92                 :     bool upgrade() const { return hasNewVersion() && install(); }
      93                 :     // newInsstal() implies install()
      94                 :     bool newInstall() const { return !installed() && install(); }
      95                 :     bool hold() const { return m_state & Hold; }
      96                 : 
      97               1 :     bool installed() const { return m_state & Installed; }
      98                 :     bool hasNewVersion() const { return m_state & Upgradable; }
      99                 :     bool upgradable() const { return hasNewVersion() && !hold(); }
     100                 :     bool held() const { return hasNewVersion() && hold(); }
     101                 :     bool nowBroken() const { return m_state & NowBroken; }
     102                 : 
     103                 :     bool modify() const { return install() || remove(); }
     104                 :     
     105                 : protected:
     106                 :     unsigned m_state;
     107                 : };
     108                 : 
     109                 : time_t aptTimestamp();
     110                 : 
     111                 : // wrap the apt's database
     112                 : struct AptDatabase {
     113            5093 :     pkgCache &cache() {
     114            5093 :         if ( !m_cache )
     115              20 :             openCache();
     116            5093 :         return *m_cache;
     117                 :     }
     118                 : 
     119            3793 :     pkgDepCache &state() {
     120            3793 :         if ( !m_state )
     121               5 :             openState();
     122            3793 :         return *m_state;
     123                 :     }
     124                 : 
     125            1436 :     pkgPolicy &policy() {
     126            1436 :         if ( !m_policy )
     127               0 :             openCache();
     128            1436 :         return *m_policy;
     129                 :     }
     130                 : 
     131                 :     OpProgress *m_progress;
     132                 :     bool m_tryWriteable;
     133                 :     bool m_writeable;
     134                 : 
     135                 :     time_t timestamp() {
     136                 :         return aptTimestamp();
     137                 :     }
     138                 : 
     139              73 :     AptDatabase() {
     140              73 :         m_cache = 0;
     141              73 :         m_state = 0;
     142              73 :         m_policy = 0;
     143              73 :         m_progress = new OpProgress();
     144              73 :         m_tryWriteable = true;
     145              73 :         m_writeable = false;
     146              73 :     }
     147                 : 
     148                 :     void setProgress( OpProgress *p ) {
     149                 :         m_progress = p;
     150                 :     }
     151                 : 
     152                 :     bool writeable() {
     153                 :         if ( !m_cache )
     154                 :             openCache();
     155                 :         return m_writeable;
     156                 :     }
     157                 : 
     158               5 :     void openState() {
     159               5 :         m_state = new pkgDepCache( &cache(), m_policy );
     160               5 :         m_state->Init( m_progress );
     161               5 :         m_progress->Done();
     162               5 :     }
     163                 : 
     164              20 :     void openCache() {
     165              20 :         if ( !_config->FindB("Initialized") ) {
     166               0 :             pkgInitConfig(*_config);
     167               0 :             _config->Set("Initialized", 1);
     168               0 :             pkgInitSystem(*_config, _system);
     169                 :         }
     170                 : 
     171              20 :         m_writeable = m_tryWriteable;
     172                 : 
     173              20 :         if ( m_tryWriteable ) {
     174                 :             try {
     175              20 :                 _system->Lock();
     176               0 :             } catch ( std::exception e ) {
     177               0 :                 m_tryWriteable = false;
     178               0 :                 openCache();
     179               0 :                 m_tryWriteable = true;
     180               0 :                 throw;
     181                 :             }
     182                 :         }
     183                 : 
     184              20 :         pkgSourceList list;
     185              20 :         if ( list.ReadMainList() == false ) {
     186               0 :             _error->DumpErrors();
     187                 :             throw wibble::exception::System(
     188               0 :                 "The list of sources could not be read." );
     189                 :         }
     190                 : 
     191              20 :         MMap *m = 0;
     192              20 :         bool Res = pkgMakeStatusCache( list, *m_progress, &m, !m_writeable );
     193                 : 
     194              20 :         if ( !Res ) {
     195                 :             std::cerr << "The package lists or status file "
     196               0 :                 "could not be parsed or opened." << std::endl;
     197                 :             throw AptException(
     198                 :                 "The package lists or status file "
     199               0 :                 "could not be parsed or opened." );
     200                 :         }
     201                 : 
     202              20 :         m_cache = new pkgCache( m, true );
     203              40 :         m_policy = new pkgPolicy( m_cache );
     204              40 :         if ( ReadPinFile( *m_policy )  == false )
     205               0 :             throw wibble::exception::System( "error reading pin file" );
     206              20 :         m_progress->Done();
     207              20 :     }
     208                 : 
     209              74 :     void invalidate() {
     210              74 :         if ( _config->FindB("Initialized") ) {
     211              74 :             _system->UnLock();
     212                 :         }
     213                 : 
     214              74 :         delete m_state;
     215              74 :         m_state = 0;
     216              74 :         delete m_policy;
     217              74 :         m_policy = 0;
     218              74 :         delete m_cache;
     219              74 :         m_cache = 0;
     220              74 :     }
     221                 : 
     222                 :     pkgCache::VerIterator anyVersion( pkgCache::PkgIterator pi ) {
     223                 :         if ( pi.end() ) return pkgCache::VerIterator();
     224                 :         return pi.VersionList();
     225                 :     }
     226                 : 
     227               5 :     Token candidateVersion( Token p ) {
     228               5 :         pkgCache::PkgIterator pi = cache().FindPkg( p.package() );
     229               6 :         if ( pi.end() ) return Token();
     230               4 :         pkgCache::VerIterator vi = policy().GetCandidateVer( pi );
     231               4 :         if ( vi.end() ) return Token();
     232                 : 
     233               4 :         Token t; t._id = p.package() + "_" + vi.VerStr();
     234               4 :         return t;
     235                 :     }
     236                 : 
     237            1432 :     pkgCache::VerIterator candidateVersion( pkgCache::PkgIterator pi ) {
     238            1432 :         if ( pi.end() ) return pkgCache::VerIterator();
     239            1432 :         pkgCache::VerIterator vi = policy().GetCandidateVer( pi );
     240            1432 :         if ( vi.end() ) return pkgCache::VerIterator();
     241            1432 :         return vi;
     242                 :     }
     243                 : 
     244            1432 :     pkgCache::VerIterator installedVersion( pkgCache::PkgIterator pi ) {
     245            1432 :         if ( pi.end() ) return pkgCache::VerIterator();
     246                 :         pkgCache::VerIterator vi = pkgCache::VerIterator( cache(),
     247            1432 :                                                           cache().VerP + pi->CurrentVer );
     248            1432 :         if ( vi.end() ) return pkgCache::VerIterator();
     249            1432 :         return vi;
     250                 :     }
     251                 : 
     252              27 :     pkgCache::PkgIterator lookupPackage( Token t ) {
     253              27 :         return cache().FindPkg( t.package() );
     254                 :     }
     255                 : 
     256               5 :     pkgCache::VerIterator lookupVersion( Token t ) {
     257               5 :         if ( !t.hasVersion() )
     258               5 :             t = candidateVersion( t );
     259               5 :         pkgCache::PkgIterator pi = lookupPackage( t );
     260               5 :         if ( pi.end() )
     261               1 :             return pkgCache::VerIterator();
     262               4 :         for (pkgCache::VerIterator vi = pi.VersionList(); !vi.end(); ++vi)
     263               4 :             if ( t.version() == vi.VerStr() )
     264               4 :                 return vi;
     265               0 :         return pkgCache::VerIterator();
     266                 :     }
     267                 : 
     268                 :     static pkgCache::VerFileIterator lookupVersionFile(
     269               5 :         pkgCache::VerIterator vi )
     270                 :     {
     271               5 :         if ( vi.end() )
     272               1 :             return pkgCache::VerFileIterator();
     273               4 :         pkgCache::VerFileIterator vfi = vi.FileList();
     274               4 :         for ( ; !vfi.end(); vfi++ )
     275               4 :             if ( ( vfi.File()->Flags & pkgCache::Flag::NotSource ) == 0)
     276               4 :                 break;
     277               4 :         if ( vfi.end() )
     278               0 :             vfi = vi.FileList();
     279               4 :         return vfi;
     280                 :     }
     281                 : 
     282               0 :     PackageState invalidState() {
     283               0 :         return PackageState( PackageState::NowBroken | PackageState::Keep );
     284                 :     }
     285                 : 
     286            3784 :     PackageState packageState( pkgCache::PkgIterator P )
     287                 :     {
     288            3784 :         PackageState s = 0;
     289            3784 :         if ( P.end() )
     290               0 :             return invalidState();
     291            3784 :         if ( ! ( P->CurrentState == pkgCache::State::ConfigFiles
     292                 :                  || P->CurrentState == pkgCache::State::NotInstalled ) )
     293            1432 :             s |= PackageState::Installed;
     294            3784 :         if ( s & PackageState::Installed &&
     295                 :              candidateVersion( P ) != installedVersion( P ) )
     296               1 :             s |= PackageState::Upgradable;
     297            3784 :         pkgDepCache::StateCache S = state()[ P ];
     298            3784 :         if ( S.Install() )
     299               3 :             s |= PackageState::Install;
     300            3784 :         if ( ( S.iFlags & pkgDepCache::ReInstall )
     301                 :              == pkgDepCache::ReInstall )
     302               0 :             s |= PackageState::ReInstall;
     303            3784 :         if ( S.Keep() )
     304            3780 :             s |= PackageState::Keep;
     305            3784 :         if ( S.Delete() )
     306               1 :             s |= PackageState::Remove;
     307            3784 :         if ( ( S.iFlags & pkgDepCache::Purge ) == pkgDepCache::Purge )
     308               0 :             s |= PackageState::Purge;
     309            3784 :         if ( S.NowBroken() )
     310               1 :             s |= PackageState::NowBroken;
     311            3784 :         if ( S.InstBroken() )
     312               0 :             s |= PackageState::WillBreak;
     313            3784 :         if ( P->SelectedState == pkgCache::State::Hold )
     314               0 :             s |= PackageState::Hold;
     315            3784 :         return s;
     316                 :     }
     317                 : 
     318               1 :     PackageState packageState( Token t ) {
     319               1 :         t = validate( t );
     320               1 :         if ( t.valid() )
     321               1 :             return packageState( lookupPackage( t ) );
     322               0 :         return invalidState();
     323                 :     }
     324                 : 
     325               4 :     Token validate( Token t ) {
     326               4 :         if ( t.hasVersion() )
     327               0 :             return lookupVersion( t ).end() ? Token() : t;
     328               4 :         return lookupPackage( t ).end() ? Token() : t;
     329                 :     }
     330                 : 
     331              73 :     ~AptDatabase() {
     332              73 :         invalidate();
     333              73 :     }
     334                 : 
     335                 : protected:
     336                 :     pkgCache *m_cache;
     337                 :     pkgDepCache *m_state;
     338                 :     pkgPolicy *m_policy;
     339                 : };
     340                 : 
     341                 : template< typename Internal >
     342                 : struct AptInternalList {
     343                 :     Internal m_head;
     344                 :     typedef Internal Type;
     345           11331 :     AptInternalList tail() const {
     346           11331 :         AptInternalList t = *this;
     347           11331 :         t.m_head++;
     348                 :         return t;
     349                 :     }
     350            7554 :     const Internal &head() const { return m_head; }
     351            3781 :     Internal &head() { return m_head; }
     352           11334 :     bool empty() const { return m_head.end(); }
     353               3 :     AptInternalList( Internal head ) : m_head( head ) {}
     354                 :     AptInternalList() {}
     355                 : };
     356                 : 
     357                 : namespace version {
     358                 : 
     359                 : typedef enum { Package, VersionString, Section, Architecture,
     360                 :                Depends, Recommends, Record } PropertyId;
     361                 : 
     362                 : typedef pkgCache::VerIterator Internal;
     363                 : template< PropertyId > struct PropertyType {};
     364                 : 
     365                 : }
     366                 : 
     367                 : namespace package {
     368                 : 
     369                 : typedef enum { Name, Versions, AnyVersion, State, CandidateVersion,
     370                 :                InstalledVersion } PropertyId;
     371                 : typedef pkgCache::PkgIterator Internal;
     372                 : template< PropertyId > struct PropertyType {};
     373                 : 
     374                 : struct VersionList {
     375                 :     version::Internal m_head;
     376                 :     VersionList tail() const;
     377                 :     const version::Internal &head() const { return m_head; }
     378                 :     version::Internal &head() { return m_head; }
     379                 : };
     380                 : 
     381                 : typedef AptInternalList< Internal > InternalList;
     382                 : 
     383                 : }
     384                 : 
     385                 : namespace record {
     386                 : 
     387                 : typedef enum { Record, Name, Priority, Section, InstalledSize, Maintainer,
     388                 :                Architecture, SourcePackage, Version, Description,
     389                 :                ShortDescription, LongDescription, PackageSize } PropertyId;
     390                 : 
     391                 : extern const char *fields[];
     392                 : 
     393                 : typedef pkgCache::VerFileIterator Internal;
     394                 : 
     395                 : template< PropertyId > struct PropertyType {
     396                 :     typedef std::string T;
     397                 : };
     398                 : 
     399                 : }
     400                 : }
     401                 : }
     402                 : 
     403                 : #include <ept/core/apt/package.h>
     404                 : #include <ept/core/apt/version.h>
     405                 : #include <ept/core/apt/record.h>
     406                 : 
     407                 : #endif

Generated by: LTP GCOV extension version 1.6