diff options
author | Michael Schroeder <mls@suse.de> | 2008-10-20 10:21:46 +0000 |
---|---|---|
committer | Michael Schroeder <mls@suse.de> | 2008-10-20 10:21:46 +0000 |
commit | f8393a70607c00966b2050029ef35a7fb70e122a (patch) | |
tree | 2523a78012fae08aecba49cb933b54143a8937a9 /src | |
parent | 64a8733d32ea62fff88a81cec5cf0aa13224a32c (diff) | |
download | libsolv-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.h | 13 | ||||
-rw-r--r-- | src/pool.c | 8 | ||||
-rw-r--r-- | src/pool.h | 4 | ||||
-rw-r--r-- | src/repo.c | 13 | ||||
-rw-r--r-- | src/repo.h | 26 | ||||
-rw-r--r-- | src/repo_solv.c | 6 | ||||
-rw-r--r-- | src/repodata.c | 326 | ||||
-rw-r--r-- | src/repodata.h | 4 |
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"), @@ -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) @@ -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; @@ -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); @@ -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); |