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