]> cygwin.com Git - cygwin-apps/setup.git/blob - IniDBBuilderPackage.cc
2007-02-17 Cesar Strauss <cstrauss@cea.inpe.br>
[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 casecompare(p1->name, 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 (const std::string& time)
50 {
51 timestamp = strtoul (time.c_str(), 0, 0);
52 }
53
54 void
55 IniDBBuilderPackage::buildVersion (const std::string& 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 (const std::string& 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, package_binary);
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 (const std::string& version)
100 {
101 cbpv.setCanonicalVersion (version);
102 add_correct_version();
103 }
104
105 void
106 IniDBBuilderPackage::buildPackageSDesc (const std::string& theDesc)
107 {
108 cbpv.set_sdesc(theDesc);
109 }
110
111 void
112 IniDBBuilderPackage::buildPackageLDesc (const std::string& theDesc)
113 {
114 cbpv.set_ldesc(theDesc);
115 #if DEBUG
116 _feedback.warning(theDesc.c_str());
117 #endif
118 }
119
120 void
121 IniDBBuilderPackage::buildPackageInstall (const std::string& path)
122 {
123 process_src (*cbpv.source(), path);
124 }
125
126 void
127 IniDBBuilderPackage::buildPackageSource (const std::string& path,
128 const std::string& size)
129 {
130 packagedb db;
131 /* get an appropriate metadata */
132 csp = db.findSource (PackageSpecification (cbpv.Name()));
133 if (!csp)
134 {
135 /* Copy the existing meta data to a new source package */
136 csp = new packagemeta (*cp);
137 /* delete versions information */
138 csp->versions.clear();
139 csp->desired = packageversion();
140 csp->installed = packageversion();
141 csp->prev = packageversion();
142 csp->curr = packageversion();
143 csp->exp = packageversion();
144 db.sourcePackages.push_back (csp);
145 }
146 /* create a source packageversion */
147 cspv = cygpackage::createInstance (cbpv.Name(), package_source);
148 cspv.setCanonicalVersion (cbpv.Canonical_version());
149 set<packageversion>::iterator i=find (csp->versions.begin(),
150 csp->versions.end(), cspv);
151 if (i == csp->versions.end())
152 {
153 csp->add_version (cspv);
154 }
155 else
156 cspv = *i;
157
158 if (!cspv.source()->Canonical())
159 cspv.source()->set_canonical (path.c_str());
160 cspv.source()->sites.push_back(site(parse_mirror));
161
162 /* creates the relationship between binary and source packageversions */
163 cbpv.setSourcePackageSpecification (PackageSpecification (cspv.Name()));
164 PackageSpecification &spec = cbpv.sourcePackageSpecification();
165 spec.setOperator (PackageSpecification::Equals);
166 spec.setVersion (cbpv.Canonical_version());
167
168 // process_src (*cspv.source(), path);
169 setSourceSize (*cspv.source(), size);
170 }
171
172 void
173 IniDBBuilderPackage::buildSourceFile (unsigned char const * md5,
174 const std::string& size,
175 const std::string& path)
176 {
177 }
178
179 void
180 IniDBBuilderPackage::buildPackageTrust (int newtrust)
181 {
182 trust = newtrust;
183 if (newtrust != TRUST_UNKNOWN)
184 {
185 cbpv = cygpackage::createInstance (cp->name, package_binary);
186 cspv = packageversion ();
187 }
188 }
189
190 void
191 IniDBBuilderPackage::buildPackageCategory (const std::string& name)
192 {
193 cp->add_category (name);
194 }
195
196 void
197 IniDBBuilderPackage::buildBeginDepends ()
198 {
199 #if DEBUG
200 log (LOG_BABBLE) << "Beginning of a depends statement for " << cp->name
201 << endLog;
202 dumpAndList (currentAndList, log(LOG_BABBLE));
203 #endif
204 currentSpec = NULL;
205 currentOrList = NULL; /* set by the build AndListNode */
206 currentAndList = cbpv.depends();
207 }
208
209 void
210 IniDBBuilderPackage::buildBeginPreDepends ()
211 {
212 #if DEBUG
213 log (LOG_BABBLE) << "Beginning of a predepends statement" << endLog;
214 dumpAndList (currentAndList, log(LOG_BABBLE));
215 #endif
216 currentSpec = NULL;
217 currentOrList = NULL; /* set by the build AndListNode */
218 currentAndList = cbpv.predepends();
219 }
220
221 void
222 IniDBBuilderPackage::buildPriority (const std::string& priority)
223 {
224 cp->priority = priority;
225 #if DEBUG
226 log (LOG_BABBLE) << "Package " << cp->name << " is " << priority << endLog;
227 #endif
228 }
229
230 void
231 IniDBBuilderPackage::buildInstalledSize (const std::string& size)
232 {
233 cbpv.source()->setInstalledSize (atoi(size.c_str()));
234 #if DEBUG
235 log (LOG_BABBLE) << "Installed size for " << cp->name << " is " << cbpv.source()->installedSize() << endLog;
236 #endif
237 }
238
239 void
240 IniDBBuilderPackage::buildMaintainer (const std::string& ){}
241
242 /* TODO: we can multiple arch's for a given package,
243 and it may befor either source or binary, so we need to either set both
244 or track a third current package that points to whether we altering source
245 or binary at the moment
246 */
247 void
248 IniDBBuilderPackage::buildArchitecture (const std::string& arch)
249 {
250 cp->architecture = arch;
251 #if DEBUG
252 log (LOG_BABBLE) << "Package " << cp->name << " is for " << arch << " architectures." << endLog;
253 #endif
254 }
255
256 void
257 IniDBBuilderPackage::buildInstallSize (const std::string& size)
258 {
259 setSourceSize (*cbpv.source(), size);
260 }
261
262 void
263 IniDBBuilderPackage::buildInstallMD5 (unsigned char const * md5)
264 {
265 if (md5 && !cbpv.source()->md5.isSet())
266 cbpv.source()->md5.set(md5);
267 }
268
269 void
270 IniDBBuilderPackage::buildSourceMD5 (unsigned char const * md5)
271 {
272 if (md5 && !cspv.source()->md5.isSet())
273 cspv.source()->md5.set(md5);
274 }
275
276 void
277 IniDBBuilderPackage::buildBeginRecommends ()
278 {
279 #if DEBUG
280 log (LOG_BABBLE) << "Beginning of a recommends statement" << endLog;
281 dumpAndList (currentAndList, log(LOG_BABBLE));
282 #endif
283 currentSpec = NULL;
284 currentOrList = NULL; /* set by the build AndListNode */
285 currentAndList = cbpv.recommends();
286 }
287
288 void
289 IniDBBuilderPackage::buildBeginSuggests ()
290 {
291 #if DEBUG
292 log (LOG_BABBLE) << "Beginning of a suggests statement" << endLog;
293 dumpAndList (currentAndList, log(LOG_BABBLE));
294 #endif
295 currentSpec = NULL;
296 currentOrList = NULL; /* set by the build AndListNode */
297 currentAndList = cbpv.suggests();
298 }
299
300 void
301 IniDBBuilderPackage::buildBeginReplaces ()
302 {
303 #if DEBUG
304 log (LOG_BABBLE) << "Beginning of a replaces statement" << endLog;
305 dumpAndList (currentAndList, log(LOG_BABBLE));
306 #endif
307 currentSpec = NULL;
308 currentOrList = NULL; /* set by the build AndListNode */
309 currentAndList = cbpv.replaces();
310 }
311
312 void
313 IniDBBuilderPackage::buildBeginConflicts ()
314 {
315 #if DEBUG
316 log (LOG_BABBLE) << "Beginning of a conflicts statement" << endLog;
317 dumpAndList (currentAndList, log(LOG_BABBLE));
318 #endif
319 currentSpec = NULL;
320 currentOrList = NULL; /* set by the build AndListNode */
321 currentAndList = cbpv.conflicts();
322 }
323
324 void
325 IniDBBuilderPackage::buildBeginProvides ()
326 {
327 #if DEBUG
328 log (LOG_BABBLE) << "Beginning of a provides statement" << endLog;
329 dumpAndList (currentAndList, log(LOG_BABBLE));
330 #endif
331 currentSpec = NULL;
332 currentOrList = NULL; /* set by the build AndListNode */
333 currentAndList = cbpv.provides();
334 }
335
336 void
337 IniDBBuilderPackage::buildBeginBuildDepends ()
338 {
339 #if DEBUG
340 log (LOG_BABBLE) << "Beginning of a Build-Depends statement" << endLog;
341 dumpAndList (currentAndList, log(LOG_BABBLE));
342 #endif
343 currentSpec = NULL;
344 currentOrList = NULL; /* set by the build AndListNode */
345 currentAndList = cspv.depends ();
346 }
347
348
349 void
350 IniDBBuilderPackage::buildBeginBinary ()
351 {
352 #if DEBUG
353 log (LOG_BABBLE) << "Beginning of a Binary statement" << endLog;
354 dumpAndList (currentAndList, log(LOG_BABBLE));
355 #endif
356 currentSpec = NULL;
357 currentOrList = NULL; /* set by the build AndListNode */
358 currentAndList = cspv.binaries ();
359 }
360
361 void
362 IniDBBuilderPackage::buildDescription (const std::string& descline)
363 {
364 if (cbpv)
365 {
366 cbpv.set_ldesc(cbpv.LDesc() + descline + "\n");
367 #if DEBUG
368 log (LOG_BABBLE) << "Description for " << cp->name << ": \"" <<
369 descline << "\"." << endLog;
370 #endif
371 }
372 else
373 _feedback.warning ((std::string ("Attempt to set description for package")
374 + std::string(cp->name)
375 + "before creation of a version.").c_str());
376 }
377
378 void
379 IniDBBuilderPackage::buildSourceName (const std::string& name)
380 {
381 if (cbpv)
382 {
383 cbpv.setSourcePackageSpecification (PackageSpecification (name));
384 #if DEBUG
385 log (LOG_BABBLE) << "\"" << cbpv.sourcePackageSpecification() <<
386 "\" is the source package for " << cp->name << "." << endLog;
387 #endif
388 }
389 else
390 _feedback.warning ((std::string ("Attempt to set source for package")
391 + std::string(cp->name)
392 + "before creation of a version.").c_str());
393 }
394
395 void
396 IniDBBuilderPackage::buildSourceNameVersion (const std::string& version)
397 {
398 if (cbpv)
399 {
400 cbpv.sourcePackageSpecification().setOperator (PackageSpecification::Equals);
401 cbpv.sourcePackageSpecification().setVersion (version);
402 #if DEBUG
403 log (LOG_BABBLE) << "The source version needed for " << cp->name <<
404 " is " << version << "." << endLog;
405 #endif
406 }
407 else
408 _feedback.warning ((std::string ("Attempt to set source version for package")
409 + std::string(cp->name)
410 + "before creation of a version.").c_str());
411 }
412
413 void
414 IniDBBuilderPackage::buildPackageListAndNode ()
415 {
416 if (currentAndList)
417 {
418 #if DEBUG
419 log (LOG_BABBLE) << "New AND node for a package list" << endLog;
420 if (currentOrList)
421 {
422 ostream &os = log (LOG_BABBLE);
423 os << "Current OR list is :";
424 for (vector<PackageSpecification *>::const_iterator i= currentOrList->begin();
425 i != currentOrList->end(); ++i)
426 os << endl << **i;
427 os << endLog;
428 }
429 #endif
430 currentSpec = NULL;
431 currentOrList = new vector<PackageSpecification *>;
432 currentAndList->push_back (currentOrList);
433 }
434 else
435 _feedback.warning ((std::string ("Attempt to add And node when no AndList"
436 " present for package ")
437 + std::string(cp->name)).c_str());
438 }
439
440 void
441 IniDBBuilderPackage::buildPackageListOrNode (const std::string& packageName)
442 {
443 if (currentOrList)
444 {
445 currentSpec = new PackageSpecification (packageName);
446 currentOrList->push_back (currentSpec);
447 #if DEBUG
448 log (LOG_BABBLE) << "New OR node in a package list refers to \"" <<
449 *currentSpec << "\"." << endLog;
450 #endif
451 }
452 else
453 _feedback.warning ((std::string ("Attempt to set specification for package ")
454 + std::string(cp->name)
455 + " before creation of a version.").c_str());
456 }
457
458 void
459 IniDBBuilderPackage::buildPackageListOperator (PackageSpecification::_operators const &_operator)
460 {
461 if (currentSpec)
462 {
463 currentSpec->setOperator (_operator);
464 #if DEBUG
465 log (LOG_BABBLE) << "Current specification is " << *currentSpec << "." <<
466 endLog;
467 #endif
468 }
469 else
470 _feedback.warning ((std::string ("Attempt to set an operator for package ")
471 + std::string(cp->name)
472 + " with no current specification.").c_str());
473 }
474
475
476 void
477 IniDBBuilderPackage::buildPackageListOperatorVersion (const std::string& aVersion)
478 {
479 if (currentSpec)
480 {
481 currentSpec->setVersion (aVersion);
482 #if DEBUG
483 log (LOG_BABBLE) << "Current specification is " << *currentSpec << "." <<
484 endLog;
485 #endif
486 }
487 else
488 _feedback.warning ((std::string ("Attempt to set an operator version for package ")
489 + std::string(cp->name)
490 + " with no current specification.").c_str());
491 }
492
493 /* privates */
494
495 void
496 IniDBBuilderPackage::add_correct_version()
497 {
498 int merged = 0;
499 for (set<packageversion>::iterator n = cp->versions.begin();
500 !merged && n != cp->versions.end(); ++n)
501 if (*n == cbpv )
502 {
503 packageversion ver = *n;
504 /* ASSUMPTIONS:
505 categories and requires are consistent for the same version across
506 all mirrors
507 */
508 /* Copy the binary mirror across if this site claims to have an install */
509 if (cbpv.source()->sites.size() )
510 ver.source()->sites.push_back(site (cbpv.source()->sites.begin()->key));
511 /* Copy the descriptions across */
512 if (cbpv.SDesc ().size() && !n->SDesc ().size())
513 ver.set_sdesc (cbpv.SDesc ());
514 if (cbpv.LDesc ().size() && !n->LDesc ().size())
515 ver.set_ldesc (cbpv.LDesc ());
516 if (cbpv.depends()->size() && !ver.depends ()->size())
517 *ver.depends() = *cbpv.depends();
518 /* TODO: other package lists */
519 /* Prevent dangling references */
520 currentOrList = NULL;
521 currentAndList = NULL;
522 currentSpec = NULL;
523 cbpv = *n;
524 merged = 1;
525 }
526 if (!merged)
527 cp->add_version (cbpv);
528 /* trust setting */
529 switch (trust)
530 {
531 case TRUST_CURR:
532 if (cp->currtimestamp < timestamp)
533 {
534 cp->currtimestamp = timestamp;
535 cp->curr = cbpv;
536 }
537 break;
538 case TRUST_PREV:
539 if (cp->prevtimestamp < timestamp)
540 {
541 cp->prevtimestamp = timestamp;
542 cp->prev = cbpv;
543 }
544 break;
545 case TRUST_TEST:
546 if (cp->exptimestamp < timestamp)
547 {
548 cp->exptimestamp = timestamp;
549 cp->exp = cbpv;
550 }
551 break;
552 }
553 }
554
555 void
556 IniDBBuilderPackage::process_src (packagesource &src, const std::string& path)
557 {
558 if (!src.Canonical())
559 src.set_canonical (path.c_str());
560 src.sites.push_back(site(parse_mirror));
561
562 if (!cbpv.Canonical_version ().size())
563 {
564 fileparse f;
565 if (parse_filename (path, f))
566 {
567 cbpv.setCanonicalVersion (f.ver);
568 add_correct_version ();
569 }
570 }
571 }
572
573 void
574 IniDBBuilderPackage::setSourceSize (packagesource &src, const std::string& size)
575 {
576 if (!src.size)
577 src.size = atoi(size.c_str());
578 }
This page took 0.063193 seconds and 5 git commands to generate.