]>
Commit | Line | Data |
---|---|---|
f55a958f AL |
1 | // -*- mode: cpp; mode: fold -*- |
2 | // Description /*{{{*/ | |
3 | // $Id: deblistparser.cc,v 1.1 1998/07/04 05:58:08 jgg Exp $ | |
4 | /* ###################################################################### | |
5 | ||
6 | Package Cache Generator - Generator for the cache structure. | |
7 | ||
8 | This builds the cache structure from the abstract package list parser. | |
9 | ||
10 | ##################################################################### */ | |
11 | /*}}}*/ | |
12 | // Include Files /*{{{*/ | |
13 | #include <pkglib/deblistparser.h> | |
14 | #include <pkglib/error.h> | |
15 | #include <system.h> | |
16 | /*}}}*/ | |
17 | ||
18 | // ListParser::debListParser - Constructor /*{{{*/ | |
19 | // --------------------------------------------------------------------- | |
20 | /* */ | |
21 | debListParser::debListParser(File &File) : Tags(File) | |
22 | { | |
23 | Step(); | |
24 | } | |
25 | /*}}}*/ | |
26 | // ListParser::FindTag - Find the tag and return a string /*{{{*/ | |
27 | // --------------------------------------------------------------------- | |
28 | /* */ | |
29 | string debListParser::FindTag(const char *Tag) | |
30 | { | |
31 | const char *Start; | |
32 | const char *Stop; | |
33 | if (Section.Find(Tag,Start,Stop) == false) | |
34 | return string(); | |
35 | return string(Start,Stop - Start); | |
36 | } | |
37 | /*}}}*/ | |
38 | // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ | |
39 | // --------------------------------------------------------------------- | |
40 | /* */ | |
41 | unsigned long debListParser::UniqFindTagWrite(const char *Tag) | |
42 | { | |
43 | const char *Start; | |
44 | const char *Stop; | |
45 | if (Section.Find(Tag,Start,Stop) == false) | |
46 | return 0; | |
47 | return WriteUniqString(Start,Stop - Start); | |
48 | } | |
49 | /*}}}*/ | |
50 | // ListParser::HandleFlag - Sets a flag variable based on a tag /*{{{*/ | |
51 | // --------------------------------------------------------------------- | |
52 | /* This checks the tag for true/false yes/no etc */ | |
53 | bool debListParser::HandleFlag(const char *Tag,unsigned long &Flags, | |
54 | unsigned long Flag) | |
55 | { | |
56 | const char *Start; | |
57 | const char *Stop; | |
58 | if (Section.Find(Tag,Start,Stop) == false) | |
59 | return true; | |
60 | ||
61 | int Set = 2; | |
62 | if (strncasecmp(Start,"yes",Stop - Start) == 0) | |
63 | Set = 1; | |
64 | if (strncasecmp(Start,"true",Stop - Start) == 0) | |
65 | Set = 1; | |
66 | if (strncasecmp(Start,"no",Stop - Start) == 0) | |
67 | Set = 0; | |
68 | if (strncasecmp(Start,"false",Stop - Start) == 0) | |
69 | Set = 0; | |
70 | if (Set == 2) | |
71 | { | |
72 | _error->Warning("Unknown flag value"); | |
73 | return true; | |
74 | } | |
75 | ||
76 | if (Set == 0) | |
77 | Flags &= ~Flag; | |
78 | if (Set == 1) | |
79 | Flags |= Flag; | |
80 | return true; | |
81 | } | |
82 | /*}}}*/ | |
83 | // ListParser::Package - Return the package name /*{{{*/ | |
84 | // --------------------------------------------------------------------- | |
85 | /* This is to return the name of the package this section describes */ | |
86 | string debListParser::Package() | |
87 | { | |
88 | string Result = FindTag("Package"); | |
89 | if (Result.empty() == true) | |
90 | _error->Error("Encoutered a section with no Package: header"); | |
91 | return Result; | |
92 | } | |
93 | /*}}}*/ | |
94 | // ListParser::Version - Return the version string /*{{{*/ | |
95 | // --------------------------------------------------------------------- | |
96 | /* This is to return the string describing the version in debian form, | |
97 | epoch:upstream-release. If this returns the blank string then the | |
98 | entry is assumed to only describe package properties */ | |
99 | string debListParser::Version() | |
100 | { | |
101 | return FindTag("Version"); | |
102 | } | |
103 | /*}}}*/ | |
104 | // ListParser::NewPackage - Fill in the package structure /*{{{*/ | |
105 | // --------------------------------------------------------------------- | |
106 | /* This is called when a new package structure is created. It must fill | |
107 | in the static package information. */ | |
108 | bool debListParser::NewPackage(pkgCache::PkgIterator Pkg) | |
109 | { | |
110 | // Debian doesnt have anything, everything is condionally megered | |
111 | return true; | |
112 | } | |
113 | /*}}}*/ | |
114 | // ListParser::NewVersion - Fill in the version structure /*{{{*/ | |
115 | // --------------------------------------------------------------------- | |
116 | /* */ | |
117 | bool debListParser::NewVersion(pkgCache::VerIterator Ver) | |
118 | { | |
119 | return true; | |
120 | } | |
121 | /*}}}*/ | |
122 | // ListParser::UsePackage - Update a package structure /*{{{*/ | |
123 | // --------------------------------------------------------------------- | |
124 | /* This is called to update the package with any new information | |
125 | that might be found in the section */ | |
126 | bool debListParser::UsePackage(pkgCache::PkgIterator Pkg, | |
127 | pkgCache::VerIterator Ver) | |
128 | { | |
129 | if (Pkg->Section == 0) | |
130 | if ((Pkg->Section = UniqFindTagWrite("Section")) == 0) | |
131 | return false; | |
132 | if (HandleFlag("Essential",Pkg->Flags,pkgCache::Essential) == false) | |
133 | return false; | |
134 | if (HandleFlag("Immediate-Configure",Pkg->Flags,pkgCache::ImmediateConf) == false) | |
135 | return false; | |
136 | if (ParseStatus(Pkg,Ver) == false) | |
137 | return false; | |
138 | return true; | |
139 | } | |
140 | /*}}}*/ | |
141 | // ListParser::ParseStatus - Parse the status feild /*{{{*/ | |
142 | // --------------------------------------------------------------------- | |
143 | /* Status lines are of the form, | |
144 | Status: want flag status | |
145 | want = unknown, install, hold, deinstall, purge | |
146 | flag = ok, reinstreq, hold, hold-reinstreq | |
147 | status = not-installed, unpacked, half-configured, uninstalled, | |
148 | half-installed, config-files, post-inst-failed, | |
149 | removal-failed, installed | |
150 | ||
151 | Some of the above are obsolete (I think?) flag = hold-* and | |
152 | status = post-inst-failed, removal-failed at least. | |
153 | */ | |
154 | bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg, | |
155 | pkgCache::VerIterator Ver) | |
156 | { | |
157 | const char *Start; | |
158 | const char *Stop; | |
159 | if (Section.Find("Status",Start,Stop) == false) | |
160 | return true; | |
161 | ||
162 | // Isolate the first word | |
163 | const char *I = Start; | |
164 | for(; I < Stop && *I != ' '; I++); | |
165 | if (I >= Stop || *I != ' ') | |
166 | return _error->Error("Malformed Status line"); | |
167 | ||
168 | // Process the want field | |
169 | WordList WantList[] = {{"unknown",pkgCache::Unknown}, | |
170 | {"install",pkgCache::Install}, | |
171 | {"hold",pkgCache::Hold}, | |
172 | {"deinstall",pkgCache::DeInstall}, | |
173 | {"purge",pkgCache::Purge}}; | |
174 | if (GrabWord(string(Start,I-Start),WantList, | |
175 | _count(WantList),Pkg->SelectedState) == false) | |
176 | return _error->Error("Malformed 1st word in the Status line"); | |
177 | ||
178 | // Isloate the next word | |
179 | I++; | |
180 | Start = I; | |
181 | for(; I < Stop && *I != ' '; I++); | |
182 | if (I >= Stop || *I != ' ') | |
183 | return _error->Error("Malformed status line, no 2nd word"); | |
184 | ||
185 | // Process the flag field | |
186 | WordList FlagList[] = {{"ok",pkgCache::Ok}, | |
187 | {"reinstreq",pkgCache::ReInstReq}, | |
188 | {"hold",pkgCache::HoldInst}, | |
189 | {"hold-reinstreq",pkgCache::HoldReInstReq}}; | |
190 | if (GrabWord(string(Start,I-Start),FlagList, | |
191 | _count(FlagList),Pkg->InstState) == false) | |
192 | return _error->Error("Malformed 2nd word in the Status line"); | |
193 | ||
194 | // Isloate the last word | |
195 | I++; | |
196 | Start = I; | |
197 | for(; I < Stop && *I != ' '; I++); | |
198 | if (I != Stop) | |
199 | return _error->Error("Malformed Status line, no 3rd word"); | |
200 | ||
201 | // Process the flag field | |
202 | WordList StatusList[] = {{"not-installed",pkgCache::NotInstalled}, | |
203 | {"unpacked",pkgCache::UnPacked}, | |
204 | {"half-configured",pkgCache::HalfConfigured}, | |
205 | {"installed",pkgCache::Installed}, | |
206 | {"uninstalled",pkgCache::UnInstalled}, | |
207 | {"half-installed",pkgCache::HalfInstalled}, | |
208 | {"config-files",pkgCache::ConfigFiles}, | |
209 | {"post-inst-failed",pkgCache::HalfConfigured}, | |
210 | {"removal-failed",pkgCache::HalfInstalled}}; | |
211 | if (GrabWord(string(Start,I-Start),StatusList, | |
212 | _count(StatusList),Pkg->CurrentState) == false) | |
213 | return _error->Error("Malformed 3rd word in the Status line"); | |
214 | ||
215 | /* A Status line marks the package as indicating the current | |
216 | version as well. Only if it is actually installed.. Otherwise | |
217 | the interesting dpkg handling of the status file creates bogus | |
218 | entries. */ | |
219 | if (!(Pkg->CurrentState == pkgCache::NotInstalled || | |
220 | Pkg->CurrentState == pkgCache::ConfigFiles)) | |
221 | { | |
222 | if (Ver.end() == true) | |
223 | _error->Warning("Encountered status field in a non-version description"); | |
224 | else | |
225 | Pkg->CurrentVer = Ver.Index(); | |
226 | } | |
227 | ||
228 | return true; | |
229 | } | |
230 | /*}}}*/ | |
231 | // ListParser::GrabWord - Matches a word and returns /*{{{*/ | |
232 | // --------------------------------------------------------------------- | |
233 | /* Looks for a word in a list of words - for ParseStatus */ | |
234 | bool debListParser::GrabWord(string Word,WordList *List,int Count, | |
235 | unsigned char &Out) | |
236 | { | |
237 | for (int C = 0; C != Count; C++) | |
238 | { | |
239 | if (strcasecmp(Word.c_str(),List[C].Str) == 0) | |
240 | { | |
241 | Out = List[C].Val; | |
242 | return true; | |
243 | } | |
244 | } | |
245 | return false; | |
246 | } | |
247 | /*}}}*/ | |
248 | // ListParser::Step - Move to the next section in the file /*{{{*/ | |
249 | // --------------------------------------------------------------------- | |
250 | /* */ | |
251 | bool debListParser::Step() | |
252 | { | |
253 | return Tags.Step(Section); | |
254 | } | |
255 | /*}}}*/ |