warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
[ntk/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
62d8a765
DK
55#define APT_FIND_NEXT_FIELD \
56 for (End++; isspace(*End) != 0 && *End != 0; ++End) \
57 /* skip spaces */ ; \
58 Start = End; \
59 for (; isspace(*End) == 0 && *End != 0; ++End) \
60 /* find end of word */ ;
61
62#define APT_WARNING_MALFORMED_LINE(FIELD) \
63 if (*End == 0) \
64 { \
65 _error->Warning(_("Malformed override %s line %llu (%s)"),File.c_str(), \
66 Counter, FIELD ); \
67 continue; \
68 } \
69 *End = 0;
70
b2e465d6 71 // Find the package and zero..
62d8a765 72 char *Start;
b2e465d6
AL
73 char *End = Pkg;
74 for (; isspace(*End) == 0 && *End != 0; End++);
62d8a765
DK
75 APT_WARNING_MALFORMED_LINE("pkgname");
76
77 APT_FIND_NEXT_FIELD;
b2e465d6
AL
78
79 // Find the priority
80 if (Source == false)
81 {
62d8a765 82 APT_WARNING_MALFORMED_LINE("priority");
b2e465d6 83 Itm.Priority = Start;
62d8a765
DK
84
85 APT_FIND_NEXT_FIELD;
b2e465d6 86 }
62d8a765 87
b2e465d6 88 // Find the Section
62d8a765 89 APT_WARNING_MALFORMED_LINE("section");
64177f17 90 Itm.FieldOverride["Section"] = Start;
b2e465d6
AL
91
92 // Source override files only have the two columns
93 if (Source == true)
94 {
95 Mapping[Pkg] = Itm;
96 continue;
97 }
62d8a765 98
b2e465d6
AL
99 // Find the =>
100 for (End++; isspace(*End) != 0 && *End != 0; End++);
101 if (*End != 0)
102 {
103 Start = End;
104 for (; *End != 0 && (End[0] != '=' || End[1] != '>'); End++);
105 if (*End == 0 || strlen(End) < 4)
106 {
107 Itm.OldMaint = "*";
108 Itm.NewMaint = _strstrip(Start);
109 }
110 else
111 {
112 *End = 0;
113 Itm.OldMaint = _strstrip(Start);
114
115 End += 3;
116 Itm.NewMaint = _strstrip(End);
117 }
118 }
119
120 Mapping[Pkg] = Itm;
121 }
122
64177f17 123 if (ferror(F))
dc738e7a 124 _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
64177f17
AL
125 fclose(F);
126 return true;
127}
128 /*}}}*/
129// Override::ReadExtraOverride - Read the extra override file /*{{{*/
130// ---------------------------------------------------------------------
131/* This parses the extra override file and reads it into the map */
9209ec47 132bool Override::ReadExtraOverride(string const &File,bool const &Source)
64177f17
AL
133{
134 if (File.empty() == true)
135 return true;
136
137 FILE *F = fopen(File.c_str(),"r");
138 if (F == 0)
dc738e7a 139 return _error->Errno("fopen",_("Unable to open %s"),File.c_str());
64177f17
AL
140
141 char Line[500];
650faab0 142 unsigned long long Counter = 0;
64177f17
AL
143 while (fgets(Line,sizeof(Line),F) != 0)
144 {
145 Counter++;
146
147 // Silence
148 for (char *I = Line; *I != 0; I++)
149 if (*I == '#')
150 *I = 0;
151
152 // Strip space leading up to the package name, skip blank lines
153 char *Pkg = Line;
154 for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
155 if (Pkg == 0)
156 continue;
157
158 // Find the package and zero..
159 char *End = Pkg;
160 for (; isspace(*End) == 0 && *End != 0; End++);
161 if (*End == 0)
162 {
650faab0 163 _error->Warning(_("Malformed override %s line %llu #1"),File.c_str(),
64177f17
AL
164 Counter);
165 continue;
166 }
167 *End = 0;
168
169 // Find the field
170 for (End++; isspace(*End) != 0 && *End != 0; End++);
171 char *Field = End;
172 for (; isspace(*End) == 0 && *End != 0; End++);
173 if (*End == 0)
174 {
650faab0 175 _error->Warning(_("Malformed override %s line %llu #2"),File.c_str(),
64177f17
AL
176 Counter);
177 continue;
178 }
179 *End = 0;
180
181 // Find the field value
182 for (End++; isspace(*End) != 0 && *End != 0; End++);
183 char *Value = End;
184 for (; *End != 0; End++);
185 for (; isspace(*(End-1)) && End > Value; End--);
186 if (End == Value)
187 {
650faab0 188 _error->Warning(_("Malformed override %s line %llu #3"),File.c_str(),
64177f17
AL
189 Counter);
190 continue;
191 }
192 *End = 0;
193
194 Mapping[Pkg].FieldOverride[Field] = Value;
195 }
196
b2e465d6 197 if (ferror(F))
dc738e7a 198 _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
b2e465d6
AL
199 fclose(F);
200 return true;
201}
202 /*}}}*/
0b41e0e7 203
d3e8fbb3 204// Override::GetItem - Get a architecture specific item /*{{{*/
0b41e0e7
MV
205// ---------------------------------------------------------------------
206/* Returns a override item for the given package and the given architecture.
207 * Treats "all" special
208 */
9209ec47 209Override::Item* Override::GetItem(string const &Package, string const &Architecture)
0b41e0e7 210{
9209ec47 211 map<string,Item>::const_iterator I = Mapping.find(Package);
0b41e0e7
MV
212 map<string,Item>::iterator J = Mapping.find(Package + "/" + Architecture);
213
214 if (I == Mapping.end() && J == Mapping.end())
215 {
216 return 0;
217 }
218
219 Item *result = new Item;
220 if (I == Mapping.end()) *result = J->second;
221 else
222 {
223 *result = I->second;
224 if (J != Mapping.end())
225 {
226 Item *R = &J->second;
227 if (R->Priority != "") result->Priority = R->Priority;
228 if (R->OldMaint != "") result->OldMaint = R->OldMaint;
229 if (R->NewMaint != "") result->NewMaint = R->NewMaint;
9209ec47 230 for (map<string,string>::const_iterator foI = R->FieldOverride.begin();
f7f0d6c7 231 foI != R->FieldOverride.end(); ++foI)
0b41e0e7
MV
232 {
233 result->FieldOverride[foI->first] = foI->second;
234 }
d3e8fbb3
DK
235 }
236 }
0b41e0e7 237 return result;
d3e8fbb3 238}
0b41e0e7
MV
239
240
b2e465d6
AL
241// Override::Item::SwapMaint - Swap the maintainer field if necessary /*{{{*/
242// ---------------------------------------------------------------------
243/* Returns the new maintainer string after evaluating the rewriting rule. If
244 there is a rule but it does not match then the empty string is returned,
245 also if there was no rewrite rule the empty string is returned. Failed
246 indicates if there was some kind of problem while rewriting. */
9209ec47 247string Override::Item::SwapMaint(string const &Orig,bool &Failed)
b2e465d6
AL
248{
249 Failed = false;
250
251 // Degenerate case..
252 if (NewMaint.empty() == true)
253 return OldMaint;
254
255 if (OldMaint == "*")
256 return NewMaint;
257
258 /* James: ancient, eliminate it, however it is still being used in the main
259 override file. Thus it persists.*/
260#if 1
261 // Break OldMaint up into little bits on double slash boundaries.
9209ec47 262 string::const_iterator End = OldMaint.begin();
b2e465d6
AL
263 while (1)
264 {
9209ec47 265 string::const_iterator Start = End;
b2e465d6
AL
266 for (; End < OldMaint.end() &&
267 (End + 3 >= OldMaint.end() || End[0] != ' ' ||
f7f0d6c7 268 End[1] != '/' || End[2] != '/'); ++End);
b2e465d6
AL
269 if (stringcasecmp(Start,End,Orig.begin(),Orig.end()) == 0)
270 return NewMaint;
271
272 if (End >= OldMaint.end())
273 break;
274
275 // Skip the divider and white space
f7f0d6c7 276 for (; End < OldMaint.end() && (*End == '/' || *End == ' '); ++End);
b2e465d6
AL
277 }
278#else
279 if (stringcasecmp(OldMaint.begin(),OldMaint.end(),Orig.begin(),Orig.end()) == 0)
280 return NewMaint;
281#endif
282
283 Failed = true;
284 return string();
285}
286 /*}}}*/