%endif
BuildRequires: cmake rpm-devel gcc-c++ ruby-devel swig perl python-devel
# the testsuite uses the check framework
-BuildRequires: check check-devel
+BuildRequires: check-devel
Summary: A new approach to package dependency solving
%description
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"),
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 */
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"),
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;
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)
typedef struct _Repopos {
struct _Repo *repo;
+ Id solvid;
Id repodataid;
Id schema;
Id dp;
*/
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;
{
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;
}
}
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;
}
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);
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.. */
#define SEARCH_NEXT_KEY 1
#define SEARCH_NEXT_SOLVABLE 2
#define SEARCH_STOP 3
+#define SEARCH_ENTERSUB -1
typedef struct _KeyValue {
Id id;
#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)
#else
typedef struct _Datamatcher {
- Pool *pool;
int flags;
void *match;
int error;
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);
}
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;
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;
}
* 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;
/* 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;
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;
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)
{
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;
}
}
-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;
ma->flags = (flags & ~SEARCH_STRINGMASK) | SEARCH_ERROR;
}
}
+ return ma->error;
}
void
}
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:
di_enterrepo,
di_entersolvable,
di_enterrepodata,
+ di_enterschema,
di_enterkey,
di_nextattr,
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
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);
{
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);
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 */
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:
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 */
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;
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;
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--;
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 */
}
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;
}
{
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;
{
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;
}
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);
}
/* 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);
static int dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv);
static void
-dump_repodata (Repo *repo)
+dump_repodata(Repo *repo)
{
unsigned i;
Repodata *data;
if (repo->nrepodata == 0)
return;
- for (i = 0; i < 32; i++)
- if (repo->rpmdbcookie[i])
- break;
- if (i < 32)
- {
- printf("rpmdb cookie: ");
- for (i = 0; i < 32; i++)
- printf("%02x", repo->rpmdbcookie[i]);
- printf("\n");
- }
printf("repo contains %d repodata sections:\n", repo->nrepodata);
for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
{
if (data->dirpool.ndirs)
printf(" localpool has %d directories\n", data->dirpool.ndirs);
printf("\n");
- repodata_search(data, SOLVID_META, 0, dump_repoattrs_cb, 0);
+ repodata_search(data, SOLVID_META, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB, dump_repoattrs_cb, 0);
}
printf("\n");
}
+#if 0
static void
printids(Repo *repo, char *kind, Offset ido)
{
while((id = *ids++) != 0)
printf(" %s\n", dep2str(pool, id));
}
+#endif
int
dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
void
dump_repoattrs(Repo *repo, Id p)
{
-#if 1
- repo_search(repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE, dump_repoattrs_cb, 0);
+#if 0
+ repo_search(repo, p, 0, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB, dump_repoattrs_cb, 0);
#else
Dataiterator di;
- dataiterator_init(&di, repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE);
+ dataiterator_init(&di, repo->pool, repo, p, 0, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB);
while (dataiterator_step(&di))
dump_attr(repo, di.data, di.key, &di.kv);
#endif
continue;
printf("\n");
printf("solvable %d (%d):\n", n, i);
+#if 0
if (s->name || s->evr || s->arch)
printf("name: %s %s %s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
if (s->vendor)
#if 0
dump_attrs (repo, n - 1);
#endif
+#endif
dump_repoattrs(repo, i);
#if 0
dump_some_attrs(repo, s);
n++;
}
#if 0
- for (i = 0; i < repo->nextra; i++)
- {
- printf("\nextra %d:\n", i);
- Dataiterator di;
- dataiterator_init(&di, repo, -1 - i, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
- while (dataiterator_step(&di))
- dump_attr(repo, di.data, di.key, &di.kv);
- }
-#endif
-#if 0
tryme(repo, 0, SOLVABLE_MEDIANR, 0, 0);
printf("\n");
tryme(repo, 0, 0, 0, 0);
#if 0
printf ("\nSearchresults:\n");
Dataiterator di;
- dataiterator_init(&di, pool->repos[0], 0, 0, "3", SEARCH_EXTRA | SEARCH_SUBSTRING | SEARCH_ALL_REPOS | SEARCH_FILES);
+ dataiterator_init(&di, pool, 0, 0, 0, "3", SEARCH_SUB | SEARCH_SUBSTRING | SEARCH_FILES);
//int count = 0;
while (dataiterator_step(&di))
{
#define TAG_DIRNAMES 1118
#define TAG_PAYLOADFORMAT 1124
#define TAG_PATCHESNAME 1133
+#define TAG_FILECOLORS 1140
#define TAG_SUGGESTSNAME 1156
#define TAG_SUGGESTSVERSION 1157
#define TAG_SUGGESTSFLAGS 1158
case REPOKEY_TYPE_FLEXARRAY:
if (kv->entry == 0)
{
- if (!kv->eof)
+ if (kv->eof != 2)
*cbdata->sp++ = 0; /* mark start */
}
else
sp--;
cbdata->subschemata = sat_extend(cbdata->subschemata, cbdata->nsubschemata, 1, sizeof(Id), SCHEMATA_BLOCK);
cbdata->subschemata[cbdata->nsubschemata++] = addschema(cbdata, sp);
- cbdata->sp = kv->eof ? sp - 1: sp;
+ cbdata->sp = kv->eof == 2 ? sp - 1: sp;
}
break;
default:
case REPOKEY_TYPE_FLEXARRAY:
if (!kv->entry)
data_addid(xd, kv->num);
- if (!kv->eof)
+ if (kv->eof != 2)
data_addid(xd, cbdata->subschemata[cbdata->current_sub++]);
if (xd == cbdata->extdata + 0 && !kv->parent && !cbdata->doingsolvables)
{
/* collect all other data from all repodatas */
/* XXX: merge arrays of equal keys? */
for (j = 0, data = repo->repodata; j < repo->nrepodata; j++, data++)
- repodata_search(data, SOLVID_META, 0, repo_write_cb_needed, &cbdata);
+ repodata_search(data, SOLVID_META, 0, SEARCH_SUB|SEARCH_ARRAYSENTINEL, repo_write_cb_needed, &cbdata);
sp = cbdata.sp;
/* add solvables if needed */
if (repo->nsolvables)
continue;
if (i < data->start || i >= data->end)
continue;
- repodata_search(data, i, 0, repo_write_cb_needed, &cbdata);
+ repodata_search(data, i, 0, SEARCH_SUB|SEARCH_ARRAYSENTINEL, repo_write_cb_needed, &cbdata);
needid = cbdata.needid;
}
}
#if 1
for (j = 0, data = repo->repodata; j < repo->nrepodata; j++, data++)
- repodata_search(data, SOLVID_META, 0, repo_write_cb_adddata, &cbdata);
+ repodata_search(data, SOLVID_META, 0, SEARCH_SUB|SEARCH_ARRAYSENTINEL, repo_write_cb_adddata, &cbdata);
#endif
if (xd->len - cbdata.lastlen > cbdata.maxdata)
continue;
if (i < data->start || i >= data->end)
continue;
- repodata_search(data, i, 0, repo_write_cb_adddata, &cbdata);
+ repodata_search(data, i, 0, SEARCH_SUB|SEARCH_ARRAYSENTINEL, repo_write_cb_adddata, &cbdata);
}
}
if (xd->len - cbdata.lastlen > cbdata.maxdata)