]> git.saurik.com Git - apt.git/blame - ftparchive/override.cc
Merge remote-tracking branch 'mvo/debian/sid' into debian/sid
[apt.git] / ftparchive / override.cc
CommitLineData
b2e465d6
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
dc738e7a 3// $Id: override.cc,v 1.4 2003/02/10 07:34:41 doogie Exp $
b2e465d6
AL
4/* ######################################################################
5
6 Override
7
8 Store the override file.
9
10 ##################################################################### */
11 /*}}}*/
12// Include Files /*{{{*/
ea542140
DK
13#include <config.h>
14
b2e465d6
AL
15#include <apt-pkg/strutl.h>
16#include <apt-pkg/error.h>
17
18#include <stdio.h>
ea542140 19
b2e465d6 20#include "override.h"
a00a9b44
DK
21
22#include <apti18n.h>
b2e465d6
AL
23 /*}}}*/
24
25// Override::ReadOverride - Read the override file /*{{{*/
26// ---------------------------------------------------------------------
27/* This parses the override file and reads it into the map */
9209ec47 28bool Override::ReadOverride(string const &File,bool const &Source)
b2e465d6
AL
29{
30 if (File.empty() == true)
31 return true;
32
33 FILE *F = fopen(File.c_str(),"r");
34 if (F == 0)
dc738e7a 35 return _error->Errno("fopen",_("Unable to open %s"),File.c_str());
b2e465d6
AL
36
37 char Line[500];
650faab0 38 unsigned long long Counter = 0;
b2e465d6
AL
39 while (fgets(Line,sizeof(Line),F) != 0)
40 {
41 Counter++;
42 Item Itm;
43
44 // Silence
45 for (char *I = Line; *I != 0; I++)
46 if (*I == '#')
47 *I = 0;
48
49 // Strip space leading up to the package name, skip blank lines
50 char *Pkg = Line;
51 for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
1c946b57 52 if (*Pkg == 0)
b2e465d6
AL
53 continue;
54
55 // Find the package and zero..
56 char *Start = Pkg;
57 char *End = Pkg;
58 for (; isspace(*End) == 0 && *End != 0; End++);
59 if (*End == 0)
60 {
650faab0 61 _error->Warning(_("Malformed override %s line %llu #1"),File.c_str(),
b2e465d6
AL
62 Counter);
63 continue;
64 }
65 *End = 0;
66
67 // Find the priority
68 if (Source == false)
69 {
70 for (End++; isspace(*End) != 0 && *End != 0; End++);
71 Start = End;
72 for (; isspace(*End) == 0 && *End != 0; End++);
73 if (*End == 0)
74 {
650faab0 75 _error->Warning(_("Malformed override %s line %llu #2"),File.c_str(),
b2e465d6
AL
76 Counter);
77 continue;
78 }
79 *End = 0;
80 Itm.Priority = Start;
81 }
82
83 // Find the Section
84 for (End++; isspace(*End) != 0 && *End != 0; End++);
85 Start = End;
86 for (; isspace(*End) == 0 && *End != 0; End++);
87 if (*End == 0)
88 {
650faab0 89 _error->Warning(_("Malformed override %s line %llu #3"),File.c_str(),
b2e465d6
AL
90 Counter);
91 continue;
92 }
93 *End = 0;
64177f17 94 Itm.FieldOverride["Section"] = Start;
b2e465d6
AL
95
96 // Source override files only have the two columns
97 if (Source == true)
98 {
99 Mapping[Pkg] = Itm;
100 continue;
101 }
102
103 // Find the =>
104 for (End++; isspace(*End) != 0 && *End != 0; End++);
105 if (*End != 0)
106 {
107 Start = End;
108 for (; *End != 0 && (End[0] != '=' || End[1] != '>'); End++);
109 if (*End == 0 || strlen(End) < 4)
110 {
111 Itm.OldMaint = "*";
112 Itm.NewMaint = _strstrip(Start);
113 }
114 else
115 {
116 *End = 0;
117 Itm.OldMaint = _strstrip(Start);
118
119 End += 3;
120 Itm.NewMaint = _strstrip(End);
121 }
122 }
123
124 Mapping[Pkg] = Itm;
125 }
126
64177f17 127 if (ferror(F))
dc738e7a 128 _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
64177f17
AL
129 fclose(F);
130 return true;
131}
132 /*}}}*/
133// Override::ReadExtraOverride - Read the extra override file /*{{{*/
134// ---------------------------------------------------------------------
135/* This parses the extra override file and reads it into the map */
9209ec47 136bool Override::ReadExtraOverride(string const &File,bool const &Source)
64177f17
AL
137{
138 if (File.empty() == true)
139 return true;
140
141 FILE *F = fopen(File.c_str(),"r");
142 if (F == 0)
dc738e7a 143 return _error->Errno("fopen",_("Unable to open %s"),File.c_str());
64177f17
AL
144
145 char Line[500];
650faab0 146 unsigned long long Counter = 0;
64177f17
AL
147 while (fgets(Line,sizeof(Line),F) != 0)
148 {
149 Counter++;
150
151 // Silence
152 for (char *I = Line; *I != 0; I++)
153 if (*I == '#')
154 *I = 0;
155
156 // Strip space leading up to the package name, skip blank lines
157 char *Pkg = Line;
158 for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
159 if (Pkg == 0)
160 continue;
161
162 // Find the package and zero..
163 char *End = Pkg;
164 for (; isspace(*End) == 0 && *End != 0; End++);
165 if (*End == 0)
166 {
650faab0 167 _error->Warning(_("Malformed override %s line %llu #1"),File.c_str(),
64177f17
AL
168 Counter);
169 continue;
170 }
171 *End = 0;
172
173 // Find the field
174 for (End++; isspace(*End) != 0 && *End != 0; End++);
175 char *Field = End;
176 for (; isspace(*End) == 0 && *End != 0; End++);
177 if (*End == 0)
178 {
650faab0 179 _error->Warning(_("Malformed override %s line %llu #2"),File.c_str(),
64177f17
AL
180 Counter);
181 continue;
182 }
183 *End = 0;
184
185 // Find the field value
186 for (End++; isspace(*End) != 0 && *End != 0; End++);
187 char *Value = End;
188 for (; *End != 0; End++);
189 for (; isspace(*(End-1)) && End > Value; End--);
190 if (End == Value)
191 {
650faab0 192 _error->Warning(_("Malformed override %s line %llu #3"),File.c_str(),
64177f17
AL
193 Counter);
194 continue;
195 }
196 *End = 0;
197
198 Mapping[Pkg].FieldOverride[Field] = Value;
199 }
200
b2e465d6 201 if (ferror(F))
dc738e7a 202 _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
b2e465d6
AL
203 fclose(F);
204 return true;
205}
206 /*}}}*/
0b41e0e7
MV
207
208// Override::GetItem - Get a architecture specific item /*{{{*/
209// ---------------------------------------------------------------------
210/* Returns a override item for the given package and the given architecture.
211 * Treats "all" special
212 */
9209ec47 213Override::Item* Override::GetItem(string const &Package, string const &Architecture)
0b41e0e7 214{
9209ec47 215 map<string,Item>::const_iterator I = Mapping.find(Package);
0b41e0e7
MV
216 map<string,Item>::iterator J = Mapping.find(Package + "/" + Architecture);
217
218 if (I == Mapping.end() && J == Mapping.end())
219 {
220 return 0;
221 }
222
223 Item *result = new Item;
224 if (I == Mapping.end()) *result = J->second;
225 else
226 {
227 *result = I->second;
228 if (J != Mapping.end())
229 {
230 Item *R = &J->second;
231 if (R->Priority != "") result->Priority = R->Priority;
232 if (R->OldMaint != "") result->OldMaint = R->OldMaint;
233 if (R->NewMaint != "") result->NewMaint = R->NewMaint;
9209ec47 234 for (map<string,string>::const_iterator foI = R->FieldOverride.begin();
f7f0d6c7 235 foI != R->FieldOverride.end(); ++foI)
0b41e0e7
MV
236 {
237 result->FieldOverride[foI->first] = foI->second;
238 }
239 }
240 }
241 return result;
242};
243
244
b2e465d6
AL
245// Override::Item::SwapMaint - Swap the maintainer field if necessary /*{{{*/
246// ---------------------------------------------------------------------
247/* Returns the new maintainer string after evaluating the rewriting rule. If
248 there is a rule but it does not match then the empty string is returned,
249 also if there was no rewrite rule the empty string is returned. Failed
250 indicates if there was some kind of problem while rewriting. */
9209ec47 251string Override::Item::SwapMaint(string const &Orig,bool &Failed)
b2e465d6
AL
252{
253 Failed = false;
254
255 // Degenerate case..
256 if (NewMaint.empty() == true)
257 return OldMaint;
258
259 if (OldMaint == "*")
260 return NewMaint;
261
262 /* James: ancient, eliminate it, however it is still being used in the main
263 override file. Thus it persists.*/
264#if 1
265 // Break OldMaint up into little bits on double slash boundaries.
9209ec47 266 string::const_iterator End = OldMaint.begin();
b2e465d6
AL
267 while (1)
268 {
9209ec47 269 string::const_iterator Start = End;
b2e465d6
AL
270 for (; End < OldMaint.end() &&
271 (End + 3 >= OldMaint.end() || End[0] != ' ' ||
f7f0d6c7 272 End[1] != '/' || End[2] != '/'); ++End);
b2e465d6
AL
273 if (stringcasecmp(Start,End,Orig.begin(),Orig.end()) == 0)
274 return NewMaint;
275
276 if (End >= OldMaint.end())
277 break;
278
279 // Skip the divider and white space
f7f0d6c7 280 for (; End < OldMaint.end() && (*End == '/' || *End == ' '); ++End);
b2e465d6
AL
281 }
282#else
283 if (stringcasecmp(OldMaint.begin(),OldMaint.end(),Orig.begin(),Orig.end()) == 0)
284 return NewMaint;
285#endif
286
287 Failed = true;
288 return string();
289}
290 /*}}}*/