[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Translating apt lists directly



Mr. Burrows,
 
I do not know if the apt database is held in a map, a list or a vector. If there is a way your program can place the contents of the APT database into a map, the solution to your problem is near.
 
Let me describe the algorithm in simple English. First, we'll create a map, which is represented as an associative container in C++. Containers are made possible with an inclusion of the <map> library. We will assume that the map contains a separate package for each element. The first cycle--or, iteration--through the database is output to the screen so that the user may verify which packages to keep. Perhaps you have compiled the kernel. Perhaps you have tinkered with the kernel. Perhaps you have taken apart the transmission of a motor vehicle. This painstaking process takes place at the user end after compilation of the program.
 
We have now helped the user decide which packages to discard and which packages might not have value. The discarded packages are to be deleted. The packages to be kept are placed in a new container. The possibly worthless packages are placed in a list. The list of excess packages is drained, and the remaining packages are placed at a lower priority in the same container.
 
The <dpkg> library is a dummy library that will represent the proper include file. An object of the package class is used as a predicate for the associative container. There is no need to understand the terminology from the last sentence.
 
Let the comments explain the following code:
#include <map>
#include <list>
#include <iterator>
#include <dpkg>
#include <iostream>
 
using namespace std;
 
// all function prototypes precede the main method
list<Bleeding_database> bleeding_packages( package );
 
int main ()
  // the database is sifted through the list function from one map to another
  container<Bloated_database> bloated_packages( package );
  container<Healthy_database> packages( package );
 
  // verify which packages to keep -- EXHAUSTIVE 
  for ( container<Bloated_database>::const_iterator pack = packages.begin();
         pack != packages.end(); ++pack ) {
    // pointers and objects are a difficult combination
    cout << endl << "Keep " << pack->name << "? [y,n,m] __>";
    if ( cin ) {
      char c;
      if ( ( c = cin.get( c ) ) == 'y' )
        Healthy_database.insert( pack, pack );
      else if ( c = cin.unget( c ) ) == 'n'
        Bloated_database.erase( pack );
      else {
        list<l> l_dpkg( package );
        l_dpkg( pack, drain_packages( pack );
    }
  }
 return 0;
 
list<Bleeding_database> drain_packages( list<Bleeding_database>& packages )
{
  list<Bleeding_database> drain;
  list<Bleeding_database>::iterator pack = packages.begin(); 
  while( pack != packages.end() ) {
    if ( delete( *pack ) ) {
      drain.push_back( *pack );
      pack = packages.erase( pack );
      } else
        ++pack;
    }
  }
  return drain;
}
 
Most importantly, I have not validated the above code in a C++ compiler. I would like to know if it is valid, if it may be improved, and if there is anything I may do for you.
 
Good luck in your Adventures,
Shaun Luke
 
On 12/5/07, Daniel Burrows <dburrows@debian.org > wrote:
Hi all,

I've been scratching my head over a problem that I'd like to solve,
and I thought maybe this list could help.

I'd like to generate some cut-down versions of my apt database for
debugging purposes (think unit tests).  Essentially I want to take all
the apt and dpkg databases, strip out all packages but a small set and
all references to packages outside this set, and write this
stripped-down set of files to a directory tree.

I've got the "hard" part of the code written, to parse dependency
fields from files containing RFC822-style stanzas and throw out entries
that talk about packages outside the subset of the archive I'm building.
But I'm not sure what the best way is to iterate over the files that
store state for apt and dpkg.

The best thing I can think of is to walk over everything in
/var/lib/apt/lists, along with /var/lib/dpkg/status and
/var/lib/apt/extended_states, treat each stanza as information about a
package and run my transform on a per-stanza basis after dropping
stanzas corresponding to packages outside my live set.

I'm a little hesitant to do that, though, because those files are
technically internal implementation details of dpkg and apt.  Admittedly
this is just for building debug inputs, but still ... does anyone know a
way of handling this (in C++, of course) that's "officially" sanctioned?

  Thanks,
Daniel


--
To UNSUBSCRIBE, email to deity-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org



Reply to: