3 * Routine(s) to handle an "rpmte" transaction element.
13 #define _RPMTE_INTERNAL
26 void rpmteCleanDS(rpmte te)
28 te->this = rpmdsFree(te->this);
29 te->provides = rpmdsFree(te->provides);
30 te->requires = rpmdsFree(te->requires);
31 te->conflicts = rpmdsFree(te->conflicts);
32 te->obsoletes = rpmdsFree(te->obsoletes);
36 * Destroy transaction element data.
37 * @param p transaction element
39 static void delTE(rpmte p)
40 /*@globals fileSystem @*/
41 /*@modifies p, fileSystem @*/
46 for (r = p->relocs; (r->oldPath || r->newPath); r++) {
47 r->oldPath = _free(r->oldPath);
48 r->newPath = _free(r->newPath);
50 p->relocs = _free(p->relocs);
55 p->fi = rpmfiFree(p->fi);
59 p->fd = fdFree(p->fd, "delTE");
63 p->arch = _free(p->arch);
64 p->epoch = _free(p->epoch);
65 p->name = _free(p->name);
66 p->NEVR = _free(p->NEVR);
68 p->h = headerFree(p->h);
71 memset(p, 0, sizeof(*p)); /* XXX trash and burn */
73 /*@-nullstate@*/ /* FIX: p->{NEVR,name} annotations */
79 * Initialize transaction element data from header.
80 * @param ts transaction set
81 * @param p transaction element
83 * @param key (TR_ADDED) package retrieval key (e.g. file name)
84 * @param relocs (TR_ADDED) package file relocations
87 static void addTE(rpmts ts, rpmte p, Header h,
88 /*@dependent@*/ /*@null@*/ fnpyKey key,
89 /*@null@*/ rpmRelocation * relocs)
90 /*@globals fileSystem @*/
91 /*@modifies ts, p, h, fileSystem @*/
94 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
97 const char * arch, * os;
100 p->NEVR = hGetNEVR(h, NULL);
101 p->name = xstrdup(p->NEVR);
102 if ((p->release = strrchr(p->name, '-')) != NULL)
103 *p->release++ = '\0';
104 if ((p->version = strrchr(p->name, '-')) != NULL)
105 *p->version++ = '\0';
108 xx = hge(h, RPMTAG_ARCH, NULL, (void **)&arch, NULL);
109 p->arch = (arch != NULL ? xstrdup(arch) : NULL);
111 xx = hge(h, RPMTAG_OS, NULL, (void **)&os, NULL);
112 p->os = (os != NULL ? xstrdup(os) : NULL);
115 xx = hge(h, RPMTAG_EPOCH, NULL, (void **)&ep, NULL);
118 p->epoch = xmalloc(20);
119 sprintf(p->epoch, "%d", *ep);
124 if (relocs != NULL) {
128 for (i = 0, r = relocs; r->oldPath || r->newPath; i++, r++)
130 p->relocs = xmalloc((i + 1) * sizeof(*p->relocs));
132 for (i = 0, r = relocs; r->oldPath || r->newPath; i++, r++) {
133 p->relocs[i].oldPath = r->oldPath ? xstrdup(r->oldPath) : NULL;
134 p->relocs[i].newPath = r->newPath ? xstrdup(r->newPath) : NULL;
136 p->relocs[i].oldPath = NULL;
137 p->relocs[i].newPath = NULL;
145 p->this = rpmdsThis(h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
146 p->provides = rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem);
147 p->requires = rpmdsNew(h, RPMTAG_REQUIRENAME, scareMem);
148 p->conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, scareMem);
149 p->obsoletes = rpmdsNew(h, RPMTAG_OBSOLETENAME, scareMem);
151 savep = rpmtsSetRelocateElement(ts, p);
152 p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
153 (void) rpmtsSetRelocateElement(ts, savep);
155 rpmteColorDS(p, RPMTAG_PROVIDENAME);
156 rpmteColorDS(p, RPMTAG_REQUIRENAME);
162 rpmte rpmteFree(rpmte te)
166 memset(te, 0, sizeof(*te)); /* XXX trash and burn */
172 rpmte rpmteNew(const rpmts ts, Header h,
175 rpmRelocation * relocs,
179 rpmte te = xcalloc(1, sizeof(*te));
181 addTE(ts, te, h, key, relocs);
185 te->u.addedKey = pkgKey;
189 te->u.removed.dependsOnKey = pkgKey;
190 te->u.removed.dboffset = dboffset;
196 rpmElementType rpmteType(rpmte te)
198 return (te != NULL ? te->type : -1);
201 const char * rpmteN(rpmte te)
203 return (te != NULL ? te->name : NULL);
206 const char * rpmteE(rpmte te)
208 return (te != NULL ? te->epoch : NULL);
211 const char * rpmteV(rpmte te)
213 return (te != NULL ? te->version : NULL);
216 const char * rpmteR(rpmte te)
218 return (te != NULL ? te->release : NULL);
221 const char * rpmteA(rpmte te)
223 return (te != NULL ? te->arch : NULL);
226 const char * rpmteO(rpmte te)
228 return (te != NULL ? te->os : NULL);
231 int rpmteMultiLib(rpmte te)
233 return (te != NULL ? te->multiLib : 0);
236 int rpmteSetMultiLib(rpmte te, int nmultiLib)
240 omultiLib = te->multiLib;
241 te->multiLib = nmultiLib;
246 int rpmteDepth(rpmte te)
248 return (te != NULL ? te->depth : 0);
251 int rpmteSetDepth(rpmte te, int ndepth)
261 int rpmteNpreds(rpmte te)
263 return (te != NULL ? te->npreds : 0);
266 int rpmteSetNpreds(rpmte te, int npreds)
276 int rpmteTree(rpmte te)
278 return (te != NULL ? te->tree : 0);
281 int rpmteSetTree(rpmte te, int ntree)
291 rpmte rpmteParent(rpmte te)
293 return (te != NULL ? te->parent : NULL);
296 rpmte rpmteSetParent(rpmte te, rpmte pte)
302 /*@-assignexpose -temptrans@*/
304 /*@=assignexpose =temptrans@*/
310 int rpmteDegree(rpmte te)
312 return (te != NULL ? te->degree : 0);
315 int rpmteSetDegree(rpmte te, int ndegree)
319 odegree = te->degree;
320 te->degree = ndegree;
325 tsortInfo rpmteTSI(rpmte te)
327 /*@-compdef -retalias -retexpose -usereleased @*/
329 /*@=compdef =retalias =retexpose =usereleased @*/
332 void rpmteFreeTSI(rpmte te)
334 if (te != NULL && rpmteTSI(te) != NULL) {
337 /* Clean up tsort remnants (if any). */
338 while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
339 rpmteTSI(te)->tsi_next = tsi->tsi_next;
340 tsi->tsi_next = NULL;
343 te->tsi = _free(te->tsi);
345 /*@-nullstate@*/ /* FIX: te->tsi is NULL */
350 void rpmteNewTSI(rpmte te)
354 te->tsi = xcalloc(1, sizeof(*te->tsi));
358 alKey rpmteAddedKey(rpmte te)
360 return (te != NULL ? te->u.addedKey : RPMAL_NOMATCH);
363 alKey rpmteSetAddedKey(rpmte te, alKey npkgKey)
365 alKey opkgKey = RPMAL_NOMATCH;
367 opkgKey = te->u.addedKey;
368 te->u.addedKey = npkgKey;
374 alKey rpmteDependsOnKey(rpmte te)
376 return (te != NULL ? te->u.removed.dependsOnKey : RPMAL_NOMATCH);
379 int rpmteDBOffset(rpmte te)
381 return (te != NULL ? te->u.removed.dboffset : 0);
384 const char * rpmteNEVR(rpmte te)
386 return (te != NULL ? te->NEVR : NULL);
389 FD_t rpmteFd(rpmte te)
391 /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
392 return (te != NULL ? te->fd : NULL);
393 /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
396 fnpyKey rpmteKey(rpmte te)
398 return (te != NULL ? te->key : NULL);
401 rpmds rpmteDS(rpmte te, rpmTag tag)
403 /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
407 if (tag == RPMTAG_NAME)
410 if (tag == RPMTAG_PROVIDENAME)
413 if (tag == RPMTAG_REQUIRENAME)
416 if (tag == RPMTAG_CONFLICTNAME)
417 return te->conflicts;
419 if (tag == RPMTAG_OBSOLETENAME)
420 return te->obsoletes;
423 /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
426 rpmfi rpmteFI(rpmte te, rpmTag tag)
428 /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
432 if (tag == RPMTAG_BASENAMES)
436 /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
439 void rpmteColorDS(rpmte te, rpmTag tag)
441 rpmfi fi = rpmteFI(te, RPMTAG_BASENAMES);
442 rpmds ds = rpmteDS(te, tag);
445 const int_32 * ddict;
454 if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
460 /*@notreached@*/ break;
461 case RPMTAG_PROVIDENAME:
464 case RPMTAG_REQUIRENAME:
469 nb = Count * sizeof(*colors);
470 colors = memset(alloca(nb), 0, nb);
471 nb = Count * sizeof(*refs);
472 refs = memset(alloca(nb), -1, nb);
474 /* Calculate dependency color and reference count. */
475 fi = rpmfiInit(fi, 0);
477 while (rpmfiNext(fi) >= 0) {
478 /* XXX ignore all but lsnibble for now. */
479 val = (rpmfiFColor(fi) & 0x0f);
481 ndx = rpmfiFDepends(fi, &ddict);
485 mydt = ((ix >> 24) & 0xff);
487 /*@innercontinue@*/ continue;
495 /* Set color/refs values in dependency set. */
497 while ((i = rpmdsNext(ds)) >= 0) {
499 (void) rpmdsSetColor(ds, val);
503 (void) rpmdsSetRefs(ds, val);
506 int rpmtsiOc(rpmtsi tsi)
511 rpmtsi XrpmtsiFree(/*@only@*//*@null@*/ rpmtsi tsi,
512 const char * fn, unsigned int ln)
514 /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */
516 tsi->ts = rpmtsFree(tsi->ts);
520 fprintf(stderr, "*** tsi %p -- %s:%d\n", tsi, fn, ln);
525 rpmtsi XrpmtsiInit(rpmts ts, const char * fn, unsigned int ln)
529 tsi = xcalloc(1, sizeof(*tsi));
530 tsi->ts = rpmtsLink(ts, "rpmtsi");
531 tsi->reverse = ((rpmtsFlags(ts) & RPMTRANS_FLAG_REVERSE) ? 1 : 0);
532 tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
533 tsi->ocsave = tsi->oc;
536 fprintf(stderr, "*** tsi %p ++ %s:%d\n", tsi, fn, ln);
542 * Return next transaction element.
543 * @param tsi transaction element iterator
544 * @return transaction element, NULL on termination
546 static /*@dependent@*/ /*@null@*/
547 rpmte rpmtsiNextElement(rpmtsi tsi)
553 if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
557 if (tsi->oc >= 0) oc = tsi->oc--;
559 if (tsi->oc < rpmtsNElements(tsi->ts)) oc = tsi->oc++;
564 te = rpmtsElement(tsi->ts, oc);
569 rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
573 while ((te = rpmtsiNextElement(tsi)) != NULL) {
574 if (type == 0 || (te->type & type) != 0)