}
void
-repo_search(Repo *repo, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
+repo_search(Repo *repo, Id p, Id keyname, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
{
struct matchdata md;
md.flags = flags;
md.callback = callback;
md.callback_data = cbdata;
- repo_search_md(repo, p, key, &md);
+ repo_search_md(repo, p, keyname, &md);
}
const char *
#endif
// EOF
+/*
+vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
+*/
#define SEARCH_NOCASE (1<<8)
#define SEARCH_NO_STORAGE_SOLVABLE (1<<9)
+/* Internal */
+#define __SEARCH_ONESOLVABLE (1 << 31)
+
Repodata *repo_add_repodata(Repo *repo);
void repo_search(Repo *repo, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata);
/* generic attribute lookup */
int repo_lookup(Solvable *s, Id key, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata);
+typedef struct _Dataiterator
+{
+ Repodata *data;
+ Id *keyp;
+ unsigned char *nextkeydp;
+ unsigned char *dp;
+ Repokey *key;
+ Repo *repo;
+ const char *match;
+ Id solvid;
+ Id keyname;
+ unsigned flags;
+ KeyValue kv;
+} Dataiterator;
+
+/* Use these like:
+ Dataiterator di;
+ dataiterator_init(&di, repo, 0, 0, "bla", SEARCH_SUBSTRING);
+ while (dataiterator_step(&di))
+ dosomething(di.solvid, di.key, di.kv); */
+void dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname,
+ const char *match, int flags);
+int dataiterator_step(Dataiterator *di);
void repo_set_id(Repo *repo, Id p, Id keyname, Id id);
void repo_set_num(Repo *repo, Id p, Id keyname, Id num);
#define _GNU_SOURCE
#include <string.h>
+#include <fnmatch.h>
#include <stdio.h>
#include <stdlib.h>
}
}
+static void
+dataiterator_newdata(Dataiterator *di)
+{
+ Id keyname = di->keyname;
+ Repodata *data = di->data;
+ di->nextkeydp = 0;
+
+ if (data->state == REPODATA_STUB)
+ {
+ if (keyname)
+ {
+ int j;
+ for (j = 1; j < data->nkeys; j++)
+ if (keyname == data->keys[j].name)
+ break;
+ if (j == data->nkeys)
+ return;
+ }
+ /* load it */
+ if (data->loadcallback)
+ data->loadcallback(data);
+ else
+ data->state = REPODATA_ERROR;
+ }
+ if (data->state == REPODATA_ERROR)
+ return;
+
+ Id schema;
+ unsigned char *dp = data->incoredata + data->incoreoffset[di->solvid - data->start];
+ dp = data_read_id(dp, &schema);
+ Id *keyp = data->schemadata + data->schemata[schema];
+ if (keyname)
+ {
+ Id k, *kp;
+ /* search in a specific key */
+ for (kp = keyp; (k = *kp++) != 0; )
+ if (data->keys[k].name == keyname)
+ break;
+ if (k == 0)
+ return;
+ dp = forward_to_key(data, k, schema, dp);
+ if (!dp)
+ return;
+ keyp = kp - 1;
+ }
+ Id keyid = *keyp++;
+ if (!keyid)
+ return;
+
+ di->data = data;
+ di->key = di->data->keys + keyid;
+ di->keyp = keyp;
+ di->dp = 0;
+
+ di->nextkeydp = dp;
+ di->dp = get_data(di->data, di->key, &di->nextkeydp);
+ di->kv.eof = 0;
+}
+
+void
+dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname,
+ const char *match, int flags)
+{
+ di->flags = flags;
+ if (p)
+ {
+ di->solvid = p;
+ di->flags |= __SEARCH_ONESOLVABLE;
+ di->data = repo->repodata - 1;
+ }
+ else
+ {
+ di->solvid = repo->start - 1;
+ di->data = repo->repodata + repo->nrepodata - 1;
+ }
+ di->match = match;
+ di->keyname = keyname;
+ static Id zeroid = 0;
+ di->keyp = &zeroid;
+ di->kv.eof = 1;
+ di->repo = repo;
+}
+
+/* FIXME factor and merge with repo_matchvalue */
+static int
+dataiterator_match(Dataiterator *di, KeyValue *kv)
+{
+ int flags = di->flags;
+
+ if ((flags & SEARCH_STRINGMASK) != 0)
+ {
+ switch (di->key->type)
+ {
+ case TYPE_ID:
+ case TYPE_IDARRAY:
+ if (di->data && di->data->localpool)
+ kv->str = stringpool_id2str(&di->data->spool, kv->id);
+ else
+ kv->str = id2str(di->repo->pool, kv->id);
+ break;
+ case TYPE_STR:
+ break;
+ default:
+ return 0;
+ }
+ switch ((flags & SEARCH_STRINGMASK))
+ {
+ case SEARCH_SUBSTRING:
+ if (flags & SEARCH_NOCASE)
+ {
+ if (!strcasestr(kv->str, di->match))
+ return 0;
+ }
+ else
+ {
+ if (!strstr(kv->str, di->match))
+ return 0;
+ }
+ break;
+ case SEARCH_STRING:
+ if (flags & SEARCH_NOCASE)
+ {
+ if (strcasecmp(di->match, kv->str))
+ return 0;
+ }
+ else
+ {
+ if (strcmp(di->match, kv->str))
+ return 0;
+ }
+ break;
+ case SEARCH_GLOB:
+ if (fnmatch(di->match, kv->str, (flags & SEARCH_NOCASE) ? FNM_CASEFOLD : 0))
+ return 0;
+ break;
+#if 0
+ case SEARCH_REGEX:
+ if (regexec(&di->regexp, kv->str, 0, NULL, 0))
+ return 0;
+#endif
+ default:
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int
+dataiterator_step(Dataiterator *di)
+{
+ /* FIXME add solvable data */
+ while (1)
+ {
+ if (di->kv.eof)
+ di->dp = 0;
+ else
+ di->dp = data_fetch(di->dp, &di->kv, di->key);
+
+ while (!di->dp)
+ {
+ Id keyid;
+ if (di->keyname || !(keyid = *di->keyp++))
+ {
+ while (1)
+ {
+ Repo *repo = di->repo;
+ Repodata *data = ++di->data;
+ if (data >= repo->repodata + repo->nrepodata)
+ {
+ if (di->flags & __SEARCH_ONESOLVABLE)
+ return 0;
+ while (++di->solvid < repo->end)
+ if (repo->pool->solvables[di->solvid].repo == repo)
+ break;
+ if (di->solvid >= repo->end)
+ return 0;
+ di->data = repo->repodata - 1;
+ continue;
+ }
+ if (di->solvid >= data->start && di->solvid < data->end)
+ {
+ dataiterator_newdata(di);
+ if (di->nextkeydp)
+ break;
+ }
+ }
+ }
+ else
+ {
+ di->key = di->data->keys + keyid;
+ di->dp = get_data(di->data, di->key, &di->nextkeydp);
+ }
+ di->dp = data_fetch(di->dp, &di->kv, di->key);
+ }
+ if (!di->match
+ || dataiterator_match(di, &di->kv))
+ break;
+ }
+ return 1;
+}
+
void
repodata_init(Repodata *data, Repo *repo, int localpool)
{
}
}
}
+/*
+vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
+*/
#include "pool.h"
#include "repo_solv.h"
-#if 0
-#include "attr_store.h"
-#include "attr_store_p.h"
-
-static void
-dump_attrs_1 (Attrstore *s, unsigned int entry)
-{
- attr_iterator ai;
- FOR_ATTRS (s, entry, &ai)
- {
- fprintf (stdout, "%s:", id2str (s->pool, ai.name));
- switch (ai.type)
- {
- case TYPE_ATTR_INT:
- fprintf (stdout, "int %u\n", ai.as_int);
- break;
- case TYPE_ATTR_CHUNK:
- {
- const char *str = attr_retrieve_blob (s, ai.as_chunk[0], ai.as_chunk[1]);
- if (str)
- fprintf (stdout, "blob %s\n", str);
- else
- fprintf (stdout, "blob %u+%u\n", ai.as_chunk[0], ai.as_chunk[1]);
- }
- break;
- case TYPE_ATTR_STRING:
- fprintf (stdout, "str %s\n", ai.as_string);
- break;
- case TYPE_ATTR_INTLIST:
- {
- fprintf (stdout, "lint\n ");
- while (1)
- {
- int val;
- get_num (ai.as_numlist, val);
- fprintf (stdout, " %d", (val & 63) | ((val >> 1) & ~63));
- if (!(val & 64))
- break;
- }
- fprintf (stdout, "\n");
- break;
- }
- case TYPE_ATTR_LOCALIDS:
- {
- fprintf (stdout, "lids");
- while (1)
- {
- Id val;
- get_num (ai.as_numlist, val);
- if (!val)
- break;
- fprintf (stdout, "\n %s(%d)", localid2str (s, val), val);
- }
- fprintf (stdout, "\n");
- break;
- }
- default:
- fprintf (stdout, "\n");
- break;
- }
- }
-}
-
-static void
-dump_attrs (Repo *repo, unsigned int entry)
-{
- unsigned i;
- for (i = 0; i < repo->nrepodata; i++)
- {
- Attrstore *s = repo->repodata[i].s;
- if (s && entry < s->entries)
- dump_attrs_1 (s, entry);
- }
-}
-#endif
static void
dump_repodata (Repo *repo)
void
dump_repoattrs(Repo *repo, Id p)
{
+#if 1
repo_search(repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE, dump_repoattrs_cb, 0);
+#else
+ Dataiterator di;
+ dataiterator_init(&di, repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE);
+ while (dataiterator_step(&di))
+ dump_repoattrs_cb(0, repo->pool->solvables + di.solvid, di.data, di.key,
+ &di.kv);
+#endif
}
+#if 0
void
dump_some_attrs(Repo *repo, Solvable *s)
{
printf (" XXX %d %d %u %s\n", medianr, downloadsize, time, summary);
}
+#endif
static FILE *
exit(0);
}
+#if 0
+static void
+tryme (Repo *repo, Id p, Id keyname, const char *match, int flags)
+{
+ Dataiterator di;
+ dataiterator_init(&di, repo, p, keyname, match, flags);
+ while (dataiterator_step(&di))
+ {
+ switch (di.key->type)
+ {
+ case TYPE_ID:
+ case TYPE_IDARRAY:
+ if (di.data && di.data->localpool)
+ di.kv.str = stringpool_id2str(&di.data->spool, di.kv.id);
+ else
+ di.kv.str = id2str(repo->pool, di.kv.id);
+ break;
+ case TYPE_STR:
+ case TYPE_DIRSTRARRAY:
+ break;
+ default:
+ di.kv.str = 0;
+ }
+ fprintf (stdout, "found: %d:%s %d %s %d %d %d\n",
+ di.solvid,
+ id2str(repo->pool, di.key->name),
+ di.kv.id,
+ di.kv.str, di.kv.num, di.kv.num2, di.kv.eof);
+ }
+}
+#endif
int main(int argc, char **argv)
{
dump_attrs (repo, n - 1);
#endif
dump_repoattrs(repo, i);
-#if 1
+#if 0
dump_some_attrs(repo, s);
#endif
n++;
}
+#if 0
+ tryme(repo, 0, str2id (repo->pool, "medianr", 0), 0, 0);
+ printf("\n");
+ tryme(repo, 0, 0, 0, 0);
+ printf("\n");
+ tryme(repo, 0, 0, "*y*e*", SEARCH_GLOB);
+#endif
pool_free(pool);
exit(0);
}