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