Create generic iterator (needs work).
CVS patchset: 7445 CVS date: 2004/10/10 05:30:48
This commit is contained in:
parent
fa313c61b0
commit
e7f1a0e59f
|
@ -8,3 +8,4 @@ tagtable.c
|
|||
*.la
|
||||
*.lcd
|
||||
*.lo
|
||||
tgi
|
||||
|
|
|
@ -13,12 +13,15 @@ INCLUDES = -I. \
|
|||
-I$(top_srcdir)/popt \
|
||||
@INCPATH@
|
||||
|
||||
EXTRA_DIST = getdate.y
|
||||
EXTRA_DIST = getdate.y tgi.c rpmgi.c rpmgi.h
|
||||
|
||||
EXTRA_PROGRAMS = tgi
|
||||
|
||||
pkgincdir = $(pkgincludedir)
|
||||
pkginc_HEADERS = \
|
||||
misc.h rpmcli.h rpmlib.h \
|
||||
rpmal.h rpmds.h rpmfi.h rpmps.h rpmsx.h rpmte.h rpmts.h stringbuf.h
|
||||
rpmal.h rpmds.h rpmfi.h rpmps.h rpmsx.h rpmte.h rpmts.h \
|
||||
stringbuf.h
|
||||
noinst_HEADERS = \
|
||||
cpio.h fsm.h manifest.h psm.h rpmlead.h signature.h rpmlock.h
|
||||
|
||||
|
@ -119,3 +122,6 @@ tplatform: tplatform.o librpm.la
|
|||
|
||||
trhn: trhn.o librpm.la
|
||||
$(LINK) @LDFLAGS_STATIC@ $(CFLAGS) $(DEFS) $(INCLUDES) -o $@ $< $(mylibs)
|
||||
|
||||
tgi_SOURCES = tgi.c rpmgi.c
|
||||
tgi_LDADD = librpm.la
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
/*@-modfilesys@*/
|
||||
/** \ingroup rpmio
|
||||
* \file rpmio/rpmio.c
|
||||
*/
|
||||
#include "system.h"
|
||||
|
||||
#define _RPMGI_INTERNAL
|
||||
#include <rpmgi.h>
|
||||
|
||||
#include <rpmdb.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
/*@unchecked@*/
|
||||
int _rpmgi_debug = 0;
|
||||
|
||||
rpmgi XrpmgiUnlink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
|
||||
{
|
||||
if (gi == NULL) return NULL;
|
||||
|
||||
if (_rpmgi_debug && msg != NULL)
|
||||
fprintf(stderr, "--> gi %p -- %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
|
||||
|
||||
gi->nrefs--;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rpmgi XrpmgiLink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
|
||||
{
|
||||
if (gi == NULL) return NULL;
|
||||
gi->nrefs++;
|
||||
|
||||
if (_rpmgi_debug && msg != NULL)
|
||||
fprintf(stderr, "--> gi %p ++ %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
|
||||
|
||||
/*@-refcounttrans@*/ return gi; /*@=refcounttrans@*/
|
||||
}
|
||||
|
||||
rpmgi rpmgiFree(rpmgi gi)
|
||||
{
|
||||
if (gi == NULL)
|
||||
return NULL;
|
||||
|
||||
if (gi->nrefs > 1)
|
||||
return rpmgiUnlink(gi, NULL);
|
||||
|
||||
if (_rpmgi_debug < 0)
|
||||
fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
|
||||
|
||||
(void) rpmgiUnlink(gi, NULL);
|
||||
|
||||
switch (gi->tag) {
|
||||
default:
|
||||
case RPMGI_RPMDB:
|
||||
break;
|
||||
case RPMGI_HDLIST:
|
||||
break;
|
||||
case RPMGI_ARGLIST:
|
||||
break;
|
||||
case RPMGI_FTSWALK:
|
||||
break;
|
||||
}
|
||||
|
||||
if (gi->ftsp != NULL) {
|
||||
int xx;
|
||||
xx = Fts_close(gi->ftsp);
|
||||
gi->ftsp = NULL;
|
||||
gi->fts = NULL;
|
||||
}
|
||||
gi->mi = rpmdbFreeIterator(gi->mi);
|
||||
gi->ts = rpmtsFree(gi->ts);
|
||||
|
||||
memset(gi, 0, sizeof(*gi)); /* XXX trash and burn */
|
||||
gi = _free(gi);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rpmgi rpmgiNew(rpmts ts, int tag, const void * keyp, size_t keylen)
|
||||
{
|
||||
rpmgi gi = xcalloc(1, sizeof(*gi));
|
||||
|
||||
if (gi == NULL)
|
||||
return NULL;
|
||||
|
||||
gi->ts = rpmtsLink(ts, NULL);
|
||||
gi->tag = tag;
|
||||
gi->i = -1;
|
||||
|
||||
switch (gi->tag) {
|
||||
default:
|
||||
case RPMGI_RPMDB:
|
||||
gi->mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
|
||||
|
||||
if (_rpmgi_debug < 0)
|
||||
fprintf(stderr, "*** gi %p\t%p\n", gi, gi->mi);
|
||||
|
||||
break;
|
||||
case RPMGI_HDLIST:
|
||||
break;
|
||||
case RPMGI_ARGLIST:
|
||||
case RPMGI_FTSWALK:
|
||||
{ char *const * argv = keyp;
|
||||
unsigned flags = keylen;
|
||||
|
||||
gi->argv = argv;
|
||||
gi->argc = 0;
|
||||
if (argv != NULL)
|
||||
while (*argv++ != NULL)
|
||||
gi->argc++;
|
||||
gi->ftsOpts = flags;
|
||||
|
||||
if (_rpmgi_debug < 0)
|
||||
fprintf(stderr, "*** gi %p\t%p[%d]\n", gi, gi->argv, gi->argc);
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
gi = rpmgiLink(gi, NULL);
|
||||
|
||||
return gi;
|
||||
}
|
||||
|
||||
static int indent = 2;
|
||||
|
||||
static const char * ftsInfoStrings[] = {
|
||||
"UNKNOWN",
|
||||
"D",
|
||||
"DC",
|
||||
"DEFAULT",
|
||||
"DNR",
|
||||
"DOT",
|
||||
"DP",
|
||||
"ERR",
|
||||
"F",
|
||||
"INIT",
|
||||
"NS",
|
||||
"NSOK",
|
||||
"SL",
|
||||
"SLNONE",
|
||||
"W",
|
||||
};
|
||||
|
||||
static const char * ftsInfoStr(int fts_info) {
|
||||
if (!(fts_info >= 1 && fts_info <= 14))
|
||||
fts_info = 0;
|
||||
return ftsInfoStrings[ fts_info ];
|
||||
}
|
||||
|
||||
const char * rpmgiNext(/*@null@*/ rpmgi gi)
|
||||
/*@modifies gi @*/
|
||||
{
|
||||
const char * val = NULL;
|
||||
Header h = NULL;
|
||||
|
||||
if (gi != NULL && ++gi->i >= 0)
|
||||
switch (gi->tag) {
|
||||
default:
|
||||
case RPMGI_RPMDB:
|
||||
h = rpmdbNextIterator(gi->mi);
|
||||
if (h != NULL) {
|
||||
const char * fmt = "%{NAME}-%{VERSION}-%{RELEASE}";
|
||||
val = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, NULL);
|
||||
} else {
|
||||
gi->mi = rpmdbFreeIterator(gi->mi);
|
||||
gi->i = -1;
|
||||
}
|
||||
break;
|
||||
case RPMGI_HDLIST:
|
||||
break;
|
||||
case RPMGI_ARGLIST:
|
||||
if (gi->argv != NULL && gi->argv[gi->i] != NULL) {
|
||||
if (_rpmgi_debug < 0)
|
||||
fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]);
|
||||
val = xstrdup(gi->argv[gi->i]);
|
||||
} else
|
||||
gi->i = -1;
|
||||
break;
|
||||
case RPMGI_FTSWALK:
|
||||
if (gi->ftsp == NULL && gi->i == 0)
|
||||
gi->ftsp = Fts_open(gi->argv, gi->ftsOpts, NULL);
|
||||
|
||||
while (val == NULL && (gi->fts = Fts_read(gi->ftsp)) != NULL) {
|
||||
FTSENT * fts = gi->fts;
|
||||
|
||||
if (_rpmgi_debug < 0)
|
||||
fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
|
||||
indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
|
||||
fts->fts_name);
|
||||
|
||||
switch (fts->fts_info) {
|
||||
case FTS_F:
|
||||
case FTS_SL:
|
||||
if (_rpmgi_debug < 0)
|
||||
fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->ftsp, gi->i, fts->fts_path);
|
||||
val = xstrdup(fts->fts_path);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gi->fts == NULL && gi->ftsp != NULL) {
|
||||
int xx;
|
||||
xx = Fts_close(gi->ftsp);
|
||||
gi->ftsp = NULL;
|
||||
gi->i = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
/*@=modfilesys@*/
|
|
@ -0,0 +1,119 @@
|
|||
#ifndef H_RPMGI
|
||||
#define H_RPMGI
|
||||
|
||||
/** \ingroup rpmio
|
||||
* \file rpmio/rpmgi.h
|
||||
*/
|
||||
|
||||
#include <rpmlib.h>
|
||||
#include <rpmts.h>
|
||||
#include <fts.h>
|
||||
#include <argv.h>
|
||||
|
||||
/**
|
||||
*/
|
||||
/*@-exportlocal@*/
|
||||
/*@unchecked@*/
|
||||
extern int _rpmgi_debug;
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/**
|
||||
*/
|
||||
typedef /*@abstract@*/ struct rpmgi_s * rpmgi;
|
||||
|
||||
/**
|
||||
*/
|
||||
typedef enum rpmgiTag_e {
|
||||
RPMGI_RPMDB = RPMDBI_PACKAGES,
|
||||
RPMGI_HDLIST = 6, /* XXX next after RPMDBI_AVAILABLE */
|
||||
RPMGI_ARGLIST = 7,
|
||||
RPMGI_FTSWALK = 8
|
||||
} rpmgiTag;
|
||||
|
||||
#if defined(_RPMGI_INTERNAL)
|
||||
/** \ingroup rpmio
|
||||
*/
|
||||
struct rpmgi_s {
|
||||
rpmts ts;
|
||||
int tag;
|
||||
int i;
|
||||
|
||||
rpmdbMatchIterator mi;
|
||||
|
||||
char *const * argv;
|
||||
int argc;
|
||||
int ftsOpts;
|
||||
FTS * ftsp;
|
||||
FTSENT * fts;
|
||||
|
||||
/*@refs@*/
|
||||
int nrefs;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Unreference a generalized iterator instance.
|
||||
* @param gi generalized iterator
|
||||
* @param msg
|
||||
* @return NULL always
|
||||
*/
|
||||
/*@unused@*/ /*@null@*/
|
||||
rpmgi rpmgiUnlink (/*@killref@*/ /*@only@*/ /*@null@*/ rpmgi gi,
|
||||
/*@null@*/ const char * msg)
|
||||
/*@modifies gi @*/;
|
||||
|
||||
/** @todo Remove debugging entry from the ABI. */
|
||||
/*@-exportlocal@*/
|
||||
/*@null@*/
|
||||
rpmgi XrpmgiUnlink (/*@killref@*/ /*@only@*/ /*@null@*/ rpmgi gi,
|
||||
/*@null@*/ const char * msg, const char * fn, unsigned ln)
|
||||
/*@modifies gi @*/;
|
||||
/*@=exportlocal@*/
|
||||
#define rpmgiUnlink(_gi, _msg) XrpmgiUnlink(_gi, _msg, __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Reference a generalized iterator instance.
|
||||
* @param gi generalized iterator
|
||||
* @param msg
|
||||
* @return new generalized iterator reference
|
||||
*/
|
||||
/*@unused@*/ /*@newref@*/ /*@null@*/
|
||||
rpmgi rpmgiLink (/*@null@*/ rpmgi gi, /*@null@*/ const char * msg)
|
||||
/*@modifies gi @*/;
|
||||
|
||||
/** @todo Remove debugging entry from the ABI. */
|
||||
/*@newref@*/ /*@null@*/
|
||||
rpmgi XrpmgiLink (/*@null@*/ rpmgi gi, /*@null@*/ const char * msg,
|
||||
const char * fn, unsigned ln)
|
||||
/*@modifies gi @*/;
|
||||
#define rpmgiLink(_gi, _msg) XrpmgiLink(_gi, _msg, __FILE__, __LINE__)
|
||||
|
||||
/** Destroy a generalized iterator.
|
||||
* @param gi generalized iterator
|
||||
* @return NULL always
|
||||
*/
|
||||
/*@only@*/
|
||||
rpmgi rpmgiFree(/*@killref@*/ /*@only@*/ /*@null@*/ rpmgi gi)
|
||||
/*@modifies gi @*/;
|
||||
|
||||
/** Create a generalized iterator.
|
||||
* @param argv iterator argv array
|
||||
* @param flags iterator flags
|
||||
* @return new general iterator
|
||||
*/
|
||||
/*@only@*/
|
||||
rpmgi rpmgiNew(rpmts ts, int tag, const void * keyp, size_t keylen)
|
||||
/*@*/;
|
||||
|
||||
const char * rpmgiNext(/*@null@*/ rpmgi gi)
|
||||
/*@modifies gi @*/;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_RPMGI */
|
|
@ -0,0 +1,100 @@
|
|||
#include "system.h"
|
||||
|
||||
#include <rpmio_internal.h>
|
||||
#define _RPMGI_INTERNAL
|
||||
#include <rpmgi.h>
|
||||
#include <rpmcli.h>
|
||||
|
||||
#include <rpmmacro.h>
|
||||
#include <rpmmessages.h>
|
||||
#include <popt.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
static int gitag = RPMGI_FTSWALK;
|
||||
static int ftsOpts = 0;
|
||||
|
||||
static struct poptOption optionsTable[] = {
|
||||
{ "rpmgidebug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmgi_debug, -1,
|
||||
N_("debug generalized iterator"), NULL},
|
||||
|
||||
{ "rpmdb", '\0', POPT_ARG_VAL, &gitag, RPMGI_RPMDB,
|
||||
N_("iterate rpmdb"), NULL },
|
||||
{ "hdlist", '\0', POPT_ARG_VAL, &gitag, RPMGI_HDLIST,
|
||||
N_("iterate hdlist"), NULL },
|
||||
{ "arglist", '\0', POPT_ARG_VAL, &gitag, RPMGI_ARGLIST,
|
||||
N_("iterate arglist"), NULL },
|
||||
{ "ftswalk", '\0', POPT_ARG_VAL, &gitag, RPMGI_FTSWALK,
|
||||
N_("iterate fts(3) walk"), NULL },
|
||||
|
||||
{ "comfollow", '\0', POPT_BIT_SET, &ftsOpts, FTS_COMFOLLOW,
|
||||
N_("follow command line symlinks"), NULL },
|
||||
{ "logical", '\0', POPT_BIT_SET, &ftsOpts, FTS_LOGICAL,
|
||||
N_("logical walk"), NULL },
|
||||
{ "nochdir", '\0', POPT_BIT_SET, &ftsOpts, FTS_NOCHDIR,
|
||||
N_("don't change directories"), NULL },
|
||||
{ "nostat", '\0', POPT_BIT_SET, &ftsOpts, FTS_NOSTAT,
|
||||
N_("don't get stat info"), NULL },
|
||||
{ "physical", '\0', POPT_BIT_SET, &ftsOpts, FTS_PHYSICAL,
|
||||
N_("physical walk"), NULL },
|
||||
{ "seedot", '\0', POPT_BIT_SET, &ftsOpts, FTS_SEEDOT,
|
||||
N_("return dot and dot-dot"), NULL },
|
||||
{ "xdev", '\0', POPT_BIT_SET, &ftsOpts, FTS_XDEV,
|
||||
N_("don't cross devices"), NULL },
|
||||
{ "whiteout", '\0', POPT_BIT_SET, &ftsOpts, FTS_WHITEOUT,
|
||||
N_("return whiteout information"), NULL },
|
||||
|
||||
#ifdef DYING
|
||||
{ "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
|
||||
N_("debug protocol data stream"), NULL},
|
||||
{ "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
|
||||
N_("debug rpmio I/O"), NULL},
|
||||
{ "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
|
||||
N_("debug URL cache handling"), NULL},
|
||||
{ "verbose", 'v', 0, 0, 'v', NULL, NULL },
|
||||
#endif
|
||||
|
||||
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
|
||||
N_("Common options for all rpm modes and executables:"),
|
||||
NULL },
|
||||
|
||||
POPT_AUTOALIAS
|
||||
POPT_AUTOHELP
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *const argv[])
|
||||
{
|
||||
poptContext optCon;
|
||||
rpmts ts = NULL;
|
||||
rpmgi gi = NULL;
|
||||
const char ** av;
|
||||
const char * arg;
|
||||
int ac;
|
||||
int rc = 0;
|
||||
|
||||
optCon = rpmcliInit(argc, argv, optionsTable);
|
||||
if (optCon == NULL)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
if (ftsOpts == 0)
|
||||
ftsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT);
|
||||
|
||||
ts = rpmtsCreate();
|
||||
av = poptGetArgs(optCon);
|
||||
gi = rpmgiNew(ts, gitag, av, ftsOpts);
|
||||
|
||||
ac = 0;
|
||||
while ((arg = rpmgiNext(gi)) != NULL) {
|
||||
fprintf(stderr, "%5d %s\n", ac, arg);
|
||||
arg = _free(arg);
|
||||
ac++;
|
||||
}
|
||||
|
||||
gi = rpmgiFree(gi);
|
||||
ts = rpmtsFree(ts);
|
||||
optCon = rpmcliFini(optCon);
|
||||
|
||||
return rc;
|
||||
}
|
Loading…
Reference in New Issue