summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2008-10-20 10:21:46 +0000
committerMichael Schroeder <mls@suse.de>2008-10-20 10:21:46 +0000
commitf8393a70607c00966b2050029ef35a7fb70e122a (patch)
tree2523a78012fae08aecba49cb933b54143a8937a9 /src
parent64a8733d32ea62fff88a81cec5cf0aa13224a32c (diff)
downloadlibsolv-f8393a70607c00966b2050029ef35a7fb70e122a.tar.gz
libsolv-f8393a70607c00966b2050029ef35a7fb70e122a.tar.bz2
libsolv-f8393a70607c00966b2050029ef35a7fb70e122a.zip
- more cleanups:
- add pool argument to datamatcher_init - add flags argument to repodata_search - only add sentinal if SEARCH_SENTINEL is specified - use kv.eof == 2 for sentinel like before - rename dataiterator_match to dataiterator_match_obsolete - add repodata_stringify function - make datamatcher match simple strings so it can be reused - add dataiterator_prepend_keyname to match keyname pathes - rename dataiterator_jump_to_solvable to dataiterator_jump_to_solvid
Diffstat (limited to 'src')
-rw-r--r--src/knownid.h13
-rw-r--r--src/pool.c8
-rw-r--r--src/pool.h4
-rw-r--r--src/repo.c13
-rw-r--r--src/repo.h26
-rw-r--r--src/repo_solv.c6
-rw-r--r--src/repodata.c326
-rw-r--r--src/repodata.h4
8 files changed, 250 insertions, 150 deletions
diff --git a/src/knownid.h b/src/knownid.h
index 77bf275..d74eb3e 100644
--- a/src/knownid.h
+++ b/src/knownid.h
@@ -26,6 +26,9 @@ enum sat_knownid {
KNOWNID(ID_NULL, "<NULL>"),
KNOWNID(ID_EMPTY, ""),
+
+/* The following Ids are stored in the solvable and must
+ * come in one block */
KNOWNID(SOLVABLE_NAME, "solvable:name"),
KNOWNID(SOLVABLE_ARCH, "solvable:arch"),
KNOWNID(SOLVABLE_EVR, "solvable:evr"),
@@ -39,6 +42,7 @@ KNOWNID(SOLVABLE_SUGGESTS, "solvable:suggests"),
KNOWNID(SOLVABLE_SUPPLEMENTS, "solvable:supplements"),
KNOWNID(SOLVABLE_ENHANCES, "solvable:enhances"),
KNOWNID(RPM_RPMDBID, "rpm:dbid"),
+
/* normal requires before this, prereqs after this */
KNOWNID(SOLVABLE_PREREQMARKER, "solvable:prereqmarker"),
/* normal provides before this, generated file provides after this */
@@ -119,12 +123,9 @@ KNOWNID(SOLVABLE_SOURCENAME, "solvable:sourcename"),
KNOWNID(SOLVABLE_SOURCEEVR, "solvable:sourceevr"),
KNOWNID(SOLVABLE_ISVISIBLE, "solvable:isvisible"),
KNOWNID(SOLVABLE_CHECKSUM, "solvable:checksum"),
-/* pkgid: md5sum over header + payload */
-KNOWNID(SOLVABLE_PKGID, "solvable:pkgid"),
-/* hdrid: sha1sum over header only */
-KNOWNID(SOLVABLE_HDRID, "solvable:hdrid"),
-/* leadsigid: md5sum over lead + sigheader */
-KNOWNID(SOLVABLE_LEADSIGID, "solvable:leadsigid"),
+KNOWNID(SOLVABLE_PKGID, "solvable:pkgid"), /* pkgid: md5sum over header + payload */
+KNOWNID(SOLVABLE_HDRID, "solvable:hdrid"), /* hdrid: sha1sum over header only */
+KNOWNID(SOLVABLE_LEADSIGID, "solvable:leadsigid"), /* leadsigid: md5sum over lead + sigheader */
KNOWNID(SOLVABLE_PATCHCATEGORY, "solvable:patchcategory"),
KNOWNID(SOLVABLE_HEADEREND, "solvable:headerend"),
diff --git a/src/pool.c b/src/pool.c
index f954b82..7394be9 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -885,7 +885,7 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru
if (data)
{
map_init(&providedids, pool->ss.nstrings);
- repodata_search(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, addfileprovides_setid_cb, &providedids);
+ repodata_search(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, 0, addfileprovides_setid_cb, &providedids);
for (i = 0; i < cbd->nfiles; i++)
if (!MAPTST(&providedids, cbd->ids[i]))
break;
@@ -1009,6 +1009,12 @@ pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callba
repo_search(pool->solvables[p].repo, p, key, match, flags, callback, cbdata);
}
+void
+pool_clear_pos(Pool *pool)
+{
+ memset(&pool->pos, 0, sizeof(pool->pos));
+}
+
void
pool_set_languages(Pool *pool, const char **languages, int nlanguages)
diff --git a/src/pool.h b/src/pool.h
index 361041d..5ac2227 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -45,6 +45,7 @@ struct _KeyValue;
typedef struct _Repopos {
struct _Repo *repo;
+ Id solvid;
Id repodataid;
Id schema;
Id dp;
@@ -270,6 +271,9 @@ static inline void pool_setloadcallback(Pool *pool, FILE *(*cb)(struct _Pool *,
*/
void pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, struct _Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata);
+void pool_clear_pos(Pool *pool);
+
+
typedef struct _duchanges {
const char *path;
int kbytes;
diff --git a/src/repo.c b/src/repo.c
index af7c402..c306292 100644
--- a/src/repo.c
+++ b/src/repo.c
@@ -581,8 +581,13 @@ repo_matchvalue(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValu
{
struct matchdata *md = cbdata;
- if (md->matcher.match && !datamatcher_match(&md->matcher, data, key, kv))
- return 0;
+ if (md->matcher.match)
+ {
+ if (!repodata_stringify(md->pool, data, key, kv, md->flags))
+ return 0;
+ if (!datamatcher_match(&md->matcher, kv->str))
+ return 0;
+ }
md->stop = md->callback(md->callback_data, s, data, key, kv);
return md->stop;
}
@@ -762,7 +767,7 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md)
}
if (data->state == REPODATA_ERROR)
continue;
- repodata_search(data, p, keyname, repo_matchvalue, md);
+ repodata_search(data, p, keyname, md->flags, repo_matchvalue, md);
if (md->stop > SEARCH_NEXT_KEY)
break;
}
@@ -779,7 +784,7 @@ repo_search(Repo *repo, Id p, Id keyname, const char *match, int flags, int (*ca
md.callback = callback;
md.callback_data = cbdata;
if (match)
- datamatcher_init(&md.matcher, md.pool, match, flags);
+ datamatcher_init(&md.matcher, match, flags);
repo_search_md(repo, p, keyname, &md);
if (match)
datamatcher_free(&md.matcher);
diff --git a/src/repo.h b/src/repo.h
index 4f801c1..0e83522 100644
--- a/src/repo.h
+++ b/src/repo.h
@@ -44,8 +44,7 @@ typedef struct _Repo {
int idarraysize;
Offset lastoff;
- Id *rpmdbid; /* hmm, go to repodata? */
- unsigned char rpmdbcookie[32];
+ Id *rpmdbid; /* solvable side data */
Repodata *repodata; /* our stores for non-solvable related data */
unsigned nrepodata; /* number of our stores.. */
@@ -142,6 +141,7 @@ static inline void repo_free_solvable_block(Repo *repo, Id start, int count, int
#define SEARCH_NEXT_KEY 1
#define SEARCH_NEXT_SOLVABLE 2
#define SEARCH_STOP 3
+#define SEARCH_ENTERSUB -1
typedef struct _KeyValue {
Id id;
@@ -166,7 +166,7 @@ typedef struct _KeyValue {
#define SEARCH_NOCASE (1<<8)
#define SEARCH_NO_STORAGE_SOLVABLE (1<<9)
#define SEARCH_SUB (1<<10)
-#define SEARCH_ALL_REPOS (1<<11)
+#define SEARCH_ARRAYSENTINEL (1<<11)
#define SEARCH_SKIP_KIND (1<<12)
@@ -223,7 +223,6 @@ typedef struct _Dataiterator
#else
typedef struct _Datamatcher {
- Pool *pool;
int flags;
void *match;
int error;
@@ -264,35 +263,40 @@ typedef struct _Dataiterator
Id *keyp;
} parents[3];
int nparents;
+ Id keynames[3 + 1];
+ int nkeynames;
+
} Dataiterator;
#endif
-void datamatcher_init(Datamatcher *ma, Pool *pool, const char *match, int flags);
+int datamatcher_init(Datamatcher *ma, const char *match, int flags);
void datamatcher_free(Datamatcher *ma);
-int datamatcher_match(Datamatcher *ma, Repodata *data, Repokey *key, KeyValue *kv);
+int datamatcher_match(Datamatcher *ma, const char *str);
/* Use these like:
Dataiterator di;
- dataiterator_init(&di, repo, 0, 0, "bla", SEARCH_SUBSTRING);
+ dataiterator_init(&di, repo->pool, repo, 0, 0, "bla", SEARCH_SUBSTRING);
while (dataiterator_step(&di))
dosomething(di.solvid, di.key, di.kv);
dataiterator_free(&di); */
-void dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname,
+int dataiterator_init(Dataiterator *di, Pool *pool, Repo *repo, Id p, Id keyname,
const char *match, int flags);
+void dataiterator_prepend_keyname(Dataiterator *di, Id keyname);
void dataiterator_free(Dataiterator *di);
int dataiterator_step(Dataiterator *di);
void dataiterator_setpos(Dataiterator *di);
void dataiterator_setpos_parent(Dataiterator *di);
-int dataiterator_match(Dataiterator *di, int flags, const void *match);
+int dataiterator_match(Dataiterator *di, Datamatcher *ma);
void dataiterator_skip_attribute(Dataiterator *di);
void dataiterator_skip_solvable(Dataiterator *di);
void dataiterator_skip_repo(Dataiterator *di);
-void dataiterator_jump_to_solvable(Dataiterator *di, Solvable *s);
+void dataiterator_jump_to_solvid(Dataiterator *di, Id solvid);
void dataiterator_jump_to_repo(Dataiterator *di, Repo *repo);
+void dataiterator_entersub(Dataiterator *di);
/* to be removed ... */
-int dataiterator_match(Dataiterator *di, int flags, const void *match);
+int dataiterator_match_obsolete(Dataiterator *di, int flags, const void *match);
void repo_set_id(Repo *repo, Id p, Id keyname, Id id);
void repo_set_num(Repo *repo, Id p, Id keyname, Id num);
diff --git a/src/repo_solv.c b/src/repo_solv.c
index 518378c..cb7d21f 100644
--- a/src/repo_solv.c
+++ b/src/repo_solv.c
@@ -430,12 +430,12 @@ create_stub_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue
}
stubdata->data = 0;
}
- if (kv->eof)
+ if (kv->eof == 2)
return SEARCH_NEXT_SOLVABLE;
stubdata->data = repo_add_repodata(data->repo, 0);
stubdata->data->state = REPODATA_STUB;
stubdata->data->loadcallback = repodata_load_stub;
- return 0;
+ return SEARCH_ENTERSUB;
}
if (!stubdata->data)
return SEARCH_NEXT_KEY;
@@ -1328,7 +1328,7 @@ printf("=> %s %s %p\n", id2str(pool, keys[key].name), id2str(pool, keys[key].typ
struct create_stub_data stubdata;
/* got some */
memset(&stubdata, 0, sizeof(stubdata));
- repodata_search(&data, SOLVID_META, REPOSITORY_EXTERNAL, create_stub_cb, &stubdata);
+ repodata_search(&data, SOLVID_META, REPOSITORY_EXTERNAL, SEARCH_ARRAYSENTINEL, create_stub_cb, &stubdata);
}
return 0;
}
diff --git a/src/repodata.c b/src/repodata.c
index ae4d470..8e2c88b 100644
--- a/src/repodata.c
+++ b/src/repodata.c
@@ -611,6 +611,44 @@ repodata_lookup_bin_checksum(Repodata *data, Id solvid, Id keyname, Id *typep)
* data search
*/
+
+int
+repodata_stringify(Pool *pool, Repodata *data, Repokey *key, KeyValue *kv, int flags)
+{
+ switch (key->type)
+ {
+ case REPOKEY_TYPE_ID:
+ case REPOKEY_TYPE_CONSTANTID:
+ case REPOKEY_TYPE_IDARRAY:
+ if (data && data->localpool)
+ kv->str = stringpool_id2str(&data->spool, kv->id);
+ else
+ kv->str = id2str(pool, kv->id);
+ if ((flags & SEARCH_SKIP_KIND) != 0 && key->storage == KEY_STORAGE_SOLVABLE)
+ {
+ const char *s = strchr(kv->str, ':');
+ if (s)
+ kv->str = s + 1;
+ }
+ return 1;
+ case REPOKEY_TYPE_STR:
+ return 1;
+ case REPOKEY_TYPE_DIRSTRARRAY:
+ if (!(flags & SEARCH_FILES))
+ return 1; /* match just the basename */
+ /* Put the full filename into kv->str. */
+ kv->str = repodata_dir2str(data, kv->id, kv->str);
+ /* And to compensate for that put the "empty" directory into
+ kv->id, so that later calls to repodata_dir2str on this data
+ come up with the same filename again. */
+ kv->id = 0;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
struct subschema_data {
Solvable *s;
void *cbdata;
@@ -619,7 +657,7 @@ struct subschema_data {
/* search a specific repodata */
void
-repodata_search(Repodata *data, Id solvid, Id keyname, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
+repodata_search(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
{
Id schema;
Repokey *key;
@@ -686,6 +724,8 @@ repodata_search(Repodata *data, Id solvid, Id keyname, int (*callback)(void *cbd
kv.eof = 0;
while (ddp && nentries > 0)
{
+ if (!--nentries)
+ kv.eof = 1;
if (key->type == REPOKEY_TYPE_FLEXARRAY || !kv.entry)
ddp = data_read_id(ddp, &schema);
kv.id = schema;
@@ -693,18 +733,17 @@ repodata_search(Repodata *data, Id solvid, Id keyname, int (*callback)(void *cbd
stop = callback(cbdata, s, data, key, &kv);
if (stop > SEARCH_NEXT_KEY)
return;
- if (stop)
+ if (stop && stop != SEARCH_ENTERSUB)
break;
- if (!keyname)
- repodata_search(data, SOLVID_SUBSCHEMA, 0, callback, &subd);
+ if ((flags & SEARCH_SUB) != 0 || stop == SEARCH_ENTERSUB)
+ repodata_search(data, SOLVID_SUBSCHEMA, 0, flags, callback, &subd);
ddp = data_skip_schema(data, ddp, schema);
- nentries--;
kv.entry++;
}
- if (!nentries)
+ if (!nentries && (flags & SEARCH_ARRAYSENTINEL) != 0)
{
/* sentinel */
- kv.eof = 1;
+ kv.eof = 2;
kv.str = (char *)ddp;
stop = callback(cbdata, s, data, key, &kv);
if (stop > SEARCH_NEXT_KEY)
@@ -734,15 +773,10 @@ repodata_setpos_kv(Repodata *data, KeyValue *kv)
{
Pool *pool = data->repo->pool;
if (!kv)
- {
- pool->pos.repo = 0;
- pool->pos.repodataid = 0;
- pool->pos.dp = 0;
- pool->pos.schema = 0;
- }
+ pool_clear_pos(pool);
else
{
- pool->pos.repo = 0;
+ pool->pos.repo = data->repo;
pool->pos.repodataid = data - data->repo->repodata;
pool->pos.dp = (unsigned char *)kv->str - data->incoredata;
pool->pos.schema = kv->id;
@@ -819,10 +853,9 @@ solvabledata_fetch(Solvable *s, KeyValue *kv, Id keyname)
}
}
-void
-datamatcher_init(Datamatcher *ma, Pool *pool, const char *match, int flags)
+int
+datamatcher_init(Datamatcher *ma, const char *match, int flags)
{
- ma->pool = pool;
ma->match = (void *)match;
ma->flags = flags;
ma->error = 0;
@@ -837,6 +870,7 @@ datamatcher_init(Datamatcher *ma, Pool *pool, const char *match, int flags)
ma->flags = (flags & ~SEARCH_STRINGMASK) | SEARCH_ERROR;
}
}
+ return ma->error;
}
void
@@ -850,72 +884,40 @@ datamatcher_free(Datamatcher *ma)
}
int
-datamatcher_match(Datamatcher *ma, Repodata *data, Repokey *key, KeyValue *kv)
+datamatcher_match(Datamatcher *ma, const char *str)
{
- switch (key->type)
- {
- case REPOKEY_TYPE_ID:
- case REPOKEY_TYPE_IDARRAY:
- if (data && data->localpool)
- kv->str = stringpool_id2str(&data->spool, kv->id);
- else
- kv->str = id2str(ma->pool, kv->id);
- break;
- case REPOKEY_TYPE_STR:
- break;
- case REPOKEY_TYPE_DIRSTRARRAY:
- if (!(ma->flags & SEARCH_FILES))
- return 0;
- /* Put the full filename into kv->str. */
- kv->str = repodata_dir2str(data, kv->id, kv->str);
- /* And to compensate for that put the "empty" directory into
- kv->id, so that later calls to repodata_dir2str on this data
- come up with the same filename again. */
- kv->id = 0;
- break;
- default:
- return 0;
- }
- /* Maybe skip the kind specifier. Do this only for SOLVABLE attributes,
- for the others we can't know if a colon separates a kind or not. */
- if ((ma->flags & SEARCH_SKIP_KIND) != 0 && key->storage == KEY_STORAGE_SOLVABLE)
- {
- const char *s = strchr(kv->str, ':');
- if (s)
- kv->str = s + 1;
- }
switch ((ma->flags & SEARCH_STRINGMASK))
{
case SEARCH_SUBSTRING:
if (ma->flags & SEARCH_NOCASE)
{
- if (!strcasestr(kv->str, (const char *)ma->match))
+ if (!strcasestr(str, (const char *)ma->match))
return 0;
}
else
{
- if (!strstr(kv->str, (const char *)ma->match))
+ if (!strstr(str, (const char *)ma->match))
return 0;
}
break;
case SEARCH_STRING:
if (ma->flags & SEARCH_NOCASE)
{
- if (strcasecmp((const char *)ma->match, kv->str))
+ if (strcasecmp((const char *)ma->match, str))
return 0;
}
else
{
- if (strcmp((const char *)ma->match, kv->str))
+ if (strcmp((const char *)ma->match, str))
return 0;
}
break;
case SEARCH_GLOB:
- if (fnmatch((const char *)ma->match, kv->str, (ma->flags & SEARCH_NOCASE) ? FNM_CASEFOLD : 0))
+ if (fnmatch((const char *)ma->match, str, (ma->flags & SEARCH_NOCASE) ? FNM_CASEFOLD : 0))
return 0;
break;
case SEARCH_REGEX:
- if (regexec((const regex_t *)ma->match, kv->str, 0, NULL, 0))
+ if (regexec((const regex_t *)ma->match, str, 0, NULL, 0))
return 0;
break;
default:
@@ -930,6 +932,7 @@ enum {
di_enterrepo,
di_entersolvable,
di_enterrepodata,
+ di_enterschema,
di_enterkey,
di_nextattr,
@@ -949,36 +952,55 @@ enum {
di_entersolvablekey
};
-void
-dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname, const char *match, int flags)
+int
+dataiterator_init(Dataiterator *di, Pool *pool, Repo *repo, Id p, Id keyname, const char *match, int flags)
{
memset(di, 0, sizeof(*di));
- di->repo = repo;
- di->keyname = keyname;
- di->solvid = p;
- di->pool = repo->pool;
- if (p)
- flags |= SEARCH_THISSOLVID;
- di->flags = flags;
- if (repo && !(flags & SEARCH_ALL_REPOS))
- di->repoid = -1;
- else
- di->repo = di->pool->repos[0];
+ di->pool = pool;
if (match)
- datamatcher_init(&di->matcher, di->pool, match, flags);
- if (p == SOLVID_POS)
{
- di->repo = di->pool->pos.repo;
- if (!di->repo)
+ int error;
+ if ((error = datamatcher_init(&di->matcher, match, flags)) != 0)
{
di->state = di_bye;
- return;
+ return error;
}
- di->data = di->repo->repodata + di->pool->pos.repodataid;
- di->repoid = -1;
- di->repodataid = -1;
}
- di->state = di_enterrepo;
+ di->repo = repo;
+ di->keyname = keyname;
+ di->keynames[0] = keyname;
+ di->flags = flags & ~SEARCH_THISSOLVID;
+ if (!pool->nrepos)
+ {
+ di->state = di_bye;
+ return 0;
+ }
+ if (repo)
+ di->repoid = -1;
+ if (p)
+ dataiterator_jump_to_solvid(di, p);
+ else
+ {
+ di->repo = pool->repos[0];
+ di->state = di_enterrepo;
+ }
+ return 0;
+}
+
+void
+dataiterator_prepend_keyname(Dataiterator *di, Id keyname)
+{
+ int i;
+
+ if (di->nkeynames >= sizeof(di->keynames)/sizeof(*di->keynames) - 2)
+ {
+ di->state = di_bye; /* sorry */
+ return;
+ }
+ for (i = di->nkeynames + 1; i > 0; i--)
+ di->keynames[i] = di->keynames[i - 1];
+ di->keynames[0] = di->keyname = keyname;
+ di->nkeynames++;
}
void
@@ -995,20 +1017,9 @@ dataiterator_find_keyname(Dataiterator *di, Id keyname)
Repokey *keys = di->data->keys;
unsigned char *dp;
- if (!(di->flags & SEARCH_SUB))
- {
- for (keyp = di->keyp; *keyp; keyp++)
- if (keys[*keyp].name == di->keyname)
- break;
- }
- else
- {
- for (keyp++; *keyp; keyp++)
- if (keys[*keyp].name == di->keyname ||
- keys[*keyp].type == REPOKEY_TYPE_FIXARRAY ||
- keys[*keyp].type == REPOKEY_TYPE_FLEXARRAY)
- break;
- }
+ for (keyp = di->keyp; *keyp; keyp++)
+ if (keys[*keyp].name == keyname)
+ break;
if (!*keyp)
return 0;
dp = forward_to_key(di->data, *keyp, di->keyp, di->dp);
@@ -1029,13 +1040,16 @@ dataiterator_step(Dataiterator *di)
{
case di_enterrepo: di_enterrepo:
if (!(di->flags & SEARCH_THISSOLVID))
- di->solvid = di->repo->start;
+ {
+ di->solvid = di->repo->start - 1; /* reset solvid iterator */
+ goto di_nextsolvable;
+ }
/* FALLTHROUGH */
case di_entersolvable: di_entersolvable:
if (di->repodataid >= 0)
{
- di->repodataid = 0;
+ di->repodataid = 0; /* reset repodata iterator */
if (di->solvid > 0 && !(di->flags & SEARCH_NO_STORAGE_SOLVABLE) && (!di->keyname || (di->keyname >= SOLVABLE_NAME && di->keyname <= RPM_RPMDBID)))
{
di->key = solvablekeys + (di->keyname ? di->keyname - SOLVABLE_NAME : 0);
@@ -1057,12 +1071,18 @@ dataiterator_step(Dataiterator *di)
di->dp = solvid2data(di->data, di->solvid, &schema);
if (!di->dp)
goto di_nextrepodata;
+ /* reset key iterator */
di->keyp = di->data->schemadata + di->data->schemata[schema];
+ /* FALLTHROUGH */
+
+ case di_enterschema: di_enterschema:
if (di->keyname)
+ di->dp = dataiterator_find_keyname(di, di->keyname);
+ if (!di->dp || !*di->keyp)
{
- di->dp = dataiterator_find_keyname(di, di->keyname);
- if (!di->dp)
- goto di_nextrepodata;
+ if (di->kv.parent)
+ goto di_leavesub;
+ goto di_nextrepodata;
}
/* FALLTHROUGH */
@@ -1074,6 +1094,8 @@ dataiterator_step(Dataiterator *di)
goto di_nextkey;
if (di->key->type == REPOKEY_TYPE_FIXARRAY || di->key->type == REPOKEY_TYPE_FLEXARRAY)
goto di_enterarray;
+ if (di->nparents < di->nkeynames)
+ goto di_nextkey;
/* FALLTHROUGH */
case di_nextattr:
@@ -1086,17 +1108,8 @@ dataiterator_step(Dataiterator *di)
break;
case di_nextkey: di_nextkey:
- if (!di->keyname)
- {
- if (*++di->keyp)
- goto di_enterkey;
- }
- else if ((di->flags & SEARCH_SUB) != 0)
- {
- di->dp = dataiterator_find_keyname(di, di->keyname);
- if (di->dp)
- goto di_enterkey;
- }
+ if (!di->keyname && *++di->keyp)
+ goto di_enterkey;
if (di->kv.parent)
goto di_leavesub;
/* FALLTHROUGH */
@@ -1138,6 +1151,8 @@ dataiterator_step(Dataiterator *di)
return 0;
case di_enterarray: di_enterarray:
+ if (di->key->name == REPOSITORY_SOLVABLES)
+ goto di_nextkey;
di->ddp = data_read_id(di->ddp, &di->kv.num);
di->kv.eof = 0;
di->kv.entry = -1;
@@ -1149,17 +1164,21 @@ dataiterator_step(Dataiterator *di)
di->ddp = data_skip_schema(di->data, di->ddp, di->kv.id);
if (di->kv.entry == di->kv.num)
{
- if (di->keyname && di->key->name != di->keyname)
+ if (di->nparents < di->nkeynames)
+ goto di_nextkey;
+ if (!(di->flags & SEARCH_ARRAYSENTINEL))
goto di_nextkey;
di->kv.str = (char *)di->ddp;
- di->kv.eof = 1;
+ di->kv.eof = 2;
di->state = di_nextkey;
break;
}
+ if (di->kv.entry == di->kv.num - 1)
+ di->kv.eof = 1;
if (di->key->type == REPOKEY_TYPE_FLEXARRAY || !di->kv.entry)
di->ddp = data_read_id(di->ddp, &di->kv.id);
di->kv.str = (char *)di->ddp;
- if (di->keyname && di->key->name != di->keyname)
+ if (di->nparents < di->nkeynames)
goto di_entersub;
if ((di->flags & SEARCH_SUB) != 0)
di->state = di_entersub;
@@ -1178,8 +1197,8 @@ dataiterator_step(Dataiterator *di)
memset(&di->kv, 0, sizeof(di->kv));
di->kv.parent = &di->parents[di->nparents].kv;
di->nparents++;
- di->keyp--;
- goto di_nextkey;
+ di->keyname = di->keynames[di->nparents];
+ goto di_enterschema;
case di_leavesub: di_leavesub:
di->nparents--;
@@ -1188,6 +1207,7 @@ dataiterator_step(Dataiterator *di)
di->keyp = di->parents[di->nparents].keyp;
di->key = di->data->keys + *di->keyp;
di->ddp = (unsigned char *)di->kv.str;
+ di->keyname = di->keynames[di->nparents];
goto di_nextarrayelement;
/* special solvable attr handling follows */
@@ -1225,8 +1245,16 @@ dataiterator_step(Dataiterator *di)
}
if (di->matcher.match)
- if (!datamatcher_match(&di->matcher, di->data, di->key, &di->kv))
+ {
+ if (!repodata_stringify(di->pool, di->data, di->key, &di->kv, di->flags))
+ {
+ if (di->keyname && (di->key->type == REPOKEY_TYPE_FIXARRAY || di->key->type == REPOKEY_TYPE_FLEXARRAY))
+ return 1;
+ continue;
+ }
+ if (!datamatcher_match(&di->matcher, di->kv.str))
continue;
+ }
/* found something! */
return 1;
}
@@ -1244,9 +1272,10 @@ dataiterator_setpos(Dataiterator *di)
{
if (di->kv.eof)
{
- memset(&di->pool->pos, 0, sizeof(di->pool->pos));
+ pool_clear_pos(di->pool);
return;
}
+ di->pool->pos.solvid = di->solvid;
di->pool->pos.repo = di->repo;
di->pool->pos.repodataid = di->data - di->repo->repodata;
di->pool->pos.schema = di->kv.id;
@@ -1258,9 +1287,10 @@ dataiterator_setpos_parent(Dataiterator *di)
{
if (!di->kv.parent)
{
- memset(&di->pool->pos, 0, sizeof(di->pool->pos));
+ pool_clear_pos(di->pool);
return;
}
+ di->pool->pos.solvid = di->solvid;
di->pool->pos.repo = di->repo;
di->pool->pos.repodataid = di->data - di->repo->repodata;
di->pool->pos.schema = di->kv.parent->id;
@@ -1289,30 +1319,78 @@ dataiterator_skip_repo(Dataiterator *di)
}
void
-dataiterator_jump_to_solvable(Dataiterator *di, Solvable *s)
+dataiterator_jump_to_solvid(Dataiterator *di, Id solvid)
{
- di->repo = s->repo;
- di->repoid = -1;
- di->solvid = s - di->pool->solvables;
+ di->nparents = 0;
+ if (solvid == SOLVID_POS)
+ {
+ di->repo = di->pool->pos.repo;
+ if (!di->repo)
+ {
+ di->state = di_bye;
+ return;
+ }
+ di->repoid = -1;
+ di->data = di->repo->repodata + di->pool->pos.repodataid;
+ di->repodataid = -1;
+ di->solvid = di->pool->pos.solvid;
+ di->state = di_enterrepo;
+ di->flags |= SEARCH_THISSOLVID;
+ return;
+ }
+ if (solvid > 0)
+ {
+ di->repo = di->pool->solvables[solvid].repo;
+ di->repoid = -1;
+ }
+ else if (di->repoid >= 0)
+ {
+ if (!di->pool->nrepos)
+ {
+ di->state = di_bye;
+ return;
+ }
+ di->repo = di->pool->repos[0];
+ di->repoid = 0;
+ }
+ di->repodataid = 0;
+ di->solvid = solvid;
+ if (solvid)
+ di->flags |= SEARCH_THISSOLVID;
di->state = di_entersolvable;
}
void
dataiterator_jump_to_repo(Dataiterator *di, Repo *repo)
{
+ di->nparents = 0;
di->repo = repo;
di->repoid = -1;
+ di->repodataid = 0;
+ di->solvid = 0;
+ di->flags &= ~SEARCH_THISSOLVID;
di->state = di_enterrepo;
}
int
-dataiterator_match(Dataiterator *di, int flags, const void *vmatch)
+dataiterator_match(Dataiterator *di, Datamatcher *ma)
{
- Datamatcher matcher = di->matcher;
+ if (!repodata_stringify(di->pool, di->data, di->key, &di->kv, di->flags))
+ return 0;
+ return datamatcher_match(ma, di->kv.str);
+}
+
+int
+dataiterator_match_obsolete(Dataiterator *di, int flags, const void *vmatch)
+{
+ Datamatcher matcher;
+
+ if (!repodata_stringify(di->pool, di->data, di->key, &di->kv, flags))
+ return 0;
+ matcher = di->matcher;
matcher.flags = flags;
matcher.match = (void *)vmatch;
- matcher.pool = di->pool;
- return datamatcher_match(&matcher, di->data, di->key, &di->kv);
+ return datamatcher_match(&matcher, di->kv.str);
}
diff --git a/src/repodata.h b/src/repodata.h
index 79c298e..0c49953 100644
--- a/src/repodata.h
+++ b/src/repodata.h
@@ -126,7 +126,9 @@ repodata_precheck_keyname(Repodata *data, Id keyname)
/* Search key <keyname> (all keys, if keyname == 0) for Id <solvid>
* Call <callback> for each match
*/
-void repodata_search(Repodata *data, Id solvid, Id keyname, int (*callback)(void *cbdata, Solvable *s, Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata);
+void repodata_search(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata);
+int repodata_stringify(Pool *pool, Repodata *data, struct _Repokey *key, struct _KeyValue *kv, int flags);
+
/* lookup functions */
Id repodata_lookup_id(Repodata *data, Id solvid, Id keyname);