renamed some macros to please doogie :P
[ntk/apt.git] / ftparchive / override.cc
CommitLineData
b2e465d6
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
3// $Id: override.cc,v 1.2 2001/02/20 07:03:18 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 */
30bool 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.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::Item::SwapMaint - Swap the maintainer field if necessary /*{{{*/
136// ---------------------------------------------------------------------
137/* Returns the new maintainer string after evaluating the rewriting rule. If
138 there is a rule but it does not match then the empty string is returned,
139 also if there was no rewrite rule the empty string is returned. Failed
140 indicates if there was some kind of problem while rewriting. */
141string Override::Item::SwapMaint(string Orig,bool &Failed)
142{
143 Failed = false;
144
145 // Degenerate case..
146 if (NewMaint.empty() == true)
147 return OldMaint;
148
149 if (OldMaint == "*")
150 return NewMaint;
151
152 /* James: ancient, eliminate it, however it is still being used in the main
153 override file. Thus it persists.*/
154#if 1
155 // Break OldMaint up into little bits on double slash boundaries.
156 string::iterator End = OldMaint.begin();
157 while (1)
158 {
159 string::iterator Start = End;
160 for (; End < OldMaint.end() &&
161 (End + 3 >= OldMaint.end() || End[0] != ' ' ||
162 End[1] != '/' || End[2] != '/'); End++);
163 if (stringcasecmp(Start,End,Orig.begin(),Orig.end()) == 0)
164 return NewMaint;
165
166 if (End >= OldMaint.end())
167 break;
168
169 // Skip the divider and white space
170 for (; End < OldMaint.end() && (*End == '/' || *End == ' '); End++);
171 }
172#else
173 if (stringcasecmp(OldMaint.begin(),OldMaint.end(),Orig.begin(),Orig.end()) == 0)
174 return NewMaint;
175#endif
176
177 Failed = true;
178 return string();
179}
180 /*}}}*/