Do not try to cast a pkgDepCache::Policy to a pkgCache
[ntk/apt.git] / apt-pkg / deb / debsrcrecords.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: debsrcrecords.cc,v 1.6 2004/03/17 05:58:54 mdz Exp $
4 /* ######################################################################
5
6 Debian Source Package Records - Parser implementation for Debian style
7 source indexes
8
9 ##################################################################### */
10 /*}}}*/
11 // Include Files /*{{{*/
12 #include <config.h>
13
14 #include <apt-pkg/deblistparser.h>
15 #include <apt-pkg/debsrcrecords.h>
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/strutl.h>
18 #include <apt-pkg/aptconfiguration.h>
19 #include <apt-pkg/srcrecords.h>
20 #include <apt-pkg/tagfile.h>
21
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <algorithm>
26 #include <string>
27 #include <vector>
28 /*}}}*/
29
30 using std::max;
31 using std::string;
32
33 // SrcRecordParser::Binaries - Return the binaries field /*{{{*/
34 // ---------------------------------------------------------------------
35 /* This member parses the binaries field into a pair of class arrays and
36 returns a list of strings representing all of the components of the
37 binaries field. The returned array need not be freed and will be
38 reused by the next Binaries function call. This function is commonly
39 used during scanning to find the right package */
40 const char **debSrcRecordParser::Binaries()
41 {
42 const char *Start, *End;
43 if (Sect.Find("Binary", Start, End) == false)
44 return NULL;
45 for (; isspace(*Start) != 0; ++Start);
46 if (Start >= End)
47 return NULL;
48
49 StaticBinList.clear();
50 free(Buffer);
51 Buffer = strndup(Start, End - Start);
52
53 char* bin = Buffer;
54 do {
55 char* binStartNext = strchrnul(bin, ',');
56 char* binEnd = binStartNext - 1;
57 for (; isspace(*binEnd) != 0; --binEnd)
58 binEnd = '\0';
59 StaticBinList.push_back(bin);
60 if (*binStartNext != ',')
61 break;
62 *binStartNext = '\0';
63 for (bin = binStartNext + 1; isspace(*bin) != 0; ++bin);
64 } while (*bin != '\0');
65 StaticBinList.push_back(NULL);
66
67 return &StaticBinList[0];
68 }
69 /*}}}*/
70 // SrcRecordParser::BuildDepends - Return the Build-Depends information /*{{{*/
71 // ---------------------------------------------------------------------
72 /* This member parses the build-depends information and returns a list of
73 package/version records representing the build dependency. The returned
74 array need not be freed and will be reused by the next call to this
75 function */
76 bool debSrcRecordParser::BuildDepends(std::vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps,
77 bool const &ArchOnly, bool const &StripMultiArch)
78 {
79 unsigned int I;
80 const char *Start, *Stop;
81 BuildDepRec rec;
82 const char *fields[] = {"Build-Depends",
83 "Build-Depends-Indep",
84 "Build-Conflicts",
85 "Build-Conflicts-Indep"};
86
87 BuildDeps.clear();
88
89 for (I = 0; I < 4; I++)
90 {
91 if (ArchOnly && (I == 1 || I == 3))
92 continue;
93
94 if (Sect.Find(fields[I], Start, Stop) == false)
95 continue;
96
97 while (1)
98 {
99 Start = debListParser::ParseDepends(Start, Stop,
100 rec.Package,rec.Version,rec.Op,true,StripMultiArch,true);
101
102 if (Start == 0)
103 return _error->Error("Problem parsing dependency: %s", fields[I]);
104 rec.Type = I;
105
106 if (rec.Package != "")
107 BuildDeps.push_back(rec);
108
109 if (Start == Stop)
110 break;
111 }
112 }
113
114 return true;
115 }
116 /*}}}*/
117 // SrcRecordParser::Files - Return a list of files for this source /*{{{*/
118 // ---------------------------------------------------------------------
119 /* This parses the list of files and returns it, each file is required to have
120 a complete source package */
121 bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
122 {
123 List.erase(List.begin(),List.end());
124
125 string Files = Sect.FindS("Files");
126 if (Files.empty() == true)
127 return false;
128
129 // Stash the / terminated directory prefix
130 string Base = Sect.FindS("Directory");
131 if (Base.empty() == false && Base[Base.length()-1] != '/')
132 Base += '/';
133
134 std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions();
135
136 // Iterate over the entire list grabbing each triplet
137 const char *C = Files.c_str();
138 while (*C != 0)
139 {
140 pkgSrcRecords::File F;
141 string Size;
142
143 // Parse each of the elements
144 if (ParseQuoteWord(C,F.MD5Hash) == false ||
145 ParseQuoteWord(C,Size) == false ||
146 ParseQuoteWord(C,F.Path) == false)
147 return _error->Error("Error parsing file record");
148
149 // Parse the size and append the directory
150 F.Size = atoi(Size.c_str());
151 F.Path = Base + F.Path;
152
153 // Try to guess what sort of file it is we are getting.
154 string::size_type Pos = F.Path.length()-1;
155 while (1)
156 {
157 string::size_type Tmp = F.Path.rfind('.',Pos);
158 if (Tmp == string::npos)
159 break;
160 if (F.Type == "tar") {
161 // source v3 has extension 'debian.tar.*' instead of 'diff.*'
162 if (string(F.Path, Tmp+1, Pos-Tmp) == "debian")
163 F.Type = "diff";
164 break;
165 }
166 F.Type = string(F.Path,Tmp+1,Pos-Tmp);
167
168 if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() ||
169 F.Type == "tar")
170 {
171 Pos = Tmp-1;
172 continue;
173 }
174
175 break;
176 }
177
178 List.push_back(F);
179 }
180
181 return true;
182 }
183 /*}}}*/
184 // SrcRecordParser::~SrcRecordParser - Destructor /*{{{*/
185 // ---------------------------------------------------------------------
186 /* */
187 debSrcRecordParser::~debSrcRecordParser()
188 {
189 delete[] Buffer;
190 }
191 /*}}}*/