]> git.saurik.com Git - apt.git/blob - apt-pkg/deb/debsrcrecords.cc
add support for apt-get build-dep foo.dsc
[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 #include <apt-pkg/gpgv.h>
22
23 #include <ctype.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <algorithm>
27 #include <string>
28 #include <vector>
29 /*}}}*/
30
31 using std::max;
32 using std::string;
33
34 // SrcRecordParser::Binaries - Return the binaries field /*{{{*/
35 // ---------------------------------------------------------------------
36 /* This member parses the binaries field into a pair of class arrays and
37 returns a list of strings representing all of the components of the
38 binaries field. The returned array need not be freed and will be
39 reused by the next Binaries function call. This function is commonly
40 used during scanning to find the right package */
41 const char **debSrcRecordParser::Binaries()
42 {
43 const char *Start, *End;
44 if (Sect.Find("Binary", Start, End) == false)
45 return NULL;
46 for (; isspace(*Start) != 0; ++Start);
47 if (Start >= End)
48 return NULL;
49
50 StaticBinList.clear();
51 free(Buffer);
52 Buffer = strndup(Start, End - Start);
53
54 char* bin = Buffer;
55 do {
56 char* binStartNext = strchrnul(bin, ',');
57 char* binEnd = binStartNext - 1;
58 for (; isspace(*binEnd) != 0; --binEnd)
59 binEnd = '\0';
60 StaticBinList.push_back(bin);
61 if (*binStartNext != ',')
62 break;
63 *binStartNext = '\0';
64 for (bin = binStartNext + 1; isspace(*bin) != 0; ++bin);
65 } while (*bin != '\0');
66 StaticBinList.push_back(NULL);
67
68 return &StaticBinList[0];
69 }
70 /*}}}*/
71 // SrcRecordParser::BuildDepends - Return the Build-Depends information /*{{{*/
72 // ---------------------------------------------------------------------
73 /* This member parses the build-depends information and returns a list of
74 package/version records representing the build dependency. The returned
75 array need not be freed and will be reused by the next call to this
76 function */
77 bool debSrcRecordParser::BuildDepends(std::vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps,
78 bool const &ArchOnly, bool const &StripMultiArch)
79 {
80 unsigned int I;
81 const char *Start, *Stop;
82 BuildDepRec rec;
83 const char *fields[] = {"Build-Depends",
84 "Build-Depends-Indep",
85 "Build-Conflicts",
86 "Build-Conflicts-Indep"};
87
88 BuildDeps.clear();
89
90 for (I = 0; I < 4; I++)
91 {
92 if (ArchOnly && (I == 1 || I == 3))
93 continue;
94
95 if (Sect.Find(fields[I], Start, Stop) == false)
96 continue;
97
98 while (1)
99 {
100 Start = debListParser::ParseDepends(Start, Stop,
101 rec.Package,rec.Version,rec.Op,true,StripMultiArch,true);
102
103 if (Start == 0)
104 return _error->Error("Problem parsing dependency: %s", fields[I]);
105 rec.Type = I;
106
107 if (rec.Package != "")
108 BuildDeps.push_back(rec);
109
110 if (Start == Stop)
111 break;
112 }
113 }
114
115 return true;
116 }
117 /*}}}*/
118 // SrcRecordParser::Files - Return a list of files for this source /*{{{*/
119 // ---------------------------------------------------------------------
120 /* This parses the list of files and returns it, each file is required to have
121 a complete source package */
122 bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
123 {
124 List.erase(List.begin(),List.end());
125
126 string Files = Sect.FindS("Files");
127 if (Files.empty() == true)
128 return false;
129
130 // Stash the / terminated directory prefix
131 string Base = Sect.FindS("Directory");
132 if (Base.empty() == false && Base[Base.length()-1] != '/')
133 Base += '/';
134
135 std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions();
136
137 // Iterate over the entire list grabbing each triplet
138 const char *C = Files.c_str();
139 while (*C != 0)
140 {
141 pkgSrcRecords::File F;
142 string Size;
143
144 // Parse each of the elements
145 if (ParseQuoteWord(C,F.MD5Hash) == false ||
146 ParseQuoteWord(C,Size) == false ||
147 ParseQuoteWord(C,F.Path) == false)
148 return _error->Error("Error parsing file record");
149
150 // Parse the size and append the directory
151 F.Size = atoi(Size.c_str());
152 F.Path = Base + F.Path;
153
154 // Try to guess what sort of file it is we are getting.
155 string::size_type Pos = F.Path.length()-1;
156 while (1)
157 {
158 string::size_type Tmp = F.Path.rfind('.',Pos);
159 if (Tmp == string::npos)
160 break;
161 if (F.Type == "tar") {
162 // source v3 has extension 'debian.tar.*' instead of 'diff.*'
163 if (string(F.Path, Tmp+1, Pos-Tmp) == "debian")
164 F.Type = "diff";
165 break;
166 }
167 F.Type = string(F.Path,Tmp+1,Pos-Tmp);
168
169 if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() ||
170 F.Type == "tar")
171 {
172 Pos = Tmp-1;
173 continue;
174 }
175
176 break;
177 }
178
179 List.push_back(F);
180 }
181
182 return true;
183 }
184 /*}}}*/
185 // SrcRecordParser::~SrcRecordParser - Destructor /*{{{*/
186 // ---------------------------------------------------------------------
187 /* */
188 debSrcRecordParser::~debSrcRecordParser()
189 {
190 delete[] Buffer;
191 }
192 /*}}}*/
193
194
195 debDscRecordParser::debDscRecordParser(std::string const &DscFile)
196 : debSrcRecordParser(DscFile, NULL)
197 {
198 // support clear signed files
199 if (OpenMaybeClearSignedFile(DscFile, Fd) == false)
200 {
201 _error->Error("Failed to open %s", DscFile.c_str());
202 return;
203 }
204
205 // re-init to ensure the updated Fd is used
206 Tags.Init(&Fd);
207 // read the first (and only) record
208 Step();
209
210 }