]> cygwin.com Git - cygwin-apps/setup.git/blob - IniDBBuilderPackage.cc
2004-12-26 Max Bowsher <maxb@ukf.net>
[cygwin-apps/setup.git] / IniDBBuilderPackage.cc
1 /*
2 * Copyright (c) 2002, Robert Collins.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
16 #include "IniDBBuilderPackage.h"
17
18 #include "csu_util/version_compare.h"
19
20 #include "setup_version.h"
21
22 #include "IniParseFeedback.h"
23 #include "package_db.h"
24 #include "package_meta.h"
25 #include "package_version.h"
26 #include "cygpackage.h"
27 #include "filemanip.h"
28 // for strtoul
29 #include <string.h>
30 #include "LogSingleton.h"
31 #include "PackageSpecification.h"
32 #include <algorithm>
33
34 using namespace std;
35
36 IniDBBuilderPackage::IniDBBuilderPackage (IniParseFeedback const &aFeedback) :
37 cp (0), cbpv (), cspv (), currentSpec (0), currentOrList (0), currentAndList (0), trust (0), _feedback (aFeedback){}
38
39 inline bool lt_packagemeta(packagemeta *p1, packagemeta *p2)
40 { return p1->name.casecompare(p2->name) < 0; }
41
42 IniDBBuilderPackage::~IniDBBuilderPackage()
43 {
44 packagedb db;
45 sort (db.packages.begin(), db.packages.end(), lt_packagemeta);
46 }
47
48 void
49 IniDBBuilderPackage::buildTimestamp (String const &time)
50 {
51 timestamp = strtoul (time.cstr_oneuse(), 0, 0);
52 }
53
54 void
55 IniDBBuilderPackage::buildVersion (String const &aVersion)
56 {
57 version = aVersion;
58 if (version.size())
59 {
60 if (version_compare(setup_version, version) < 0)
61 _feedback.warning("The current ini file is from a newer version of setup.exe. If you have any trouble installing, please download a fresh version from http://www.cygwin.com/setup.exe");
62 }
63 }
64
65 void
66 IniDBBuilderPackage::buildPackage (String const &name)
67 {
68 #if DEBUG
69 if (cp)
70 {
71 log (LOG_BABBLE) << "Finished with package " << cp->name << endLog;
72 if (cbpv)
73 {
74 log (LOG_BABBLE) << "Version " << cbpv.Canonical_version() << endLog;
75 log (LOG_BABBLE) << "Depends:" << endLog;
76 dumpAndList (cbpv.depends(), log(LOG_BABBLE));
77 }
78 }
79 #endif
80 packagedb db;
81 cp = db.findBinary (PackageSpecification(name));
82 if (!cp)
83 {
84 cp = new packagemeta (name);
85 db.packages.push_back (cp);
86 }
87 cbpv = cygpackage::createInstance (name);
88 cspv = packageversion ();
89 currentSpec = NULL;
90 currentOrList = NULL;
91 currentAndList = NULL;
92 trust = TRUST_CURR;
93 #if DEBUG
94 log (LOG_BABBLE) << "Created package " << name << endLog;
95 #endif
96 }
97
98 void
99 IniDBBuilderPackage::buildPackageVersion (String const &version)
100 {
101 cbpv.setCanonicalVersion (version);
102 add_correct_version();
103 }
104
105 void
106 IniDBBuilderPackage::buildPackageSDesc (String const &theDesc)
107 {
108 cbpv.set_sdesc(theDesc);
109 }
110
111 void
112 IniDBBuilderPackage::buildPackageLDesc (String const &theDesc)
113 {
114 cbpv.set_ldesc(theDesc);
115 #if DEBUG
116 _feedback.warning(theDesc.cstr_oneuse());
117 #endif
118 }
119
120 void
121 IniDBBuilderPackage::buildPackageInstall (String const &path)
122 {
123 process_src (*cbpv.source(), path);
124 }
125
126 void
127 IniDBBuilderPackage::buildPackageSource (String const &path, String const &size)
128 {
129 packagedb db;
130 /* get an appropriate metadata */
131 csp = db.findSource (PackageSpecification (cbpv.Name()));
132 if (!csp)
133 {
134 /* Copy the existing meta data to a new source package */
135 csp = new packagemeta (*cp);
136 /* delete versions information */
137 csp->versions.clear();
138 csp->desired = packageversion();
139 csp->installed = packageversion();
140 csp->prev = packageversion();
141 csp->curr = packageversion();
142 csp->exp = packageversion();
143 db.sourcePackages.push_back (csp);
144 }
145 /* create a source packageversion */
146 cspv = cygpackage::createInstance (cbpv.Name());
147 cspv.setCanonicalVersion (cbpv.Canonical_version());
148 set<packageversion>::iterator i=find (csp->versions.begin(),
149 csp->versions.end(), cspv);
150 if (i == csp->versions.end())
151 {
152 csp->add_version (cspv);
153 }
154 else
155 cspv = *i;
156
157 if (!cspv.source()->Canonical())
158 cspv.source()->set_canonical (path.cstr_oneuse());
159 cspv.source()->sites.push_back(site(parse_mirror));
160
161 cbpv.setSourcePackageSpecification (PackageSpecification (cspv.Name()));
162
163 // process_src (*cspv.source(), path);
164 setSourceSize (*cspv.source(), size);
165 }
166
167 void
168 IniDBBuilderPackage::buildSourceFile (unsigned char const * md5, String const &size, String const &path)
169 {
170 }
171
172 void
173 IniDBBuilderPackage::buildPackageTrust (int newtrust)
174 {
175 trust = newtrust;
176 if (newtrust != TRUST_UNKNOWN)
177 {
178 cbpv = cygpackage::createInstance (cp->name);
179 cspv = packageversion ();
180 }
181 }
182
183 void
184 IniDBBuilderPackage::buildPackageCategory (String const &name)
185 {
186 cp->add_category (name);
187 }
188
189 void
190 IniDBBuilderPackage::buildBeginDepends ()
191 {
192 #if DEBUG
193 log (LOG_BABBLE) << "Beginning of a depends statement for " << cp->name
194 << endLog;
195 dumpAndList (currentAndList, log(LOG_BABBLE));
196 #endif
197 currentSpec = NULL;
198 currentOrList = NULL; /* set by the build AndListNode */
199 currentAndList = cbpv.depends();
200 }
201
202 void
203 IniDBBuilderPackage::buildBeginPreDepends ()
204 {
205 #if DEBUG
206 log (LOG_BABBLE) << "Beginning of a predepends statement" << endLog;
207 dumpAndList (currentAndList, log(LOG_BABBLE));
208 #endif
209 currentSpec = NULL;
210 currentOrList = NULL; /* set by the build AndListNode */
211 currentAndList = cbpv.predepends();
212 }
213
214 void
215 IniDBBuilderPackage::buildPriority (String const &priority)
216 {
217 cp->priority = priority;
218 #if DEBUG
219 log (LOG_BABBLE) << "Package " << cp->name << " is " << priority << endLog;
220 #endif
221 }
222
223 void
224 IniDBBuilderPackage::buildInstalledSize (String const &size)
225 {
226 cbpv.source()->setInstalledSize (atoi(size.cstr_oneuse()));
227 #if DEBUG
228 log (LOG_BABBLE) << "Installed size for " << cp->name << " is " << cbpv.source()->installedSize() << endLog;
229 #endif
230 }
231
232 void
233 IniDBBuilderPackage::buildMaintainer (String const &){}
234
235 /* TODO: we can multiple arch's for a given package,
236 and it may befor either source or binary, so we need to either set both
237 or track a third current package that points to whether we altering source
238 or binary at the moment
239 */
240 void
241 IniDBBuilderPackage::buildArchitecture (String const &arch)
242 {
243 cp->architecture = arch;
244 #if DEBUG
245 log (LOG_BABBLE) << "Package " << cp->name << " is for " << arch << " architectures." << endLog;
246 #endif
247 }
248
249 void
250 IniDBBuilderPackage::buildInstallSize (String const &size)
251 {
252 setSourceSize (*cbpv.source(), size);
253 }
254
255 void
256 IniDBBuilderPackage::buildInstallMD5 (unsigned char const * md5)
257 {
258 if (md5 && !cbpv.source()->md5.isSet())
259 cbpv.source()->md5.set(md5);
260 }
261
262 void
263 IniDBBuilderPackage::buildSourceMD5 (unsigned char const * md5)
264 {
265 if (md5 && !cspv.source()->md5.isSet())
266 cspv.source()->md5.set(md5);
267 }
268
269 void
270 IniDBBuilderPackage::buildBeginRecommends ()
271 {
272 #if DEBUG
273 log (LOG_BABBLE) << "Beginning of a recommends statement" << endLog;
274 dumpAndList (currentAndList, log(LOG_BABBLE));
275 #endif
276 currentSpec = NULL;
277 currentOrList = NULL; /* set by the build AndListNode */
278 currentAndList = cbpv.recommends();
279 }
280
281 void
282 IniDBBuilderPackage::buildBeginSuggests ()
283 {
284 #if DEBUG
285 log (LOG_BABBLE) << "Beginning of a suggests statement" << endLog;
286 dumpAndList (currentAndList, log(LOG_BABBLE));
287 #endif
288 currentSpec = NULL;
289 currentOrList = NULL; /* set by the build AndListNode */
290 currentAndList = cbpv.suggests();
291 }
292
293 void
294 IniDBBuilderPackage::buildBeginReplaces ()
295 {
296 #if DEBUG
297 log (LOG_BABBLE) << "Beginning of a replaces statement" << endLog;
298 dumpAndList (currentAndList, log(LOG_BABBLE));
299 #endif
300 currentSpec = NULL;
301 currentOrList = NULL; /* set by the build AndListNode */
302 currentAndList = cbpv.replaces();
303 }
304
305 void
306 IniDBBuilderPackage::buildBeginConflicts ()
307 {
308 #if DEBUG
309 log (LOG_BABBLE) << "Beginning of a conflicts statement" << endLog;
310 dumpAndList (currentAndList, log(LOG_BABBLE));
311 #endif
312 currentSpec = NULL;
313 currentOrList = NULL; /* set by the build AndListNode */
314 currentAndList = cbpv.conflicts();
315 }
316
317 void
318 IniDBBuilderPackage::buildBeginProvides ()
319 {
320 #if DEBUG
321 log (LOG_BABBLE) << "Beginning of a provides statement" << endLog;
322 dumpAndList (currentAndList, log(LOG_BABBLE));
323 #endif
324 currentSpec = NULL;
325 currentOrList = NULL; /* set by the build AndListNode */
326 currentAndList = cbpv.provides();
327 }
328
329 void
330 IniDBBuilderPackage::buildBeginBuildDepends ()
331 {
332 #if DEBUG
333 log (LOG_BABBLE) << "Beginning of a Build-Depends statement" << endLog;
334 dumpAndList (currentAndList, log(LOG_BABBLE));
335 #endif
336 currentSpec = NULL;
337 currentOrList = NULL; /* set by the build AndListNode */
338 currentAndList = cspv.depends ();
339 }
340
341
342 void
343 IniDBBuilderPackage::buildBeginBinary ()
344 {
345 #if DEBUG
346 log (LOG_BABBLE) << "Beginning of a Binary statement" << endLog;
347 dumpAndList (currentAndList, log(LOG_BABBLE));
348 #endif
349 currentSpec = NULL;
350 currentOrList = NULL; /* set by the build AndListNode */
351 currentAndList = cspv.binaries ();
352 }
353
354 void
355 IniDBBuilderPackage::buildDescription (String const &descline)
356 {
357 if (cbpv)
358 {
359 cbpv.set_ldesc(cbpv.LDesc() + descline + "\n");
360 #if DEBUG
361 log (LOG_BABBLE) << "Description for " << cp->name << ": \"" <<
362 descline << "\"." << endLog;
363 #endif
364 }
365 else
366 _feedback.warning ((String ("Attempt to set description for package")
367 + cp->name
368 + "before creation of a version.").cstr_oneuse());
369 }
370
371 void
372 IniDBBuilderPackage::buildSourceName (String const &name)
373 {
374 if (cbpv)
375 {
376 cbpv.setSourcePackageSpecification (PackageSpecification (name));
377 #if DEBUG
378 log (LOG_BABBLE) << "\"" << cbpv.sourcePackageSpecification() <<
379 "\" is the source package for " << cp->name << "." << endLog;
380 #endif
381 }
382 else
383 _feedback.warning ((String ("Attempt to set source for package")
384 + cp->name
385 + "before creation of a version.").cstr_oneuse());
386 }
387
388 void
389 IniDBBuilderPackage::buildSourceNameVersion (String const &version)
390 {
391 if (cbpv)
392 {
393 cbpv.sourcePackageSpecification().setOperator (PackageSpecification::Equals);
394 cbpv.sourcePackageSpecification().setVersion (version);
395 #if DEBUG
396 log (LOG_BABBLE) << "The source version needed for " << cp->name <<
397 " is " << version << "." << endLog;
398 #endif
399 }
400 else
401 _feedback.warning ((String ("Attempt to set source version for package")
402 + cp->name
403 + "before creation of a version.").cstr_oneuse());
404 }
405
406 void
407 IniDBBuilderPackage::buildPackageListAndNode ()
408 {
409 if (currentAndList)
410 {
411 #if DEBUG
412 log (LOG_BABBLE) << "New AND node for a package list" << endLog;
413 if (currentOrList)
414 {
415 ostream &os = log (LOG_BABBLE);
416 os << "Current OR list is :";
417 for (vector<PackageSpecification *>::const_iterator i= currentOrList->begin();
418 i != currentOrList->end(); ++i)
419 os << endl << **i;
420 os << endLog;
421 }
422 #endif
423 currentSpec = NULL;
424 currentOrList = new vector<PackageSpecification *>;
425 currentAndList->push_back (currentOrList);
426 }
427 else
428 _feedback.warning ((String ("Attempt to add And node when no AndList"
429 " present for package ")
430 + cp->name).cstr_oneuse());
431 }
432
433 void
434 IniDBBuilderPackage::buildPackageListOrNode (String const &packageName)
435 {
436 if (currentOrList)
437 {
438 currentSpec = new PackageSpecification (packageName);
439 currentOrList->push_back (currentSpec);
440 #if DEBUG
441 log (LOG_BABBLE) << "New OR node in a package list refers to \"" <<
442 *currentSpec << "\"." << endLog;
443 #endif
444 }
445 else
446 _feedback.warning ((String ("Attempt to set specification for package ")
447 + cp->name
448 + " before creation of a version.").cstr_oneuse());
449 }
450
451 void
452 IniDBBuilderPackage::buildPackageListOperator (PackageSpecification::_operators const &_operator)
453 {
454 if (currentSpec)
455 {
456 currentSpec->setOperator (_operator);
457 #if DEBUG
458 log (LOG_BABBLE) << "Current specification is " << *currentSpec << "." <<
459 endLog;
460 #endif
461 }
462 else
463 _feedback.warning ((String ("Attempt to set an operator for package ")
464 + cp->name
465 + " with no current specification.").cstr_oneuse());
466 }
467
468
469 void
470 IniDBBuilderPackage::buildPackageListOperatorVersion (String const &aVersion)
471 {
472 if (currentSpec)
473 {
474 currentSpec->setVersion (aVersion);
475 #if DEBUG
476 log (LOG_BABBLE) << "Current specification is " << *currentSpec << "." <<
477 endLog;
478 #endif
479 }
480 else
481 _feedback.warning ((String ("Attempt to set an operator version for package ")
482 + cp->name
483 + " with no current specification.").cstr_oneuse());
484 }
485
486 /* privates */
487
488 void
489 IniDBBuilderPackage::add_correct_version()
490 {
491 int merged = 0;
492 for (set<packageversion>::iterator n = cp->versions.begin();
493 !merged && n != cp->versions.end(); ++n)
494 if (*n == cbpv )
495 {
496 packageversion ver = *n;
497 /* ASSUMPTIONS:
498 categories and requires are consistent for the same version across
499 all mirrors
500 */
501 /* Copy the binary mirror across if this site claims to have an install */
502 if (cbpv.source()->sites.size() )
503 ver.source()->sites.push_back(site (cbpv.source()->sites.begin()->key));
504 /* Copy the descriptions across */
505 if (cbpv.SDesc ().size() && !n->SDesc ().size())
506 ver.set_sdesc (cbpv.SDesc ());
507 if (cbpv.LDesc ().size() && !n->LDesc ().size())
508 ver.set_ldesc (cbpv.LDesc ());
509 if (cbpv.depends()->size() && !ver.depends ()->size())
510 *ver.depends() = *cbpv.depends();
511 /* TODO: other package lists */
512 /* Prevent dangling references */
513 currentOrList = NULL;
514 currentAndList = NULL;
515 currentSpec = NULL;
516 cbpv = *n;
517 merged = 1;
518 }
519 if (!merged)
520 cp->add_version (cbpv);
521 /* trust setting */
522 switch (trust)
523 {
524 case TRUST_CURR:
525 if (cp->currtimestamp < timestamp)
526 {
527 cp->currtimestamp = timestamp;
528 cp->curr = cbpv;
529 }
530 break;
531 case TRUST_PREV:
532 if (cp->prevtimestamp < timestamp)
533 {
534 cp->prevtimestamp = timestamp;
535 cp->prev = cbpv;
536 }
537 break;
538 case TRUST_TEST:
539 if (cp->exptimestamp < timestamp)
540 {
541 cp->exptimestamp = timestamp;
542 cp->exp = cbpv;
543 }
544 break;
545 }
546 }
547
548 void
549 IniDBBuilderPackage::process_src (packagesource &src, String const &path)
550 {
551 if (!src.Canonical())
552 src.set_canonical (path.cstr_oneuse());
553 src.sites.push_back(site(parse_mirror));
554
555 if (!cbpv.Canonical_version ().size())
556 {
557 fileparse f;
558 if (parse_filename (path, f))
559 {
560 cbpv.setCanonicalVersion (f.ver);
561 add_correct_version ();
562 }
563 }
564 }
565
566 void
567 IniDBBuilderPackage::setSourceSize (packagesource &src, String const &size)
568 {
569 if (!src.size)
570 src.size = atoi(size.cstr_oneuse());
571 }
This page took 0.062465 seconds and 5 git commands to generate.