Config class and source list
[ntk/apt.git] / apt-pkg / tagfile.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: tagfile.cc,v 1.6 1998/07/09 05:12:32 jgg Exp $
4 /* ######################################################################
5
6 Fast scanner for RFC-822 type header information
7
8 This uses a rotating 64K buffer to load the package information into.
9 The scanner runs over it and isolates and indexes a single section.
10
11 ##################################################################### */
12 /*}}}*/
13 // Include Files /*{{{*/
14 #ifdef __GNUG__
15 #pragma implementation "pkglib/tagfile.h"
16 #endif
17
18 #include <pkglib/tagfile.h>
19 #include <pkglib/error.h>
20 #include <pkglib/init.h>
21
22 #include <string>
23 #include <stdio.h>
24 /*}}}*/
25
26 // TagFile::pkgTagFile - Constructor /*{{{*/
27 // ---------------------------------------------------------------------
28 /* */
29 pkgTagFile::pkgTagFile(File &Fd) : Fd(Fd)
30 {
31 Buffer = new char[64*1024];
32 Start = End = Buffer + 64*1024;
33 Left = Fd.Size();
34 iOffset = 0;
35 Fill();
36 }
37 /*}}}*/
38 // TagFile::Step - Advance to the next section /*{{{*/
39 // ---------------------------------------------------------------------
40 /* If the Section Scanner fails we refill the buffer and try again. */
41 bool pkgTagFile::Step(pkgTagSection &Tag)
42 {
43 if (Tag.Scan(Start,End - Start) == false)
44 {
45 if (Fill() == false)
46 return false;
47
48 if (Tag.Scan(Start,End - Start) == false)
49 return _error->Error("Unable to parse package file");
50 }
51 Start += Tag.size();
52 iOffset += Tag.size();
53
54 return true;
55 }
56 /*}}}*/
57 // TagFile::Fill - Top up the buffer /*{{{*/
58 // ---------------------------------------------------------------------
59 /* This takes the bit at the end of the buffer and puts it at the start
60 then fills the rest from the file */
61 bool pkgTagFile::Fill()
62 {
63 unsigned long Size = End - Start;
64
65 if (Left == 0)
66 {
67 if (Size <= 1)
68 return false;
69 return true;
70 }
71
72 memmove(Buffer,Start,Size);
73 Start = Buffer;
74
75 // See if only a bit of the file is left or if
76 if (Left < End - Buffer - Size)
77 {
78 if (Fd.Read(Buffer + Size,Left) == false)
79 return false;
80 End = Buffer + Size + Left;
81 Left = 0;
82 }
83 else
84 {
85 if (Fd.Read(Buffer + Size, End - Buffer - Size) == false)
86 return false;
87 Left -= End - Buffer - Size;
88 }
89 return true;
90 }
91 /*}}}*/
92 // TagSection::Scan - Scan for the end of the header information /*{{{*/
93 // ---------------------------------------------------------------------
94 /* This looks for the first double new line in the data stream. It also
95 indexes the tags in the section. */
96 bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
97 {
98 const char *End = Start + MaxLength;
99 Stop = Section = Start;
100
101 TagCount = 0;
102 Indexes[TagCount++] = Stop - Section;
103 Stop++;
104 for (; Stop < End; Stop++)
105 {
106 if (Stop[-1] != '\n')
107 continue;
108 if (Stop[0] == '\n')
109 {
110 // Extra one at the end to simplify find
111 Indexes[TagCount] = Stop - Section;
112 for (; Stop[0] == '\n' && Stop < End; Stop++);
113 return true;
114 break;
115 }
116
117 if (isspace(Stop[0]) == 0)
118 Indexes[TagCount++] = Stop - Section;
119
120 // Just in case.
121 if (TagCount > sizeof(Indexes)/sizeof(Indexes[0]))
122 TagCount = sizeof(Indexes)/sizeof(Indexes[0]);
123 }
124 return false;
125 }
126 /*}}}*/
127 // TagSection::Find - Locate a tag /*{{{*/
128 // ---------------------------------------------------------------------
129 /* This searches the section for a tag that matches the given string. */
130 bool pkgTagSection::Find(const char *Tag,const char *&Start,
131 const char *&End)
132 {
133 unsigned int Length = strlen(Tag);
134 for (unsigned int I = 0; I != TagCount; I++)
135 {
136 if (strncasecmp(Tag,Section + Indexes[I],Length) != 0)
137 continue;
138
139 // Make sure the colon is in the right place
140 const char *C = Section + Length + Indexes[I];
141 for (; isspace(*C) != 0; C++);
142 if (*C != ':')
143 continue;
144
145 // Strip off the gunk from the start end
146 Start = C;
147 End = Section + Indexes[I+1];
148 for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++);
149 for (; isspace(End[-1]) != 0 && End > Start; End--);
150 return true;
151 }
152 Start = End = 0;
153 return false;
154 }
155 /*}}}*/
156
157 #include <pkglib/pkgcachegen.h>
158 #include <pkglib/deblistparser.h>
159
160 int main(int argc,char *argv[])
161 {
162 pkglibInitialize(*_config);
163 cout << _config->Find("APT::arch") << endl;
164 cout << _config->FindDir("DIR::Etc::sourcelist") << endl;
165
166 {
167 File CacheF("./cache",File::WriteEmpty);
168 DynamicMMap Map(CacheF,MMap::Public);
169 pkgCacheGenerator Gen(Map);
170
171 for (int I = 1; I != argc; I++)
172 {
173 cout << "Merging in " << argv[I] << endl;
174 File F(argv[I],File::ReadOnly);
175 Gen.SelectFile(argv[I]);
176 debListParser Parser(F);
177 Gen.MergeList(Parser);
178 }
179 }
180 /*
181 {
182 File CacheF("./cache",File::WriteExists);
183 MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
184 pkgCache Cache(Map);
185 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
186 {
187 cout << "Package: " << I.Name() << endl;
188 for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++)
189 {
190 cout << "Version: " << V.VerStr() << endl;
191 cout << "Size: " << V->Size << endl;
192 cout << "Installed-Size: " << V->InstalledSize << endl;
193 cout << "Section: " << V.Section() << endl;
194 cout << "Priority: " << Cache.Priority(V->Priority) << endl;
195
196 pkgCache::PrvIterator P = V.ProvidesList();
197 if (P.end() == false)
198 {
199 cout << "Provides: ";
200 for (; P.end() == false; P++)
201 cout << P.Name() << ", ";
202 cout << endl;
203 }
204 }
205 cout << endl;
206 }
207 }
208 */
209 #if 0
210 pkgTagSection I;
211 while (Test.Step(I) == true)
212 {
213 const char *Start;
214 const char *End;
215 if (I.Find("Package",Start,End) == false)
216 {
217 cout << "Failed" << endl;
218 continue;
219 }
220
221 cout << "Package: " << string(Start,End - Start) << endl;
222
223 /* for (const char *I = Start; I < End; I++)
224 {
225 const char *Begin = I;
226 bool Number = true;
227 while (isspace(*I) == 0 && ispunct(*I) == 0 && I < End)
228 {
229 if (isalpha(*I) != 0)
230 Number = false;
231 I++;
232 }
233 if (Number == false)
234 cout << string(Begin,I-Begin) << endl;
235 while ((isspace(*I) != 0 || ispunct(*I) != 0) && I < End)
236 I++;
237 I--;
238 } */
239 }
240 #endif
241 _error->DumpErrors();
242 }