Merge with Matt
[ntk/apt.git] / apt-pkg / deb / debsrcrecords.cc
CommitLineData
11e7af84
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
c33b707e 3// $Id: debsrcrecords.cc,v 1.6 2004/03/17 05:58:54 mdz Exp $
11e7af84
AL
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
b2e465d6 16#include <apt-pkg/deblistparser.h>
11e7af84
AL
17#include <apt-pkg/debsrcrecords.h>
18#include <apt-pkg/error.h>
36f610f1 19#include <apt-pkg/strutl.h>
b2e465d6 20#include <apt-pkg/configuration.h>
11e7af84
AL
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
b2e465d6
AL
28 reused by the next Binaries function call. This function is commonly
29 used during scanning to find the right package */
11e7af84
AL
30const char **debSrcRecordParser::Binaries()
31{
b2e465d6 32 // This should use Start/Stop too, it is supposed to be efficient after all.
11e7af84 33 string Bins = Sect.FindS("Binary");
c33b707e 34 if (Bins.empty() == true || Bins.length() >= 102400)
11e7af84
AL
35 return 0;
36
c33b707e
AL
37 // Workaround for #236688. Only allocate a new buffer if the field
38 // is large, to avoid a performance penalty
39 char *BigBuf = NULL;
40 char *Buf;
41 if (Bins.length() > sizeof(Buffer))
42 {
43 BigBuf = new char[Bins.length()];
44 Buf = BigBuf;
45 }
46 else
47 {
48 Buf = Buffer;
49 }
50
51 strcpy(Buf,Bins.c_str());
52 if (TokSplitString(',',Buf,StaticBinList,
b2e465d6 53 sizeof(StaticBinList)/sizeof(StaticBinList[0])) == false)
c33b707e
AL
54 {
55 if (BigBuf != NULL)
56 delete BigBuf;
b2e465d6 57 return 0;
c33b707e
AL
58 }
59
60 if (BigBuf != NULL)
61 delete BigBuf;
b2e465d6
AL
62 return (const char **)StaticBinList;
63}
64 /*}}}*/
65// SrcRecordParser::BuildDepends - Return the Build-Depends information /*{{{*/
66// ---------------------------------------------------------------------
67/* This member parses the build-depends information and returns a list of
68 package/version records representing the build dependency. The returned
69 array need not be freed and will be reused by the next call to this
70 function */
45430cbf 71bool debSrcRecordParser::BuildDepends(vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps, bool ArchOnly)
b2e465d6
AL
72{
73 unsigned int I;
74 const char *Start, *Stop;
75 BuildDepRec rec;
76 const char *fields[] = {"Build-Depends",
77 "Build-Depends-Indep",
78 "Build-Conflicts",
79 "Build-Conflicts-Indep"};
80
81 BuildDeps.clear();
11e7af84 82
b2e465d6 83 for (I = 0; I < 4; I++)
11e7af84 84 {
45430cbf
AL
85 if (ArchOnly && (I == 1 || I == 3))
86 continue;
87
b2e465d6
AL
88 if (Sect.Find(fields[I], Start, Stop) == false)
89 continue;
11e7af84 90
b2e465d6
AL
91 while (1)
92 {
93 Start = debListParser::ParseDepends(Start, Stop,
94 rec.Package,rec.Version,rec.Op,true);
95
96 if (Start == 0)
97 return _error->Error("Problem parsing dependency: %s", fields[I]);
98 rec.Type = I;
99
100 if (rec.Package != "")
101 BuildDeps.push_back(rec);
102
103 if (Start == Stop)
104 break;
105 }
11e7af84
AL
106 }
107
b2e465d6 108 return true;
11e7af84
AL
109}
110 /*}}}*/
36f610f1
AL
111// SrcRecordParser::Files - Return a list of files for this source /*{{{*/
112// ---------------------------------------------------------------------
113/* This parses the list of files and returns it, each file is required to have
114 a complete source package */
115bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
116{
117 List.erase(List.begin(),List.end());
118
119 string Files = Sect.FindS("Files");
120 if (Files.empty() == true)
121 return false;
122
123 // Stash the / terminated directory prefix
36375005 124 string Base = Sect.FindS("Directory");
36f610f1
AL
125 if (Base.empty() == false && Base[Base.length()-1] != '/')
126 Base += '/';
36375005 127
36f610f1
AL
128 // Iterate over the entire list grabbing each triplet
129 const char *C = Files.c_str();
130 while (*C != 0)
131 {
132 pkgSrcRecords::File F;
133 string Size;
134
135 // Parse each of the elements
136 if (ParseQuoteWord(C,F.MD5Hash) == false ||
137 ParseQuoteWord(C,Size) == false ||
138 ParseQuoteWord(C,F.Path) == false)
139 return _error->Error("Error parsing file record");
140
141 // Parse the size and append the directory
142 F.Size = atoi(Size.c_str());
143 F.Path = Base + F.Path;
b2e465d6
AL
144
145 // Try to guess what sort of file it is we are getting.
146 string::size_type Pos = F.Path.length()-1;
147 while (1)
148 {
149 string::size_type Tmp = F.Path.rfind('.',Pos);
150 if (Tmp == string::npos)
151 break;
152 F.Type = string(F.Path,Tmp+1,Pos-Tmp);
153
154 if (F.Type == "gz" || F.Type == "bz2")
155 {
156 Pos = Tmp-1;
157 continue;
158 }
159
160 break;
161 }
162
36f610f1
AL
163 List.push_back(F);
164 }
165
166 return true;
167}
168 /*}}}*/