- initial import of revision 374 from cnc
[apt.git] / apt-pkg / srcrecords.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description                                                          /*{{{*/
3 // $Id: srcrecords.cc,v 1.2 2003/01/29 18:43:48 niemeyer Exp $
4 /* ######################################################################
5    
6    Source Package Records - Allows access to source package records
7    
8    Parses and allows access to the list of source records and searching by
9    source name on that list.
10    
11    ##################################################################### */
12                                                                         /*}}}*/
13 // Include Files                                                        /*{{{*/
14 #ifdef __GNUG__
15 #pragma implementation "apt-pkg/srcrecords.h"
16 #endif 
17
18 #include <apt-pkg/srcrecords.h>
19 #include <apt-pkg/error.h>
20 #include <apt-pkg/sourcelist.h>
21 #include <apt-pkg/strutl.h>
22     
23 #include <apti18n.h>    
24                                                                         /*}}}*/
25
26 // SrcRecords::pkgSrcRecords - Constructor                              /*{{{*/
27 // ---------------------------------------------------------------------
28 /* Open all the source index files */
29 pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : Files(0), Current(0)
30 {
31    Files = new Parser *[List.end() - List.begin() + 1];
32    memset(Files,0,sizeof(*Files)*(List.end() - List.begin() + 1));
33    
34    unsigned int Count = 0;
35    pkgSourceList::const_iterator I = List.begin();
36    for (; I != List.end(); I++)
37    {
38       Files[Count] = (*I)->CreateSrcParser();
39       if (_error->PendingError() == true)
40          return;
41       if (Files[Count] != 0)
42          Count++;
43    }
44    Files[Count] = 0;
45    
46    // Doesn't work without any source index files
47    if (Count == 0)
48    {
49       _error->Error(_("You must put some 'source' URIs"
50                     " in your sources.list"));
51       return;
52    }   
53
54    Restart();
55 }
56                                                                         /*}}}*/
57 // SrcRecords::~pkgSrcRecords - Destructor                              /*{{{*/
58 // ---------------------------------------------------------------------
59 /* */
60 pkgSrcRecords::~pkgSrcRecords()
61 {
62    if (Files == 0)
63       return;
64
65    // Blow away all the parser objects
66    for (unsigned int Count = 0; Files[Count] != 0; Count++)
67       delete Files[Count];
68    delete [] Files;
69 }
70                                                                         /*}}}*/
71 // SrcRecords::Restart - Restart the search                             /*{{{*/
72 // ---------------------------------------------------------------------
73 /* Return all of the parsers to their starting position */
74 bool pkgSrcRecords::Restart()
75 {
76    Current = Files;
77    for (Parser **I = Files; *I != 0; I++)
78       (*I)->Restart();
79    
80    return true;
81 }
82                                                                         /*}}}*/
83 // SrcRecords::Find - Find the first source package with the given name /*{{{*/
84 // ---------------------------------------------------------------------
85 /* This searches on both source package names and output binary names and
86    returns the first found. A 'cursor' like system is used to allow this
87    function to be called multiple times to get successive entries */
88 pkgSrcRecords::Parser *pkgSrcRecords::Find(const char *Package,bool SrcOnly)
89 {
90    if (*Current == 0)
91       return 0;
92    
93    while (true)
94    {
95       // Step to the next record, possibly switching files
96       while ((*Current)->Step() == false)
97       {
98          if (_error->PendingError() == true)
99             return 0;
100          Current++;
101          if (*Current == 0)
102             return 0;
103       }
104       
105       // IO error somehow
106       if (_error->PendingError() == true)
107          return 0;
108
109       // Source name hit
110       if ((*Current)->Package() == Package)
111          return *Current;
112       
113
114       // CNC:2003-11-21
115       // Check for a files hit
116       vector<pkgSrcRecords::File> Files;
117       if ((*Current)->Files(Files) == true) {
118          vector<pkgSrcRecords::File>::const_iterator I = Files.begin();
119          for (; I != Files.end(); I++) {
120             if (flNotDir(I->Path) == flNotDir(Package))
121                return *Current;
122          }
123       }
124       
125       if (SrcOnly == true)
126          continue;
127       
128       // Check for a binary hit
129       const char **I = (*Current)->Binaries();
130       for (; I != 0 && *I != 0; I++)
131          if (strcmp(Package,*I) == 0)
132             return *Current;
133    }
134 }
135                                                                         /*}}}*/
136 // Parser::BuildDepType - Convert a build dep to a string               /*{{{*/
137 // ---------------------------------------------------------------------
138 /* */
139 const char *pkgSrcRecords::Parser::BuildDepType(unsigned char Type)
140 {
141    const char *fields[] = {"Build-Depends", 
142                            "Build-Depends-Indep",
143                            "Build-Conflicts",
144                            "Build-Conflicts-Indep"};
145    if (Type < 4) 
146       return fields[Type]; 
147    else 
148       return "";
149 }
150                                                                         /*}}}*/
151
152