rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

rpmte.c
Go to the documentation of this file.
1
5 #include "system.h"
6
7 #include <rpmio.h>
8 #include <rpmiotypes.h> /* XXX fnpyKey */
9
10 #include <rpmtypes.h>
11 #include <rpmtag.h>
12
13 #include "rpmds.h"
14 #include "rpmfi.h"
15
16 #define _RPMTE_INTERNAL
17 #include "rpmte.h"
18 #include "rpmts.h"
19
20 #include "debug.h"
21
22 /*@unchecked@*/
23 int _rpmte_debug = 0;
24
25 /*@access alKey @*/
26 /*@access rpmts @*/ /* XXX cast */
27 /*@access rpmtsi @*/
28
29 void rpmteCleanDS(rpmte te)
30 {
31 te->PRCO = rpmdsFreePRCO(te->PRCO);
32 }
33
38 static void delTE(rpmte p)
39 /*@globals fileSystem @*/
40 /*@modifies p, fileSystem @*/
41 {
42 p->relocs = rpmfiFreeRelocations(p->relocs);
43
44 rpmteCleanDS(p);
45
46 p->fi = rpmfiFree(p->fi);
47
48 /*@-refcounttrans@*/ /* FIX: XfdFree annotation */
49 if (p->fd != NULL)
50 p->fd = fdFree(p->fd, "delTE");
51 /*@=refcounttrans@*/
52
53 p->os = _free(p->os);
54 p->arch = _free(p->arch);
55 p->epoch = _free(p->epoch);
56 p->name = _free(p->name);
57 p->version = _free(p->version);
58 p->release = _free(p->release);
59 #ifdef RPM_VENDOR_MANDRIVA
60 p->distepoch = _free(p->distepoch);
61 #endif
62 p->NEVR = _free(p->NEVR);
63 p->NEVRA = _free(p->NEVRA);
64 p->pkgid = _free(p->pkgid);
65 p->hdrid = _free(p->hdrid);
66 p->sourcerpm = _free(p->sourcerpm);
67
68 p->replaced = _free(p->replaced);
69
70 p->flink.NEVRA = argvFree(p->flink.NEVRA);
71 p->flink.Pkgid = argvFree(p->flink.Pkgid);
72 p->flink.Hdrid = argvFree(p->flink.Hdrid);
73 p->blink.NEVRA = argvFree(p->blink.NEVRA);
74 p->blink.Pkgid = argvFree(p->blink.Pkgid);
75 p->blink.Hdrid = argvFree(p->blink.Hdrid);
76
77 (void)headerFree(p->h);
78 p->h = NULL;
79
80 /*@-nullstate@*/ /* FIX: p->{NEVR,name} annotations */
81 return;
82 /*@=nullstate@*/
83 }
84
93 static void addTE(rpmts ts, rpmte p, Header h,
94 /*@dependent@*/ /*@null@*/ fnpyKey key,
95 /*@null@*/ rpmRelocation relocs)
96 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
97 /*@modifies ts, p, h,
98 rpmGlobalMacroContext, fileSystem, internalState @*/
99 {
100 int scareMem = 0;
101 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
102 int xx;
103
104 he->tag = RPMTAG_NVRA;
105 xx = headerGet(h, he, 0);
106 assert(he->p.str != NULL);
107 p->NEVR = (xx ? he->p.str : xstrdup("?N-?V-?R.?A"));
108
109 he->tag = RPMTAG_NAME;
110 xx = headerGet(h, he, 0);
111 p->name = (xx ? he->p.str : xstrdup("?RPMTAG_NAME?"));
112 he->tag = RPMTAG_VERSION;
113 xx = headerGet(h, he, 0);
114 p->version = (char *)(xx ? he->p.str : xstrdup("?RPMTAG_VERSION?"));
115 he->tag = RPMTAG_RELEASE;
116 xx = headerGet(h, he, 0);
117 p->release = (char *)(xx ? he->p.str : xstrdup("?RPMTAG_RELEASE?"));
118
119 p->db_instance = 0;
120
121 he->tag = RPMTAG_PKGID;
122 xx = headerGet(h, he, 0);
123 if (he->p.ui8p != NULL) {
124 static const char hex[] = "0123456789abcdef";
125 char * t;
126 rpmuint32_t i;
127
128 p->pkgid = t = xmalloc((2*he->c) + 1);
129 for (i = 0 ; i < he->c; i++) {
130 *t++ = hex[ (unsigned)((he->p.ui8p[i] >> 4) & 0x0f) ];
131 *t++ = hex[ (unsigned)((he->p.ui8p[i] ) & 0x0f) ];
132 }
133 *t = '\0';
134 he->p.ptr = _free(he->p.ptr);
135 } else
136 p->pkgid = NULL;
137
138 he->tag = RPMTAG_HDRID;
139 xx = headerGet(h, he, 0);
140 p->hdrid = (xx ? he->p.str : xstrdup("?RPMTAG_HDRID?"));
141
142 he->tag = RPMTAG_SOURCERPM;
143 xx = headerGet(h, he, 0);
144 p->sourcerpm = (xx ? he->p.str : NULL);
145
146 he->tag = RPMTAG_ARCH;
147 xx = headerGet(h, he, 0);
148 p->arch = (xx ? he->p.str : xstrdup("?RPMTAG_ARCH?"));
149
150 he->tag = RPMTAG_OS;
151 xx = headerGet(h, he, 0);
152 p->os = (xx ? he->p.str : xstrdup("?RPMTAG_OS?"));
153
154 p->isSource =
155 (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
156 headerIsEntry(h, RPMTAG_ARCH) != 0);
157
158 p->NEVRA = xstrdup(p->NEVR);
159
160 he->tag = RPMTAG_EPOCH;
161 xx = headerGet(h, he, 0);
162 if (he->p.ui32p != NULL) {
163 p->epoch = xmalloc(20);
164 sprintf(p->epoch, "%u", he->p.ui32p[0]);
165 he->p.ptr = _free(he->p.ptr);
166 } else
167 p->epoch = NULL;
168
169 #ifdef RPM_VENDOR_MANDRIVA
170 he->tag = RPMTAG_DISTEPOCH;
171 xx = headerGet(h, he, 0);
172 if (he->p.str != NULL) {
173 p->distepoch = (char*)(xx ? he->p.str : xstrdup("?RPMTAG_DISTEPOCH?"));
174 } else
175 p->distepoch = NULL;
176 #endif
177
178 p->installed = 0;
179
180 p->relocs = rpmfiDupeRelocations(relocs, &p->nrelocs);
181 p->autorelocatex = -1;
182
183 p->key = key;
184 p->fd = NULL;
185
186 p->replaced = NULL;
187
188 p->pkgFileSize = 0;
189 memset(p->originTid, 0, sizeof(p->originTid));
190 memset(p->originTime, 0, sizeof(p->originTime));
191
192 p->PRCO = rpmdsNewPRCO(h);
193
194 { rpmte savep = rpmtsSetRelocateElement(ts, p);
195 p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
196 (void) rpmtsSetRelocateElement(ts, savep);
197 }
198
199 rpmteColorDS(p, RPMTAG_PROVIDENAME);
200 rpmteColorDS(p, RPMTAG_REQUIRENAME);
201 /*@-compdef@*/
202 return;
203 /*@=compdef@*/
204 }
205
206 static void rpmteFini(void * _te)
207 /*@modifies _te @*/
208 {
209 rpmte te = _te;
210
211 delTE(te);
212 }
213
214 /*@unchecked@*/ /*@only@*/ /*@null@*/
215 rpmioPool _rpmtePool;
216
217 static rpmte rpmteGetPool(/*@null@*/ rpmioPool pool)
218 /*@globals _rpmtePool, fileSystem, internalState @*/
219 /*@modifies pool, _rpmtePool, fileSystem, internalState @*/
220 {
221 rpmte te;
222
223 if (_rpmtePool == NULL) {
224 _rpmtePool = rpmioNewPool("te", sizeof(*te), -1, _rpmte_debug,
225 NULL, NULL, rpmteFini);
226 pool = _rpmtePool;
227 }
228 return (rpmte) rpmioGetPool(pool, sizeof(*te));
229 }
230
231 rpmte rpmteNew(const rpmts ts, Header h,
232 rpmElementType type,
233 fnpyKey key,
234 rpmRelocation relocs,
235 int dboffset,
236 alKey pkgKey)
237 {
238 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
239 rpmte p = rpmteGetPool(_rpmtePool);
240 int xx;
241
242 p->type = type;
243
244 addTE(ts, p, h, key, relocs);
245 switch (type) {
246 case TR_ADDED:
247 p->u.addedKey = pkgKey;
248 /* XXX 256 is only an estimate of signature header. */
249 p->pkgFileSize = 96 + 256;
250 he->tag = RPMTAG_SIGSIZE;
251 xx = headerGet(h, he, 0);
252 if (xx && he->p.ui32p)
253 p->pkgFileSize += *he->p.ui32p;
254 he->p.ptr = _free(he->p.ptr);
255 break;
256 case TR_REMOVED:
257 p->u.addedKey = pkgKey;
258 p->u.removed.dboffset = dboffset;
259 break;
260 }
261 return p;
262 }
263
264 /* Get the DB Instance value */
265 unsigned int rpmteDBInstance(rpmte te)
266 {
267 return (te != NULL ? te->db_instance : 0);
268 }
269
270 /* Set the DB Instance value */
271 void rpmteSetDBInstance(rpmte te, unsigned int instance)
272 {
273 if (te != NULL)
274 te->db_instance = instance;
275 }
276
277 Header rpmteHeader(rpmte te)
278 {
279 /*@-castexpose -retalias -retexpose @*/
280 return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
281 /*@=castexpose =retalias =retexpose @*/
282 }
283
284 Header rpmteSetHeader(rpmte te, Header h)
285 {
286 if (te != NULL) {
287 (void)headerFree(te->h);
288 te->h = NULL;
289 /*@-assignexpose -castexpose @*/
290 if (h != NULL)
291 te->h = headerLink(h);
292 /*@=assignexpose =castexpose @*/
293 }
294 return NULL;
295 }
296
297 rpmElementType rpmteType(rpmte te)
298 {
299 return (te != NULL ? te->type : (rpmElementType)-1);
300 }
301
302 const char * rpmteN(rpmte te)
303 {
304 return (te != NULL ? te->name : NULL);
305 }
306
307 const char * rpmteE(rpmte te)
308 {
309 return (te != NULL ? te->epoch : NULL);
310 }
311
312 const char * rpmteV(rpmte te)
313 {
314 return (te != NULL ? te->version : NULL);
315 }
316
317 const char * rpmteR(rpmte te)
318 {
319 return (te != NULL ? te->release : NULL);
320 }
321
322 #ifdef RPM_VENDOR_MANDRIVA
323 const char * rpmteD(rpmte te)
324 {
325 return (te != NULL ? te->distepoch : NULL);
326 }
327 #endif
328
329 const char * rpmteA(rpmte te)
330 {
331 return (te != NULL ? te->arch : NULL);
332 }
333
334 const char * rpmteO(rpmte te)
335 {
336 return (te != NULL ? te->os : NULL);
337 }
338
339 int rpmteIsSource(rpmte te)
340 {
341 return (te != NULL ? te->isSource : 0);
342 }
343
344 rpmuint32_t rpmteColor(rpmte te)
345 {
346 return (te != NULL ? te->color : 0);
347 }
348
349 rpmuint32_t rpmteSetColor(rpmte te, rpmuint32_t color)
350 {
351 int ocolor = 0;
352 if (te != NULL) {
353 ocolor = te->color;
354 te->color = color;
355 }
356 return ocolor;
357 }
358
359 rpmuint32_t rpmtePkgFileSize(rpmte te)
360 {
361 return (te != NULL ? te->pkgFileSize : 0);
362 }
363
364 rpmuint32_t * rpmteOriginTid(rpmte te)
365 {
366 return te->originTid;
367 }
368
369 rpmuint32_t * rpmteOriginTime(rpmte te)
370 {
371 return te->originTime;
372 }
373
374 int rpmteDepth(rpmte te)
375 {
376 return (te != NULL ? te->depth : 0);
377 }
378
379 int rpmteSetDepth(rpmte te, int ndepth)
380 {
381 int odepth = 0;
382 if (te != NULL) {
383 odepth = te->depth;
384 te->depth = ndepth;
385 }
386 return odepth;
387 }
388
389 int rpmteBreadth(rpmte te)
390 {
391 return (te != NULL ? te->depth : 0);
392 }
393
394 int rpmteSetBreadth(rpmte te, int nbreadth)
395 {
396 int obreadth = 0;
397 if (te != NULL) {
398 obreadth = te->breadth;
399 te->breadth = nbreadth;
400 }
401 return obreadth;
402 }
403
404 int rpmteNpreds(rpmte te)
405 {
406 return (te != NULL ? te->npreds : 0);
407 }
408
409 int rpmteSetNpreds(rpmte te, int npreds)
410 {
411 int opreds = 0;
412 if (te != NULL) {
413 opreds = te->npreds;
414 te->npreds = npreds;
415 }
416 return opreds;
417 }
418
419 int rpmteTree(rpmte te)
420 {
421 return (te != NULL ? te->tree : 0);
422 }
423
424 int rpmteSetTree(rpmte te, int ntree)
425 {
426 int otree = 0;
427 if (te != NULL) {
428 otree = te->tree;
429 te->tree = ntree;
430 }
431 return otree;
432 }
433
434 rpmte rpmteParent(rpmte te)
435 {
436 return (te != NULL ? te->parent : NULL);
437 }
438
439 rpmte rpmteSetParent(rpmte te, rpmte pte)
440 {
441 rpmte opte = NULL;
442 if (te != NULL) {
443 opte = te->parent;
444 /*@-assignexpose -temptrans@*/
445 te->parent = pte;
446 /*@=assignexpose =temptrans@*/
447 }
448 return opte;
449 }
450
451 int rpmteDegree(rpmte te)
452 {
453 return (te != NULL ? te->degree : 0);
454 }
455
456 int rpmteSetDegree(rpmte te, int ndegree)
457 {
458 int odegree = 0;
459 if (te != NULL) {
460 odegree = te->degree;
461 te->degree = ndegree;
462 }
463 return odegree;
464 }
465
466 tsortInfo rpmteTSI(rpmte te)
467 {
468 /*@-compdef -retalias -retexpose -usereleased @*/
469 return te->tsi;
470 /*@=compdef =retalias =retexpose =usereleased @*/
471 }
472
473 void rpmteFreeTSI(rpmte te)
474 {
475 if (te != NULL && rpmteTSI(te) != NULL) {
476 tsortInfo tsi;
477
478 /* Clean up tsort remnants (if any). */
479 while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
480 rpmteTSI(te)->tsi_next = tsi->tsi_next;
481 tsi->tsi_next = NULL;
482 tsi = _free(tsi);
483 }
484 te->tsi = _free(te->tsi);
485 }
486 /*@-nullstate@*/ /* FIX: te->tsi is NULL */
487 return;
488 /*@=nullstate@*/
489 }
490
491 void rpmteNewTSI(rpmte te)
492 {
493 if (te != NULL) {
494 rpmteFreeTSI(te);
495 te->tsi = xcalloc(1, sizeof(*te->tsi));
496 }
497 }
498
499 alKey rpmteAddedKey(rpmte te)
500 {
501 return (te != NULL ? te->u.addedKey : RPMAL_NOMATCH);
502 }
503
504 alKey rpmteSetAddedKey(rpmte te, alKey npkgKey)
505 {
506 alKey opkgKey = RPMAL_NOMATCH;
507 if (te != NULL) {
508 opkgKey = te->u.addedKey;
509 te->u.addedKey = npkgKey;
510 }
511 return opkgKey;
512 }
513
514
515 int rpmteDBOffset(rpmte te)
516 {
517 return (te != NULL ? te->u.removed.dboffset : 0);
518 }
519
520 const char * rpmteNEVR(rpmte te)
521 {
522 return (te != NULL ? te->NEVR : NULL);
523 }
524
525 const char * rpmteNEVRA(rpmte te)
526 {
527 return (te != NULL ? te->NEVRA : NULL);
528 }
529
530 const char * rpmtePkgid(rpmte te)
531 {
532 return (te != NULL ? te->pkgid : NULL);
533 }
534
535 const char * rpmteHdrid(rpmte te)
536 {
537 return (te != NULL ? te->hdrid : NULL);
538 }
539
540 const char * rpmteSourcerpm(rpmte te)
541 {
542 return (te != NULL ? te->sourcerpm : NULL);
543 }
544
545 FD_t rpmteFd(rpmte te)
546 {
547 /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
548 return (te != NULL ? te->fd : NULL);
549 /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
550 }
551
552 fnpyKey rpmteKey(rpmte te)
553 {
554 return (te != NULL ? te->key : NULL);
555 }
556
557 rpmds rpmteDS(rpmte te, rpmTag tag)
558 {
559 return (te != NULL ? rpmdsFromPRCO(te->PRCO, tag) : NULL);
560 }
561
562 rpmfi rpmteFI(rpmte te, rpmTag tag)
563 {
564 /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
565 if (te == NULL)
566 return NULL;
567
568 if (tag == RPMTAG_BASENAMES)
569 return te->fi;
570 else
571 return NULL;
572 /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
573 }
574
575 void rpmteColorDS(rpmte te, rpmTag tag)
576 {
577 rpmfi fi = rpmteFI(te, RPMTAG_BASENAMES);
578 rpmds ds = rpmteDS(te, tag);
579 char deptype = 'R';
580 char mydt;
581 const rpmuint32_t * ddict;
582 rpmuint32_t * colors;
583 rpmuint32_t * refs;
584 rpmuint32_t val;
585 int Count;
586 size_t nb;
587 unsigned ix;
588 int ndx, i;
589
590 if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
591 return;
592
593 switch (tag) {
594 default:
595 return;
596 /*@notreached@*/ break;
597 case RPMTAG_PROVIDENAME:
598 deptype = 'P';
599 break;
600 case RPMTAG_REQUIRENAME:
601 deptype = 'R';
602 break;
603 }
604
605 nb = Count * sizeof(*colors);
606 colors = memset(alloca(nb), 0, nb);
607 nb = Count * sizeof(*refs);
608 refs = memset(alloca(nb), -1, nb);
609
610 /* Calculate dependency color and reference count. */
611 fi = rpmfiInit(fi, 0);
612 if (fi != NULL)
613 while (rpmfiNext(fi) >= 0) {
614 val = rpmfiFColor(fi);
615 ddict = NULL;
616 ndx = rpmfiFDepends(fi, &ddict);
617 if (ddict != NULL)
618 while (ndx-- > 0) {
619 ix = *ddict++;
620 mydt = (char)((ix >> 24) & 0xff);
621 if (mydt != deptype)
622 /*@innercontinue@*/ continue;
623 ix &= 0x00ffffff;
624 assert ((int)ix < Count);
625 colors[ix] |= val;
626 refs[ix]++;
627 }
628 }
629
630 /* Set color/refs values in dependency set. */
631 ds = rpmdsInit(ds);
632 while ((i = rpmdsNext(ds)) >= 0) {
633 val = colors[i];
634 te->color |= val;
635 (void) rpmdsSetColor(ds, val);
636 val = refs[i];
637 (void) rpmdsSetRefs(ds, val);
638 }
639 }
640
641 /*@unchecked@*/
642 static int __mydebug = 0;
643
644 int rpmteChain(rpmte p, rpmte q, Header oh, const char * msg)
645 {
646 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
647 const char * blinkNEVRA = NULL;
648 const char * blinkPkgid = NULL;
649 const char * blinkHdrid = NULL;
650 int xx;
651
652 if (msg == NULL)
653 msg = "";
654 he->tag = RPMTAG_NVRA;
655 xx = headerGet(oh, he, 0);
656 assert(he->p.str != NULL);
657 blinkNEVRA = he->p.str;
658
659 /*
660 * Convert binary pkgid to a string.
661 * XXX Yum's borken conception of a "header" doesn't have signature
662 * tags appended.
663 */
664 he->tag = RPMTAG_PKGID;
665 xx = headerGet(oh, he, 0);
666 if (xx && he->p.ui8p != NULL) {
667 static const char hex[] = "0123456789abcdef";
668 char * t;
669 rpmuint32_t i;
670
671 blinkPkgid = t = xmalloc((2*he->c) + 1);
672 for (i = 0 ; i < he->c; i++) {
673 *t++ = hex[ ((he->p.ui8p[i] >> 4) & 0x0f) ];
674 *t++ = hex[ ((he->p.ui8p[i] ) & 0x0f) ];
675 }
676 *t = '\0';
677 he->p.ptr = _free(he->p.ptr);
678 } else
679 blinkPkgid = NULL;
680
681 he->tag = RPMTAG_HDRID;
682 xx = headerGet(oh, he, 0);
683 blinkHdrid = he->p.str;
684
685 /*@-modfilesys@*/
686 if (__mydebug)
687 fprintf(stderr, "%s argvAdd(&q->flink.NEVRA, \"%s\")\n", msg, p->NEVRA);
688 xx = argvAdd(&q->flink.NEVRA, p->NEVRA);
689 if (__mydebug)
690 fprintf(stderr, "%s argvAdd(&p->blink.NEVRA, \"%s\")\n", msg, blinkNEVRA);
691 xx = argvAdd(&p->blink.NEVRA, blinkNEVRA);
692 if (__mydebug)
693 fprintf(stderr, "%s argvAdd(&q->flink.Pkgid, \"%s\")\n", msg, p->pkgid);
694 if (p->pkgid != NULL)
695 xx = argvAdd(&q->flink.Pkgid, p->pkgid);
696 if (__mydebug)
697 fprintf(stderr, "%s argvAdd(&p->blink.Pkgid, \"%s\")\n", msg, blinkPkgid);
698 if (blinkPkgid != NULL)
699 xx = argvAdd(&p->blink.Pkgid, blinkPkgid);
700 if (__mydebug)
701 fprintf(stderr, "%s argvAdd(&q->flink.Hdrid, \"%s\")\n", msg, p->hdrid);
702 if (p->hdrid != NULL)
703 xx = argvAdd(&q->flink.Hdrid, p->hdrid);
704 if (__mydebug)
705 fprintf(stderr, "%s argvAdd(&p->blink.Hdrid, \"%s\")\n", msg, blinkHdrid);
706 if (blinkHdrid != NULL)
707 xx = argvAdd(&p->blink.Hdrid, blinkHdrid);
708 /*@=modfilesys@*/
709
710 blinkNEVRA = _free(blinkNEVRA);
711 blinkPkgid = _free(blinkPkgid);
712 blinkHdrid = _free(blinkHdrid);
713
714 return 0;
715 }
716
717 int rpmtsiOc(rpmtsi tsi)
718 {
719 return tsi->ocsave;
720 }
721
722 /*@-mustmod@*/
723 static void rpmtsiFini(void * _tsi)
724 /*@modifies _tsi @*/
725 {
726 rpmtsi tsi = _tsi;
727 /*@-internalglobs@*/
728 (void)rpmtsFree(tsi->ts);
729 tsi->ts = NULL;
730 /*@=internalglobs@*/
731 }
732 /*@=mustmod@*/
733
734 /*@unchecked@*/ /*@only@*/ /*@null@*/
735 rpmioPool _rpmtsiPool;
736
737 static rpmtsi rpmtsiGetPool(/*@null@*/ rpmioPool pool)
738 /*@globals _rpmtsiPool, fileSystem, internalState @*/
739 /*@modifies pool, _rpmtsiPool, fileSystem, internalState @*/
740 {
741 rpmtsi tsi;
742
743 if (_rpmtsiPool == NULL) {
744 _rpmtsiPool = rpmioNewPool("tsi", sizeof(*tsi), -1, _rpmte_debug,
745 NULL, NULL, rpmtsiFini);/* XXX _rpmtsi_debug? */
746 pool = _rpmtsiPool;
747 }
748 return (rpmtsi) rpmioGetPool(pool, sizeof(*tsi));
749 }
750
751 rpmtsi XrpmtsiInit(rpmts ts, const char * fn, unsigned int ln)
752 {
753 rpmtsi tsi = rpmtsiGetPool(_rpmtsiPool);
754
755 /*@-assignexpose -castexpose @*/
756 tsi->ts = rpmtsLink(ts, "rpmtsi");
757 /*@=assignexpose =castexpose @*/
758 tsi->reverse = 0;
759 tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
760 tsi->ocsave = tsi->oc;
761
762 return (rpmtsi) rpmioLinkPoolItem((rpmioItem)tsi, "rpmtsiInit", fn, ln);
763 }
764
770 static /*@null@*/ /*@dependent@*/
771 rpmte rpmtsiNextElement(rpmtsi tsi)
772 /*@modifies tsi @*/
773 {
774 rpmte te = NULL;
775 int oc = -1;
776
777 if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
778 return te;
779
780 if (tsi->reverse) {
781 if (tsi->oc >= 0) oc = tsi->oc--;
782 } else {
783 if (tsi->oc < rpmtsNElements(tsi->ts)) oc = tsi->oc++;
784 }
785 tsi->ocsave = oc;
786 if (oc != -1)
787 te = rpmtsElement(tsi->ts, oc);
788 return te;
789 }
790
791 rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
792 {
793 rpmte te;
794
795 while ((te = rpmtsiNextElement(tsi)) != NULL) {
796 if (type == 0 || (te->type & type) != 0)
797 break;
798 }
799 return te;
800 }