csomh / source-git / rpm

Forked from source-git/rpm 4 years ago
Clone
2ff057
/**
2ff057
 * \file lib/rpmps.c
2ff057
 */
2ff057
2ff057
#include "system.h"
2ff057
2ff057
#include <inttypes.h>
2ff057
#include <stdlib.h>
2ff057
2ff057
#include <rpm/rpmstring.h>
2ff057
#include <rpm/rpmps.h>
2ff057
2ff057
#include "debug.h"
2ff057
2ff057
struct rpmps_s {
2ff057
    int numProblems;		/*!< Current probs array size. */
2ff057
    int numProblemsAlloced;	/*!< Allocated probs array size. */
2ff057
    rpmProblem *probs;		/*!< Array of pointers to specific problems. */
2ff057
    int nrefs;			/*!< Reference count. */
2ff057
};
2ff057
2ff057
struct rpmpsi_s {
2ff057
    int ix;
2ff057
    rpmps ps;
2ff057
};
2ff057
2ff057
2ff057
static rpmps rpmpsUnlink(rpmps ps)
2ff057
{
2ff057
    if (ps) {
2ff057
	ps->nrefs--;
2ff057
    }
2ff057
    return NULL;
2ff057
}
2ff057
2ff057
rpmps rpmpsLink(rpmps ps)
2ff057
{
2ff057
    if (ps) {
2ff057
	ps->nrefs++;
2ff057
    }
2ff057
    return ps;
2ff057
}
2ff057
2ff057
int rpmpsNumProblems(rpmps ps)
2ff057
{
2ff057
    int numProblems = 0;
2ff057
    if (ps && ps->probs)
2ff057
	numProblems = ps->numProblems;
2ff057
    return numProblems;
2ff057
}
2ff057
2ff057
rpmpsi rpmpsInitIterator(rpmps ps)
2ff057
{
2ff057
    rpmpsi psi = NULL;
2ff057
    if (ps != NULL && ps->numProblems > 0) {
2ff057
	psi = xcalloc(1, sizeof(*psi));
2ff057
	psi->ps = rpmpsLink(ps);
2ff057
	psi->ix = -1;
2ff057
    }
2ff057
    return psi;
2ff057
}
2ff057
2ff057
rpmpsi rpmpsFreeIterator(rpmpsi psi)
2ff057
{
2ff057
    if (psi != NULL) {
2ff057
	rpmpsUnlink(psi->ps);
2ff057
	free(psi);
2ff057
    }
2ff057
    return NULL;
2ff057
}
2ff057
2ff057
rpmProblem rpmpsiNext(rpmpsi psi)
2ff057
{
2ff057
    rpmProblem p = NULL;
2ff057
    if (psi != NULL && psi->ps != NULL && ++psi->ix >= 0) {
2ff057
	rpmps ps = psi->ps;
2ff057
	if (psi->ix < ps->numProblems) {
2ff057
	    p = ps->probs[psi->ix];
2ff057
	} else {
2ff057
	    psi->ix = -1;
2ff057
	}
2ff057
    }
2ff057
    return p;
2ff057
}
2ff057
2ff057
int rpmpsNextIterator(rpmpsi psi)
2ff057
{
2ff057
    return (rpmpsiNext(psi) != NULL) ? psi->ix : -1;
2ff057
}
2ff057
2ff057
rpmProblem rpmpsGetProblem(rpmpsi psi)
2ff057
{
2ff057
    rpmProblem p = NULL;
2ff057
    if (psi != NULL && psi->ix >= 0 && psi->ix < rpmpsNumProblems(psi->ps)) {
2ff057
	p = psi->ps->probs[psi->ix];
2ff057
    } 
2ff057
    return p;
2ff057
}
2ff057
2ff057
rpmps rpmpsCreate(void)
2ff057
{
2ff057
    rpmps ps = xcalloc(1, sizeof(*ps));
2ff057
    return rpmpsLink(ps);
2ff057
}
2ff057
2ff057
rpmps rpmpsFree(rpmps ps)
2ff057
{
2ff057
    if (ps == NULL) return NULL;
2ff057
    if (ps->nrefs > 1) {
2ff057
	return rpmpsUnlink(ps);
2ff057
    }
2ff057
	
2ff057
    if (ps->probs) {
2ff057
	rpmpsi psi = rpmpsInitIterator(ps);
2ff057
	while (rpmpsNextIterator(psi) >= 0) {
2ff057
	    rpmProblemFree(rpmpsGetProblem(psi));	
2ff057
	}
2ff057
	rpmpsFreeIterator(psi);
2ff057
	ps->probs = _free(ps->probs);
2ff057
    }
2ff057
    ps = _free(ps);
2ff057
    return NULL;
2ff057
}
2ff057
2ff057
void rpmpsAppendProblem(rpmps ps, rpmProblem prob)
2ff057
{
2ff057
    if (ps == NULL || prob == NULL) return;
2ff057
2ff057
    if (ps->numProblems == ps->numProblemsAlloced) {
2ff057
	if (ps->numProblemsAlloced)
2ff057
	    ps->numProblemsAlloced *= 2;
2ff057
	else
2ff057
	    ps->numProblemsAlloced = 2;
2ff057
	ps->probs = xrealloc(ps->probs,
2ff057
			ps->numProblemsAlloced * sizeof(*ps->probs));
2ff057
    }
2ff057
2ff057
    ps->probs[ps->numProblems] = rpmProblemLink(prob);
2ff057
    ps->numProblems++;
2ff057
}
2ff057
2ff057
/*
2ff057
 * TODO: filter out duplicates while merging. Also horribly inefficient... */
2ff057
int rpmpsMerge(rpmps dest, rpmps src)
2ff057
{
2ff057
    int rc = 0;
2ff057
    if (dest != NULL) {
2ff057
	rpmProblem p;
2ff057
	rpmpsi spi = rpmpsInitIterator(src);
2ff057
	while ((p = rpmpsiNext(spi)) != NULL) {
2ff057
	    rpmpsAppendProblem(dest, p);
2ff057
	    rc++;
2ff057
	}
2ff057
	rpmpsFreeIterator(spi);
2ff057
    }
2ff057
    return rc;
2ff057
}
2ff057
2ff057
void rpmpsPrint(FILE *fp, rpmps ps)
2ff057
{
2ff057
    rpmProblem p;
2ff057
    rpmpsi psi = rpmpsInitIterator(ps);
2ff057
    FILE *f = (fp != NULL) ? fp : stderr;
2ff057
2ff057
    while ((p = rpmpsiNext(psi))) {
2ff057
	char *msg = rpmProblemString(p);
2ff057
	fprintf(f, "\t%s\n", msg);
2ff057
	free(msg);
2ff057
    }
2ff057
    rpmpsFreeIterator(psi);
2ff057
}
2ff057