can also show the content of test.attr, yeah.
{
LongNV *nv;
unsigned int len;
- if (entry >= s->entries)
- return;
+ ensure_entry (s, entry);
if (attr.key >= s->nkeys)
return;
nv = s->attrs[entry];
/* This routine is used only when attributes are embedded into the
normal repo SOLV file. */
void
-add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, FILE *fp)
+add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, Id *idmap, unsigned maxid, FILE *fp)
{
- //Pool *pool = s->pool;
+ Pool *pool = s->pool;
//fprintf (stderr, "%s: attribute in a repo SOLV?\n", id2str (pool, name));
switch (type)
{
case TYPE_ATTR_LOCALIDS:
{
Id i;
- while ((i = read_id(fp, 0)) != 0)
- add_attr_localids_id (s, entry, name, i);
+ /* The read ID will be pool-based. */
+ while ((i = read_id(fp, maxid)) != 0)
+ {
+ if (idmap)
+ i = idmap[i];
+ add_attr_localids_id (s, entry, name, str2localid (s, id2str (pool, i), 1));
+ }
}
break;
default:
s->ent2attr[i] += start, start = s->ent2attr[i];
}
- if (fwrite (s->flat_attrs, s->attr_next_free, 1, fp) != 1)
+ if (fwrite (s->flat_attrs + 1, s->attr_next_free - 1, 1, fp) != 1)
{
perror ("write error");
exit (1);
s->attr_next_free = start;
s->flat_attrs = xmalloc (((s->attr_next_free + FLAT_ATTR_BLOCK) & ~FLAT_ATTR_BLOCK) * sizeof (s->flat_attrs[0]));
- if (fread (s->flat_attrs, s->attr_next_free, 1, fp) != 1)
+ s->flat_attrs[0] = 0;
+ if (fread (s->flat_attrs + 1, s->attr_next_free - 1, 1, fp) != 1)
{
perror ("read error");
exit (1);
unsigned int packed:1;
};
-void add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, FILE *fp);
+void add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, Id *idmap, unsigned maxid, FILE *fp);
#define get_num(ptr,val) do { \
typedef int __wrong_buf__[(1-sizeof((ptr)[0])) * (sizeof((ptr)[0])-1)];\
#include "pool.h"
#include "poolid_private.h"
#include "util.h"
+#include "attr_store_p.h"
#define IDARRAY_BLOCK 4095
}
#endif
+static int
+key_cmp (const void *pa, const void *pb)
+{
+ struct key { Id name; unsigned type; };
+ struct key *a = (struct key*)pa;
+ struct key *b = (struct key*)pb;
+ return a->name - b->name;
+}
+
+void
+repo_add_attrstore (Repo *repo, Attrstore *s)
+{
+ unsigned i;
+ Repodata *data;
+ repo->nrepodata++;
+ repo->repodata = xrealloc (repo->repodata, repo->nrepodata * sizeof (*data));
+ data = repo->repodata + repo->nrepodata - 1;
+ memset (data, 0, sizeof (*data));
+ data->s = s;
+ data->nkeys = s->nkeys;
+ if (s->nkeys)
+ {
+ data->keys = xmalloc (data->nkeys * sizeof (data->keys[0]));
+ for (i = 0; i < data->nkeys; i++)
+ {
+ data->keys[i].name = s->keys[i].name;
+ data->keys[i].type = s->keys[i].type;
+ }
+ qsort (data->keys, data->nkeys, sizeof (data->keys[0]), key_cmp);
+ }
+}
+
// EOF
#include "pooltypes.h"
#include "pool.h"
+#include "attr_store.h"
+
+typedef struct _Repodata {
+ /* Keys provided by this attribute store, sorted by name value.
+ The same keys may be provided by multiple attribute stores, but
+ then only for different solvables. I.e. the relation
+ (solvable,name) -> store
+ has to be injective. */
+ struct {
+ Id name;
+ unsigned type;
+ } *keys;
+ /* Length of names. */
+ unsigned nkeys;
+ /* The attribute store itself. */
+ Attrstore *s;
+ /* A filename where to find this attribute store, or where to store
+ it. May be NULL, in which case we can't load it on demand or store
+ into it. */
+ const char *name;
+ /* The SHA1 checksum of the file. */
+ unsigned char checksum[20];
+} Repodata;
typedef struct _Repo {
const char *name;
Offset lastoff;
Id *rpmdbid;
+
+ /* The attribute stores we know about. */
+ Repodata *repodata;
+ /* Number of attribute stores.. */
+ unsigned nrepodata;
} Repo;
extern Repo *repo_create(Pool *pool, const char *name);
extern Offset repo_reserve_ids(Repo *repo, Offset olddeps, int num);
extern Offset repo_fix_legacy(Repo *repo, Offset provides, Offset supplements);
+extern void repo_add_attrstore (Repo *repo, Attrstore *s);
+
static inline const char *repo_name(const Repo *repo)
{
return repo->name;
#include "repo_solv.h"
#include "util.h"
+#include "attr_store_p.h"
#define INTERESTED_START SOLVABLE_NAME
#define INTERESTED_END SOLVABLE_FRESHENS
Id size;
};
-
// ----------------------------------------------
/*
int i, l;
unsigned int numid, numrel, numsolv;
unsigned int numkeys, numschemata, numinfo;
+ Attrstore *embedded_store = 0;
int type;
Offset sizeid;
case TYPE_ID:
read_id(fp, numid + numrel); /* just check Id */
break;
+ case TYPE_ATTR_CHUNK:
+ read_id(fp, 0);
+ /* Fallthrough. */
+ case TYPE_ATTR_INT:
+ read_id(fp, 0);
+ break;
case TYPE_U32:
read_u32(fp);
break;
+ case TYPE_ATTR_STRING:
case TYPE_STR:
while(read_u8(fp) != 0)
;
while ((read_u8(fp) & 0xc0) != 0)
;
break;
+ case TYPE_ATTR_INTLIST:
+ case TYPE_ATTR_LOCALIDS:
+ while (read_id(fp, 0) != 0)
+ ;
+ break;
default:
pool_debug(pool, SAT_FATAL, "unknown type %d\n", type);
exit(0);
}
/******* Part 6: packed sizes (optional) ****************************/
+ char *exists = 0;
if ((solvflags & SOLV_FLAG_PACKEDSIZES) != 0)
{
+ exists = xmalloc (numsolv);
for (i = 0; i < numsolv; i++)
- read_id(fp, 0);
+ exists[i] = read_id(fp, 0) != 0;
}
/******* Part 7: item data *******************************************/
else if (id == SOLVABLE_FRESHENS)
s->freshens = ido;
break;
+ case TYPE_ATTR_INT:
+ case TYPE_ATTR_CHUNK:
+ case TYPE_ATTR_STRING:
+ case TYPE_ATTR_INTLIST:
+ case TYPE_ATTR_LOCALIDS:
+ if (!embedded_store)
+ embedded_store = new_store (pool);
+ add_attr_from_file (embedded_store, i, id, type, idmap, numid, fp);
+ break;
}
}
}
}
for (i = 0; i < numsolv; i++, s++)
{
+ if (exists && !exists[i])
+ continue;
Id *keyp = schemadata + schemata[read_id(fp, numschemata)];
while ((key = *keyp++) != 0)
{
POOL_DEBUG(SAT_DEBUG_STATS," %s\n", dep2str(pool, repo->idarraydata[ido]));
#endif
break;
+ case TYPE_ATTR_INT:
+ case TYPE_ATTR_CHUNK:
+ case TYPE_ATTR_STRING:
+ case TYPE_ATTR_INTLIST:
+ case TYPE_ATTR_LOCALIDS:
+ if (!embedded_store)
+ embedded_store = new_store (pool);
+ add_attr_from_file (embedded_store, i, id, keys[key].type, idmap, numid, fp);
+ break;
}
}
}
+ xfree(exists);
+ if (embedded_store)
+ {
+ attr_store_pack (embedded_store);
+ repo_add_attrstore (repo, embedded_store);
+ }
xfree(idmap);
xfree(schemata);
xfree(schemadata);
#include "pool.h"
#include "repo_solv.h"
+#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);
+ if (!val)
+ break;
+ fprintf (stdout, " %d", val);
+ }
+ 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:
+ 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);
+ }
+}
static void
printids(Repo *repo, char *kind, Offset ido)
if (s->repo != repo)
continue;
printf("\n");
- printf("solvable %d:\n", n++);
- printf("name: %s %s %s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
+ printf("solvable %d:\n", n);
+ 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)
printf("vendor: %s\n", id2str(pool, s->vendor));
printids(repo, "provides", s->provides);
printids(repo, "supplements", s->supplements);
printids(repo, "enhances", s->enhances);
printids(repo, "freshens", s->freshens);
+ dump_attrs (repo, n - 1);
+ n++;
}
pool_free(pool);
exit(0);