2000-08-28 03:27:03 +08:00
|
|
|
/**
|
2002-05-20 02:42:25 +08:00
|
|
|
* \file lib/rpmps.c
|
2000-08-28 03:27:03 +08:00
|
|
|
*/
|
|
|
|
|
1998-12-19 03:09:38 +08:00
|
|
|
#include "system.h"
|
|
|
|
|
2008-10-14 17:25:01 +08:00
|
|
|
#include <inttypes.h>
|
2010-01-05 21:04:20 +08:00
|
|
|
#include <stdlib.h>
|
2008-10-14 17:25:01 +08:00
|
|
|
|
2008-03-18 16:18:08 +08:00
|
|
|
#include <rpm/rpmstring.h>
|
2007-12-08 20:02:32 +08:00
|
|
|
#include <rpm/rpmps.h>
|
2002-04-12 00:55:19 +08:00
|
|
|
|
2000-12-13 04:03:45 +08:00
|
|
|
#include "debug.h"
|
1998-12-19 03:09:38 +08:00
|
|
|
|
2007-10-19 17:30:26 +08:00
|
|
|
struct rpmps_s {
|
|
|
|
int numProblems; /*!< Current probs array size. */
|
|
|
|
int numProblemsAlloced; /*!< Allocated probs array size. */
|
2007-10-19 18:01:58 +08:00
|
|
|
rpmProblem *probs; /*!< Array of pointers to specific problems. */
|
2007-10-19 17:30:26 +08:00
|
|
|
int nrefs; /*!< Reference count. */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rpmpsi_s {
|
2007-12-14 17:36:48 +08:00
|
|
|
int ix;
|
2007-10-19 17:30:26 +08:00
|
|
|
rpmps ps;
|
|
|
|
};
|
|
|
|
|
2001-10-30 00:35:01 +08:00
|
|
|
|
2010-03-22 18:54:44 +08:00
|
|
|
rpmps rpmpsUnlink(rpmps ps)
|
2001-11-10 01:22:08 +08:00
|
|
|
{
|
2009-07-09 18:43:10 +08:00
|
|
|
if (ps) {
|
|
|
|
ps->nrefs--;
|
|
|
|
}
|
|
|
|
return NULL;
|
2001-11-10 01:22:08 +08:00
|
|
|
}
|
|
|
|
|
2010-03-22 18:54:44 +08:00
|
|
|
rpmps rpmpsLink(rpmps ps)
|
2001-11-10 01:22:08 +08:00
|
|
|
{
|
2009-07-09 18:43:10 +08:00
|
|
|
if (ps) {
|
|
|
|
ps->nrefs++;
|
|
|
|
}
|
2002-05-18 05:08:39 +08:00
|
|
|
return ps;
|
2001-11-10 01:22:08 +08:00
|
|
|
}
|
|
|
|
|
2002-06-12 22:52:59 +08:00
|
|
|
int rpmpsNumProblems(rpmps ps)
|
|
|
|
{
|
|
|
|
int numProblems = 0;
|
|
|
|
if (ps && ps->probs)
|
|
|
|
numProblems = ps->numProblems;
|
|
|
|
return numProblems;
|
|
|
|
}
|
|
|
|
|
2007-10-18 18:45:25 +08:00
|
|
|
rpmpsi rpmpsInitIterator(rpmps ps)
|
|
|
|
{
|
|
|
|
rpmpsi psi = NULL;
|
2010-03-25 18:34:06 +08:00
|
|
|
if (ps != NULL && ps->numProblems > 0) {
|
2007-10-18 18:45:25 +08:00
|
|
|
psi = xcalloc(1, sizeof(*psi));
|
2010-03-22 18:54:44 +08:00
|
|
|
psi->ps = rpmpsLink(ps);
|
2007-10-18 18:45:25 +08:00
|
|
|
psi->ix = -1;
|
|
|
|
}
|
|
|
|
return psi;
|
|
|
|
}
|
|
|
|
|
|
|
|
rpmpsi rpmpsFreeIterator(rpmpsi psi)
|
|
|
|
{
|
|
|
|
if (psi != NULL) {
|
2010-03-22 18:54:44 +08:00
|
|
|
rpmpsUnlink(psi->ps);
|
2007-10-18 18:45:25 +08:00
|
|
|
free(psi);
|
|
|
|
}
|
2010-03-25 18:35:05 +08:00
|
|
|
return NULL;
|
2007-10-18 18:45:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int rpmpsNextIterator(rpmpsi psi)
|
|
|
|
{
|
|
|
|
int i = -1;
|
|
|
|
|
|
|
|
if (psi != NULL && ++psi->ix >= 0) {
|
|
|
|
if (psi->ix < rpmpsNumProblems(psi->ps)) {
|
|
|
|
i = psi->ix;
|
|
|
|
} else {
|
|
|
|
psi->ix = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2007-10-19 18:25:08 +08:00
|
|
|
rpmProblem rpmpsGetProblem(rpmpsi psi)
|
2007-10-18 18:45:25 +08:00
|
|
|
{
|
2010-03-25 18:45:37 +08:00
|
|
|
rpmProblem p = NULL;
|
2007-10-18 18:45:25 +08:00
|
|
|
if (psi != NULL && psi->ix >= 0 && psi->ix < rpmpsNumProblems(psi->ps)) {
|
2010-03-25 18:45:37 +08:00
|
|
|
p = psi->ps->probs[psi->ix];
|
2007-10-18 18:45:25 +08:00
|
|
|
}
|
2010-03-25 18:45:37 +08:00
|
|
|
return p;
|
2007-10-18 18:45:25 +08:00
|
|
|
}
|
|
|
|
|
2002-05-20 02:42:25 +08:00
|
|
|
rpmps rpmpsCreate(void)
|
2001-10-30 00:35:01 +08:00
|
|
|
{
|
2002-05-20 02:42:25 +08:00
|
|
|
rpmps ps = xcalloc(1, sizeof(*ps));
|
2010-03-22 18:54:44 +08:00
|
|
|
return rpmpsLink(ps);
|
2001-10-30 00:35:01 +08:00
|
|
|
}
|
|
|
|
|
2002-05-20 02:42:25 +08:00
|
|
|
rpmps rpmpsFree(rpmps ps)
|
2001-11-10 01:22:08 +08:00
|
|
|
{
|
|
|
|
if (ps == NULL) return NULL;
|
2009-07-09 18:43:10 +08:00
|
|
|
if (ps->nrefs > 1) {
|
2010-03-22 18:54:44 +08:00
|
|
|
return rpmpsUnlink(ps);
|
2009-07-09 18:43:10 +08:00
|
|
|
}
|
2001-11-10 01:22:08 +08:00
|
|
|
|
|
|
|
if (ps->probs) {
|
2007-10-19 18:01:58 +08:00
|
|
|
rpmpsi psi = rpmpsInitIterator(ps);
|
|
|
|
while (rpmpsNextIterator(psi) >= 0) {
|
2007-10-19 18:25:08 +08:00
|
|
|
rpmProblemFree(rpmpsGetProblem(psi));
|
2001-11-10 01:22:08 +08:00
|
|
|
}
|
2007-10-19 18:01:58 +08:00
|
|
|
rpmpsFreeIterator(psi);
|
2002-05-07 09:07:41 +08:00
|
|
|
ps->probs = _free(ps->probs);
|
2001-11-10 01:22:08 +08:00
|
|
|
}
|
|
|
|
ps = _free(ps);
|
|
|
|
return NULL;
|
2001-10-30 00:35:01 +08:00
|
|
|
}
|
|
|
|
|
2007-10-19 18:01:58 +08:00
|
|
|
void rpmpsAppendProblem(rpmps ps, rpmProblem prob)
|
2001-10-30 00:35:01 +08:00
|
|
|
{
|
2010-03-25 18:39:13 +08:00
|
|
|
if (ps == NULL || prob == NULL) return;
|
2001-11-10 01:22:08 +08:00
|
|
|
|
|
|
|
if (ps->numProblems == ps->numProblemsAlloced) {
|
|
|
|
if (ps->numProblemsAlloced)
|
|
|
|
ps->numProblemsAlloced *= 2;
|
2001-10-30 00:35:01 +08:00
|
|
|
else
|
2001-11-10 01:22:08 +08:00
|
|
|
ps->numProblemsAlloced = 2;
|
|
|
|
ps->probs = xrealloc(ps->probs,
|
2007-10-19 18:01:58 +08:00
|
|
|
ps->numProblemsAlloced * sizeof(ps->probs));
|
2001-10-30 00:35:01 +08:00
|
|
|
}
|
|
|
|
|
2010-03-25 18:39:13 +08:00
|
|
|
ps->probs[ps->numProblems] = rpmProblemLink(prob);
|
2001-11-10 01:22:08 +08:00
|
|
|
ps->numProblems++;
|
2007-10-19 18:01:58 +08:00
|
|
|
}
|
2001-10-30 00:35:01 +08:00
|
|
|
|
2007-10-19 18:01:58 +08:00
|
|
|
void rpmpsAppend(rpmps ps, rpmProblemType type,
|
|
|
|
const char * pkgNEVR, fnpyKey key,
|
|
|
|
const char * dn, const char * bn,
|
2008-06-11 15:31:14 +08:00
|
|
|
const char * altNEVR, uint64_t number)
|
2007-10-19 18:01:58 +08:00
|
|
|
{
|
|
|
|
rpmProblem p = NULL;
|
|
|
|
if (ps == NULL) return;
|
2001-11-01 06:19:42 +08:00
|
|
|
|
2008-06-11 15:31:14 +08:00
|
|
|
p = rpmProblemCreate(type, pkgNEVR, key, dn, bn, altNEVR, number);
|
2007-10-19 18:01:58 +08:00
|
|
|
rpmpsAppendProblem(ps, p);
|
2009-07-09 18:39:55 +08:00
|
|
|
rpmProblemFree(p);
|
2001-10-30 00:35:01 +08:00
|
|
|
}
|
|
|
|
|
2007-10-19 18:01:58 +08:00
|
|
|
/* XXX TODO: implement with iterators */
|
2002-05-20 02:42:25 +08:00
|
|
|
int rpmpsTrim(rpmps ps, rpmps filter)
|
2001-10-30 00:35:01 +08:00
|
|
|
{
|
2007-10-19 18:01:58 +08:00
|
|
|
rpmProblem *t;
|
|
|
|
rpmProblem *f;
|
2001-10-30 00:35:01 +08:00
|
|
|
int gotProblems = 0;
|
|
|
|
|
2001-11-10 01:22:08 +08:00
|
|
|
if (ps == NULL || ps->numProblems == 0)
|
2001-10-30 00:35:01 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (filter == NULL)
|
2001-11-10 01:22:08 +08:00
|
|
|
return (ps->numProblems == 0 ? 0 : 1);
|
2001-10-30 00:35:01 +08:00
|
|
|
|
2001-11-10 01:22:08 +08:00
|
|
|
t = ps->probs;
|
2001-10-30 00:35:01 +08:00
|
|
|
f = filter->probs;
|
|
|
|
|
|
|
|
while ((f - filter->probs) < filter->numProblems) {
|
2001-11-10 01:22:08 +08:00
|
|
|
while ((t - ps->probs) < ps->numProblems) {
|
2010-03-25 22:22:53 +08:00
|
|
|
if (rpmProblemCompare(*f, *t) == 0)
|
2007-09-12 01:07:39 +08:00
|
|
|
break;
|
2001-10-30 00:35:01 +08:00
|
|
|
t++;
|
|
|
|
gotProblems = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX This can't happen, but let's be sane in case it does. */
|
2001-11-10 01:22:08 +08:00
|
|
|
if ((t - ps->probs) == ps->numProblems)
|
2001-10-30 00:35:01 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
t++, f++;
|
|
|
|
}
|
|
|
|
|
2001-11-10 01:22:08 +08:00
|
|
|
if ((t - ps->probs) < ps->numProblems)
|
2001-10-30 00:35:01 +08:00
|
|
|
gotProblems = 1;
|
|
|
|
|
|
|
|
return gotProblems;
|
|
|
|
}
|
1999-09-18 04:52:46 +08:00
|
|
|
|
2002-06-29 05:54:24 +08:00
|
|
|
void rpmpsPrint(FILE *fp, rpmps ps)
|
2001-11-10 01:22:08 +08:00
|
|
|
{
|
2007-12-14 23:55:31 +08:00
|
|
|
char * msg = NULL;
|
2007-10-18 21:09:05 +08:00
|
|
|
rpmpsi psi = NULL;
|
2001-11-10 01:22:08 +08:00
|
|
|
int i;
|
|
|
|
|
2002-06-29 05:54:24 +08:00
|
|
|
if (ps == NULL || ps->probs == NULL || ps->numProblems <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (fp == NULL)
|
|
|
|
fp = stderr;
|
|
|
|
|
2007-10-18 21:09:05 +08:00
|
|
|
psi = rpmpsInitIterator(ps);
|
|
|
|
while ((i = rpmpsNextIterator(psi)) >= 0) {
|
2001-11-10 01:22:08 +08:00
|
|
|
int j;
|
2007-10-19 18:25:08 +08:00
|
|
|
rpmProblem p = rpmpsGetProblem(psi);
|
2001-11-10 01:22:08 +08:00
|
|
|
|
2007-10-18 21:09:05 +08:00
|
|
|
rpmpsi psif = rpmpsInitIterator(ps);
|
2001-11-10 01:22:08 +08:00
|
|
|
/* Filter already displayed problems. */
|
2007-10-18 21:09:05 +08:00
|
|
|
while ((j = rpmpsNextIterator(psif)) < i) {
|
2010-03-25 22:22:53 +08:00
|
|
|
if (rpmProblemCompare(p, rpmpsGetProblem(psif)) == 0)
|
2007-09-12 01:07:39 +08:00
|
|
|
break;
|
2001-11-10 01:22:08 +08:00
|
|
|
}
|
2007-10-18 21:09:05 +08:00
|
|
|
rpmpsFreeIterator(psif);
|
2001-11-10 01:22:08 +08:00
|
|
|
if (j < i)
|
|
|
|
continue;
|
|
|
|
|
2002-06-29 05:54:24 +08:00
|
|
|
msg = rpmProblemString(p);
|
|
|
|
fprintf(fp, "\t%s\n", msg);
|
|
|
|
msg = _free(msg);
|
2001-11-10 01:22:08 +08:00
|
|
|
|
|
|
|
}
|
2007-10-18 21:09:05 +08:00
|
|
|
psi = rpmpsFreeIterator(psi);
|
2001-11-10 01:22:08 +08:00
|
|
|
}
|