- initial import of revision 374 from cnc
[apt.git] / apt-pkg / deb / debsrcrecords.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description                                                          /*{{{*/
3 // $Id: debsrcrecords.cc,v 1.2 2002/07/25 18:07:18 niemeyer Exp $
4 /* ######################################################################
5    
6    Debian Source Package Records - Parser implementation for Debian style
7                                    source indexes
8       
9    ##################################################################### */
10                                                                         /*}}}*/
11 // Include Files                                                        /*{{{*/
12 #ifdef __GNUG__
13 #pragma implementation "apt-pkg/debsrcrecords.h"
14 #endif 
15
16 #include <apt-pkg/deblistparser.h>
17 #include <apt-pkg/debsrcrecords.h>
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/strutl.h>
20 #include <apt-pkg/configuration.h>
21                                                                         /*}}}*/
22
23 // SrcRecordParser::Binaries - Return the binaries field                /*{{{*/
24 // ---------------------------------------------------------------------
25 /* This member parses the binaries field into a pair of class arrays and
26    returns a list of strings representing all of the components of the
27    binaries field. The returned array need not be freed and will be
28    reused by the next Binaries function call. This function is commonly
29    used during scanning to find the right package */
30 const char **debSrcRecordParser::Binaries()
31 {
32    // This should use Start/Stop too, it is supposed to be efficient after all.
33    string Bins = Sect.FindS("Binary");
34    if (Bins.empty() == true || Bins.length() >= sizeof(Buffer))
35       return 0;
36    
37    strcpy(Buffer,Bins.c_str());
38    if (TokSplitString(',',Buffer,StaticBinList,
39                       sizeof(StaticBinList)/sizeof(StaticBinList[0])) == false)
40       return 0;
41    return (const char **)StaticBinList;
42 }
43                                                                         /*}}}*/
44 // SrcRecordParser::BuildDepends - Return the Build-Depends information /*{{{*/
45 // ---------------------------------------------------------------------
46 /* This member parses the build-depends information and returns a list of 
47    package/version records representing the build dependency. The returned 
48    array need not be freed and will be reused by the next call to this 
49    function */
50 bool debSrcRecordParser::BuildDepends(vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps, bool ArchOnly)
51 {
52    unsigned int I;
53    const char *Start, *Stop;
54    BuildDepRec rec;
55    const char *fields[] = {"Build-Depends", 
56                            "Build-Depends-Indep",
57                            "Build-Conflicts",
58                            "Build-Conflicts-Indep"};
59
60    BuildDeps.clear();
61
62    for (I = 0; I < 4; I++) 
63    {
64       if (ArchOnly && (I == 1 || I == 3))
65          continue;
66
67       if (Sect.Find(fields[I], Start, Stop) == false)
68          continue;
69       
70       while (1)
71       {
72          Start = debListParser::ParseDepends(Start, Stop, 
73                      rec.Package,rec.Version,rec.Op,true);
74          
75          if (Start == 0) 
76             return _error->Error("Problem parsing dependency: %s", fields[I]);
77          rec.Type = I;
78
79          if (rec.Package != "")
80             BuildDeps.push_back(rec);
81          
82          if (Start == Stop) 
83             break;
84       }  
85    }
86    
87    return true;
88 }
89                                                                         /*}}}*/
90 // SrcRecordParser::Files - Return a list of files for this source      /*{{{*/
91 // ---------------------------------------------------------------------
92 /* This parses the list of files and returns it, each file is required to have
93    a complete source package */
94 bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
95 {
96    List.erase(List.begin(),List.end());
97    
98    string Files = Sect.FindS("Files");
99    if (Files.empty() == true)
100       return false;
101
102    // Stash the / terminated directory prefix
103    string Base = Sect.FindS("Directory");
104    if (Base.empty() == false && Base[Base.length()-1] != '/')
105       Base += '/';
106    
107    // Iterate over the entire list grabbing each triplet
108    const char *C = Files.c_str();
109    while (*C != 0)
110    {   
111       pkgSrcRecords::File F;
112       string Size;
113       
114       // Parse each of the elements
115       if (ParseQuoteWord(C,F.MD5Hash) == false ||
116           ParseQuoteWord(C,Size) == false ||
117           ParseQuoteWord(C,F.Path) == false)
118          return _error->Error("Error parsing file record");
119       
120       // Parse the size and append the directory
121       F.Size = atoi(Size.c_str());
122       F.Path = Base + F.Path;
123       
124       // Try to guess what sort of file it is we are getting.
125       string::size_type Pos = F.Path.length()-1;
126       while (1)
127       {
128          string::size_type Tmp = F.Path.rfind('.',Pos);
129          if (Tmp == string::npos)
130             break;
131          F.Type = string(F.Path,Tmp+1,Pos-Tmp);
132          
133          if (F.Type == "gz" || F.Type == "bz2")
134          {
135             Pos = Tmp-1;
136             continue;
137          }
138          
139          break;
140       }
141       
142       List.push_back(F);
143    }
144    
145    return true;
146 }
147                                                                         /*}}}*/