From: Michael Matz Date: Sun, 10 Feb 2008 06:09:37 +0000 (+0000) Subject: Support for generating separate sub files and bugfixes in the reader X-Git-Tag: BASE-SuSE-Code-12_1-Branch~308^2~647 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc242b8aa0fe56ec3e06e46bee698f5184d18f76;p=thirdparty%2Flibsolv.git Support for generating separate sub files and bugfixes in the reader side. Try "susetags2solv -as" to play (e.g. with dumpsolv). --- diff --git a/src/pool.h b/src/pool.h index 7b6a11af..7c702c64 100644 --- a/src/pool.h +++ b/src/pool.h @@ -69,6 +69,7 @@ extern "C" { //----------------------------------------------- struct _Repo; +struct _Repodata; struct _Pool { struct _Stringpool ss; @@ -113,6 +114,10 @@ struct _Pool { int debugmask; void (*debugcallback)(struct _Pool *, void *data, int type, const char *str); void *debugcallbackdata; + + /* load callback */ + FILE * (*loadcallback)(struct _Pool *, struct _Repodata *, void *); + void *loadcallbackdata; }; #define SAT_FATAL (1<<0) @@ -253,6 +258,12 @@ static inline void pool_setdebugmask(Pool *pool, int mask) pool->debugmask = mask; } +static inline void pool_setloadcallback(Pool *pool, FILE *(*cb)(struct _Pool *, struct _Repodata *, void *), void *loadcbdata) +{ + pool->loadcallback = cb; + pool->loadcallbackdata = loadcbdata; +} + /* loop over all providers of d */ #define FOR_PROVIDES(v, vp, d) \ for (vp = pool_whatprovides(pool, d) ; (v = *vp++) != 0; ) diff --git a/src/repo.c b/src/repo.c index 2a2eb4c5..58fed3c1 100644 --- a/src/repo.c +++ b/src/repo.c @@ -818,7 +818,8 @@ repo_add_repodata(Repo *repo) return data; } -static Repodata *findrepodata(Repo *repo, Id p, Id keyname) +static Repodata * +findrepodata(Repo *repo, Id p, Id keyname) { int i; Repodata *data; diff --git a/src/repo_solv.c b/src/repo_solv.c index 2c613401..8fae8dc1 100644 --- a/src/repo_solv.c +++ b/src/repo_solv.c @@ -371,8 +371,9 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned skip_item(maindata, TYPE_IDVALUEARRAY, numid, numrel); break; } - ida = sat_calloc(keys[key].size, sizeof(Id)); - ide = read_idarray(maindata, 0, 0, ida, ida + keys[key].size, 0); + /* read_idarray writes a terminating 0, that's why the + 1 */ + ida = sat_calloc(keys[key].size + 1, sizeof(Id)); + ide = read_idarray(maindata, 0, 0, ida, ida + keys[key].size + 1, 0); n = ide - ida - 1; if (n & 1) { @@ -409,9 +410,7 @@ parse_repodata(Repodata *maindata, Id *keyp, Repokey *keys, Id *idmap, unsigned unsigned len = sizeof (buf); char *filename = buf; read_str(maindata, &filename, &len); -#if 0 data->location = strdup(filename); -#endif if (filename != buf) free(filename); } @@ -608,9 +607,9 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent) pool_debug(pool, SAT_ERROR, "relations are forbidden in a store\n"); return SOLV_ERROR_CORRUPT; } - if (numsolv) + if (parent->end - parent->start != numsolv) { - pool_debug(pool, SAT_ERROR, "solvables are forbidden in a store\n"); + pool_debug(pool, SAT_ERROR, "unequal number of solvables in a store\n"); return SOLV_ERROR_CORRUPT; } if (numinfo) @@ -638,6 +637,7 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent) spool = &pool->ss; else { + data.localpool = 1; spool = &data.spool; spool->stringspace = sat_malloc(7); strcpy(spool->stringspace, ""); @@ -703,12 +703,12 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent) { /* no shared pool, thus no idmap and no unification */ idmap = 0; - sp += 7; - if (*sp) + if (0 && *sp) { pool_debug(pool, SAT_ERROR, "store strings don't start with ''\n"); return SOLV_ERROR_CORRUPT; } + spool->nstrings = numid; str[0] = 0; for (i = 1; i < spool->nstrings; i++) { @@ -717,9 +717,10 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent) pool_debug(pool, SAT_ERROR, "not enough strings\n"); return SOLV_ERROR_OVERFLOW; } - str[i] = sp - strsp; + str[i] = sp - spool->stringspace; sp += strlen(sp) + 1; } + spool->sstrings = sp - spool->stringspace; } else { @@ -905,9 +906,15 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent) id = read_id(&data, numid); if (idmap) id = idmap[id]; + else if (parent) + id = str2id(pool, stringpool_id2str(spool, id), 1); keys[i].name = id; keys[i].type = read_id(&data, 0); keys[i].size = read_id(&data, 0); +#if 0 + fprintf (stderr, "key %d %s %d %d\n", i, id2str(pool,id), keys[i].type, + keys[i].size); +#endif if (solvversion >= SOLV_VERSION_5) { keys[i].storage = read_id(&data, 0); @@ -979,6 +986,13 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent) { schemata[i] = schemadatap - schemadata; schemadatap = read_idarray(&data, numid, 0, schemadatap, schemadataend, 0); +#if 0 + Id *sp = schemadata + schemata[i]; + fprintf (stderr, "schema %d:", i); + for (; *sp; sp++) + fprintf (stderr, " %d", *sp); + fprintf (stderr, "\n"); +#endif } data.schemata = schemata; data.nschemata = numschemata; @@ -1046,12 +1060,25 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent) } /* read solvables */ - if (numsolv) + if (parent) + { + data.start = parent->start; + data.end = parent->end; + s = pool_id2solvable(pool, data.start); + } + else if (numsolv) { s = pool_id2solvable(pool, repo_add_solvable_block(repo, numsolv)); /* store start and end of our id block */ data.start = s - pool->solvables; data.end = data.start + numsolv; + /* In case we have subfiles, make them refer to our part of the + repository now. */ + for (i = 0; i < repo->nrepodata; i++) + { + repo->repodata[i].start = data.start; + repo->repodata[i].end = data.end; + } } else s = 0; @@ -1365,14 +1392,14 @@ static void repodata_load_solv(Repodata *data) { FILE *fp; -#if 0 +#if 1 Pool *pool = data->repo->pool; if (!pool->loadcallback) { data->state = REPODATA_ERROR; return; } - fp = pool->loadcallback(pool->loadcallback_data, pool, data); + fp = pool->loadcallback(pool, data, pool->loadcallbackdata); #else fp = 0; #endif diff --git a/src/repodata.c b/src/repodata.c index a777bb6b..6fb94599 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -399,6 +399,21 @@ get_data(Repodata *data, Repokey *key, unsigned char **dpp) return 0; } +static inline int +maybe_load_repodata(Repodata *data) +{ + if (data->state == REPODATA_STUB) + { + if (data->loadcallback) + data->loadcallback(data); + else + data->state = REPODATA_ERROR; + } + if (data->state == REPODATA_AVAILABLE) + return 1; + data->state = REPODATA_ERROR; + return 0; +} const char * repodata_lookup_str(Repodata *data, Id entry, Id keyid) @@ -408,6 +423,9 @@ repodata_lookup_str(Repodata *data, Id entry, Id keyid) Id id, *keyp; unsigned char *dp; + if (!maybe_load_repodata (data)) + return 0; + dp = data->incoredata + data->incoreoffset[entry]; dp = data_read_id(dp, &schema); /* make sure the schema of this solvable contains the key */ @@ -440,6 +458,10 @@ repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value) unsigned char *dp; *value = 0; + + if (!maybe_load_repodata (data)) + return 0; + dp = data->incoredata + data->incoreoffset[entry]; dp = data_read_id(dp, &schema); /* make sure the schema of this solvable contains the key */ @@ -473,6 +495,9 @@ repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbda int stop; KeyValue kv; + if (!maybe_load_repodata (data)) + return; + dp = data->incoredata + data->incoreoffset[entry]; dp = data_read_id(dp, &schema); keyp = data->schemadata + data->schemata[schema]; diff --git a/src/repodata.h b/src/repodata.h index c695d789..c9de915e 100644 --- a/src/repodata.h +++ b/src/repodata.h @@ -39,9 +39,17 @@ typedef struct _Attrblobpage typedef struct _Repodata { struct _Repo *repo; /* back pointer to repo */ +#define REPODATA_AVAILABLE 0 +#define REPODATA_STUB 1 +#define REPODATA_ERROR 2 +#define REPODATA_STORE 3 int state; /* available, stub or error */ void (*loadcallback)(struct _Repodata *); + char *location; /* E.g. filename or the like */ + char *checksum; /* Checksum of the file */ + unsigned nchecksum; /* Length of the checksum */ + unsigned checksumtype; /* Type of checksum */ int start; /* start of solvables this repodata is valid for */ int end; /* last solvable + 1 of this repodata */ @@ -94,10 +102,6 @@ typedef struct _Repodata { } Repodata; -#define REPODATA_AVAILABLE 0 -#define REPODATA_STUB 1 -#define REPODATA_ERROR 2 -#define REPODATA_STORE 3 void repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbdata, Solvable *s, Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata); const char *repodata_lookup_str(Repodata *data, Id entry, Id keyid); diff --git a/tools/content2solv.c b/tools/content2solv.c index 5c5af58f..c29958fc 100644 --- a/tools/content2solv.c +++ b/tools/content2solv.c @@ -23,7 +23,7 @@ main(int argc, char **argv) Pool *pool = pool_create(); Repo *repo = repo_create(pool, ""); repo_add_content(repo, stdin); - repo_write(repo, stdout, 0, 0); + repo_write(repo, stdout, 0, 0, 0, 0); pool_free(pool); return 0; } diff --git a/tools/dumpsolv.c b/tools/dumpsolv.c index 100f3cb4..631e529e 100644 --- a/tools/dumpsolv.c +++ b/tools/dumpsolv.c @@ -86,6 +86,7 @@ dump_attrs (Repo *repo, unsigned int entry) dump_attrs_1 (s, entry); } } +#endif static void dump_repodata (Repo *repo) @@ -94,18 +95,17 @@ dump_repodata (Repo *repo) Repodata *data; if (repo->nrepodata == 0) return; - printf("repo refers to %d attribute stores:\n", repo->nrepodata); + printf("repo refers to %d subfiles:\n", repo->nrepodata); for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++) { unsigned int j; printf("%s has %d keys", data->location ? data->location : "**EMBED**", data->nkeys); - for (j = 0; j < data->nkeys; j++) + for (j = 1; j < data->nkeys; j++) printf("\n %s", id2str(repo->pool, data->keys[j].name)); printf("\n"); } printf("\n"); } -#endif static void printids(Repo *repo, char *kind, Offset ido) @@ -189,6 +189,34 @@ dump_repoattrs(Repo *repo, Id p) } } +void +dump_some_attrs(Repo *repo, Solvable *s) +{ + Id name = str2id (repo->pool, "summary", 0); + const char *summary = 0; + unsigned int medianr = -1, downloadsize = -1; + unsigned int time = -1; + if (name) + summary = repo_lookup_str (s, name); + if ((name = str2id (repo->pool, "medianr", 0))) + medianr = repo_lookup_num (s, name); + if ((name = str2id (repo->pool, "downloadsize", 0))) + downloadsize = repo_lookup_num (s, name); + if ((name = str2id (repo->pool, "time", 0))) + time = repo_lookup_num (s, name); + + printf (" XXX %d %d %u %s\n", medianr, downloadsize, time, summary); +} + +static FILE * +loadcallback (Pool *pool, Repodata *data, void *vdata) +{ + FILE *fp; + fprintf (stderr, "Loading SOLV file %s\n", data->location); + fp = fopen ("test.attr", "r"); + return fp; +} + int main(int argc, char **argv) { Repo *repo; @@ -206,13 +234,12 @@ int main(int argc, char **argv) } pool = pool_create(); pool_setdebuglevel(pool, 1); + pool_setloadcallback(pool, loadcallback, 0); repo = repo_create(pool, argc != 1 ? argv[1] : ""); if (repo_add_solv(repo, stdin)) printf("could not read repository\n"); -#if 0 dump_repodata (repo); -#endif printf("repo contains %d solvables\n", repo->nsolvables); for (i = repo->start, n = 1; i < repo->end; i++) { @@ -238,6 +265,9 @@ int main(int argc, char **argv) dump_attrs (repo, n - 1); #endif dump_repoattrs(repo, i); +#if 1 + dump_some_attrs(repo, s); +#endif n++; } pool_free(pool); diff --git a/tools/helix2solv.c b/tools/helix2solv.c index 9c3a618b..764f1955 100644 --- a/tools/helix2solv.c +++ b/tools/helix2solv.c @@ -31,7 +31,7 @@ main(int argc, char **argv) Pool *pool = pool_create(); Repo *repo = repo_create(pool, ""); repo_add_helix(repo, stdin); - repo_write(repo, stdout, 0, 0); + repo_write(repo, stdout, 0, 0, 0, 0); pool_free(pool); exit(0); } diff --git a/tools/mergesolv.c b/tools/mergesolv.c index b3a17959..c8d6f62d 100644 --- a/tools/mergesolv.c +++ b/tools/mergesolv.c @@ -82,7 +82,7 @@ main(int argc, char **argv) } create_filter(pool); - repo_write(repo, stdout, keyfilter, 0); + repo_write(repo, stdout, keyfilter, 0, 0, 0); pool_free(pool); return 0; diff --git a/tools/patchxml2solv.c b/tools/patchxml2solv.c index 30a359dd..68b478e9 100644 --- a/tools/patchxml2solv.c +++ b/tools/patchxml2solv.c @@ -23,7 +23,7 @@ main(int argc, char **argv) Pool *pool = pool_create(); Repo *repo = repo_create(pool, ""); repo_add_patchxml(repo, stdin); - repo_write(repo, stdout, 0, 0); + repo_write(repo, stdout, 0, 0, 0, 0); pool_free(pool); exit(0); } diff --git a/tools/repo_susetags.c b/tools/repo_susetags.c index 4dd20211..27adcc1e 100644 --- a/tools/repo_susetags.c +++ b/tools/repo_susetags.c @@ -643,6 +643,10 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr) case CTAG('=', 'P', 's', 'g'): s->suggests = adddep(pool, &pd, s->suggests, line, 0, 0); continue; + case CTAG('=', 'V', 'e', 'r'): + last_found_pack = 0; + indesc++; + continue; } if (!with_attr) continue; @@ -716,10 +720,6 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr) case CTAG('=', 'D', 'i', 'r'): add_dirline (&pd, line + 6); continue; - case CTAG('=', 'V', 'e', 'r'): - last_found_pack = 0; - indesc++; - continue; } } if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) diff --git a/tools/repo_write.c b/tools/repo_write.c index 2af78288..f44ffa3c 100644 --- a/tools/repo_write.c +++ b/tools/repo_write.c @@ -172,6 +172,8 @@ write_blob(FILE *fp, void *data, int len) } } +static unsigned id_bytes; + /* * Id */ @@ -196,7 +198,7 @@ write_id(FILE *fp, Id x) } } -#if 0 +#if 1 static void write_str(FILE *fp, const char *str) { @@ -668,6 +670,7 @@ traverse_dirs(Dirpool *dp, Id *dirmap, Id n, Id dir, Id *used) continue; if (sib == 1 && parent == 1) continue; /* already did that one above */ +assert (sib < dp->ndirs); dirmap[n++] = sib; } lastn = n; @@ -713,7 +716,7 @@ write_compressed_page(FILE *fp, unsigned char *page, int len) */ void -repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata) +repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodatafile *fileinfo, int nsubfiles) { Pool *pool = repo->pool; int i, j, k, n; @@ -744,6 +747,15 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void Stringpool ownspool, *spool; Dirpool owndirpool, *dirpool; + int setfileinfo = 0; + Id repodataschema = 0; + Id repodataschema_internal = 0; + + /* If we're given a fileinfo structure, but have no subfiles, then we're + writing a subfile and our callers wants info about it. */ + if (fileinfo && nsubfiles == 0) + setfileinfo = 1; + memset(&cbdata, 0, sizeof(cbdata)); /* go through all repodata and find the keys we need */ @@ -791,6 +803,34 @@ repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void } cbdata.nmykeys = i; + /* If we store subfile info, generate the three necessary keys. */ + if (nsubfiles) + { + key = cbdata.mykeys + cbdata.nmykeys; + key->name = REPODATA_EXTERNAL; + key->type = TYPE_VOID; + key->size = 0; + key->storage = KEY_STORAGE_SOLVABLE; + cbdata.keymap[key->name] = key - cbdata.mykeys; + key++; + + key->name = REPODATA_KEYS; + key->type = TYPE_IDVALUEARRAY; + key->size = 0; + key->storage = KEY_STORAGE_SOLVABLE; + cbdata.keymap[key->name] = key - cbdata.mykeys; + key++; + + key->name = REPODATA_LOCATION; + key->type = TYPE_STR; + key->size = 0; + key->storage = KEY_STORAGE_SOLVABLE; + cbdata.keymap[key->name] = key - cbdata.mykeys; + key++; + + cbdata.nmykeys = key - cbdata.mykeys; + } + dirpoolusage = 0; spool = 0; @@ -1053,6 +1093,46 @@ for (i = 1; i < cbdata.nmykeys; i++) reloff = needid[0].map; + /* If we have fileinfos to write, setup schemas and increment needid[] + of the right strings. */ + for (i = 0; i < nsubfiles; i++) + { + int j; + + if (fileinfo[i].location && !repodataschema) + { + Id schema[4]; + schema[0] = cbdata.keymap[REPODATA_EXTERNAL]; + schema[1] = cbdata.keymap[REPODATA_KEYS]; + schema[2] = cbdata.keymap[REPODATA_LOCATION]; + schema[3] = 0; + repodataschema = addschema(&cbdata, schema); + } + else if (!repodataschema_internal) + { + Id schema[3]; + schema[0] = cbdata.keymap[REPODATA_EXTERNAL]; + schema[1] = cbdata.keymap[REPODATA_KEYS]; + schema[2] = 0; + repodataschema_internal = addschema(&cbdata, schema); + } + if (2 * fileinfo[i].nkeys > cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size) + cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size = 2 * fileinfo[i].nkeys; + for (j = 1; j < fileinfo[i].nkeys; j++) + needid[fileinfo[i].keys[j].name].need++; +#if 0 + fprintf (stderr, " %d nkeys: %d:", i, fileinfo[i].nkeys); + for (j = 1; j < fileinfo[i].nkeys; j++) + { + needid[fileinfo[i].keys[j].name].need++; + fprintf (stderr, " %s(%d,%d)", id2str(pool, fileinfo[i].keys[j].name), + fileinfo[i].keys[j].name, fileinfo[i].keys[j].type); + } + fprintf (stderr, "\n"); +#endif + } + if (nsubfiles) + cbdata.mykeys[cbdata.keymap[REPODATA_KEYS]].size -= 2; /********************************************************************/ @@ -1222,7 +1302,7 @@ if (cbdata.dirused) write_u32(fp, repo->nsolvables); write_u32(fp, cbdata.nmykeys); write_u32(fp, cbdata.nmyschemata); - write_u32(fp, 0); /* info blocks. */ + write_u32(fp, nsubfiles); /* info blocks. */ solv_flags = 0; solv_flags |= SOLV_FLAG_PREFIX_POOL; #if 0 @@ -1294,6 +1374,11 @@ if (cbdata.dirused) /* * write keys */ + if (setfileinfo) + { + fileinfo->nkeys = cbdata.nmykeys; + fileinfo->keys = sat_calloc (fileinfo->nkeys, sizeof (*fileinfo->keys)); + } for (i = 1; i < cbdata.nmykeys; i++) { write_id(fp, needid[cbdata.mykeys[i].name].need); @@ -1303,6 +1388,8 @@ if (cbdata.dirused) else write_id(fp, cbdata.extdata[i].len); write_id(fp, cbdata.mykeys[i].storage); + if (setfileinfo) + fileinfo->keys[i] = cbdata.mykeys[i]; } /* @@ -1315,28 +1402,32 @@ if (cbdata.dirused) write_idarray(fp, pool, 0, cbdata.myschemadata + cbdata.myschemata[i]); } -#if 0 /* * write info block */ - for (i = 0; i < repo->nrepodata; i++) + for (i = 0; i < nsubfiles; i++) { int j; - if (repo->repodata[i].location) + if (fileinfo[i].location) write_id(fp, repodataschema); else write_id(fp, repodataschema_internal); /* keys + location, write idarray */ - for (j = 0; j < repo->repodata[i].nkeys; j++) + for (j = 1; j < fileinfo[i].nkeys; j++) { - Id id = needid[repo->repodata[i].keys[j].name].need; - write_id_value(fp, id, repo->repodata[i].keys[j].type, j == repo->repodata[i].nkeys - 1); + + Id id = needid[fileinfo[i].keys[j].name].need; +#if 0 + fprintf (stderr, "writing %d(%s) %d\n", id, + id2str(pool, needid[id].map), + fileinfo[i].keys[j].type); +#endif + write_id_value(fp, id, fileinfo[i].keys[j].type, j == fileinfo[i].nkeys - 1); } - if (repo->repodata[i].location) - write_str(fp, repo->repodata[i].location); + if (fileinfo[i].location) + write_str(fp, fileinfo[i].location); } -#endif /********************************************************************/ @@ -1350,6 +1441,7 @@ if (cbdata.dirused) { if (s->repo != repo) continue; + id_bytes = 0; /* keep in sync with schema generation! */ write_id(fp, cbdata.solvschemata[n]); #if 0 @@ -1389,11 +1481,12 @@ if (cbdata.dirused) if (s->freshens && cbdata.keymap[SOLVABLE_FRESHENS]) write_idarray_sort(fp, pool, needid, idarraydata + s->freshens); if (repo->rpmdbid && cbdata.keymap[RPM_RPMDBID]) - write_u32(fp, repo->rpmdbid[i - repo->start]); + write_u32(fp, repo->rpmdbid[i - repo->start]),id_bytes+=4; if (cbdata.incorelen[n]) { write_blob(fp, incoredata, cbdata.incorelen[n]); incoredata += cbdata.incorelen[n]; + id_bytes += cbdata.incorelen[n]; } n++; } @@ -1443,6 +1536,15 @@ if (cbdata.dirused) write_blob(fp, cbdata.extdata[i].buf, cbdata.extdata[i].len); #endif + /* Fill fileinfo for our caller. */ + if (setfileinfo) + { + fileinfo->checksum = 0; + fileinfo->nchecksum = 0; + fileinfo->checksumtype = 0; + fileinfo->location = 0; + } + for (i = 1; i < cbdata.nmykeys; i++) sat_free(cbdata.extdata[i].buf); @@ -1451,5 +1553,3 @@ if (cbdata.dirused) sat_free(cbdata.myschemadata); sat_free(cbdata.myschemata); } - -// EOF diff --git a/tools/repo_write.h b/tools/repo_write.h index eb3b7e76..149eb3e8 100644 --- a/tools/repo_write.h +++ b/tools/repo_write.h @@ -18,6 +18,19 @@ #include "pool.h" #include "repo.h" -void repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata); +/* Describes a repodata file */ +typedef struct _Repodatafile +{ + /* These have the same meaning as the equally named fields in + Repodata. */ + char *location; + char *checksum; + unsigned nchecksum; + unsigned checksumtype; + struct _Repokey *keys; + unsigned int nkeys; +} Repodatafile; + +void repo_write(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodatafile *fileinfo, int nsubfiles); #endif diff --git a/tools/rpmdb2solv.c b/tools/rpmdb2solv.c index ba23da67..8bd134ab 100644 --- a/tools/rpmdb2solv.c +++ b/tools/rpmdb2solv.c @@ -54,7 +54,7 @@ main(int argc, char **argv) ref = 0; } - repo_write(repo, stdout, 0, 0); + repo_write(repo, stdout, 0, 0, 0, 0); pool_free(pool); exit(0); diff --git a/tools/rpmmd2solv.c b/tools/rpmmd2solv.c index b035ac69..1351c479 100644 --- a/tools/rpmmd2solv.c +++ b/tools/rpmmd2solv.c @@ -23,7 +23,7 @@ main(int argc, char **argv) Pool *pool = pool_create(); Repo *repo = repo_create(pool, ""); repo_add_rpmmd(repo, stdin); - repo_write(repo, stdout, 0, 0); + repo_write(repo, stdout, 0, 0, 0, 0); pool_free(pool); exit(0); } diff --git a/tools/susetags2solv.c b/tools/susetags2solv.c index 234a57d1..a7a8b819 100644 --- a/tools/susetags2solv.c +++ b/tools/susetags2solv.c @@ -53,9 +53,23 @@ create_filter(Pool *pool) } } +static int test_separate = 0; + static int -keyfilter(Repo *data, Repokey *key, void *kfdata) +keyfilter_solv(Repo *data, Repokey *key, void *kfdata) { + if (test_separate && key->storage != KEY_STORAGE_SOLVABLE) + return KEY_STORAGE_DROPPED; + if (key->name < nfilter && filter[key->name]) + return KEY_STORAGE_VERTICAL_OFFSET; + return KEY_STORAGE_INCORE; +} + +static int +keyfilter_attr(Repo *data, Repokey *key, void *kfdata) +{ + if (key->storage == KEY_STORAGE_SOLVABLE) + return KEY_STORAGE_DROPPED; if (key->name < nfilter && filter[key->name]) return KEY_STORAGE_VERTICAL_OFFSET; return KEY_STORAGE_INCORE; @@ -64,6 +78,9 @@ keyfilter(Repo *data, Repokey *key, void *kfdata) int main(int argc, char **argv) { + Repodatafile fileinfoa[1]; + Repodatafile *fileinfo = 0; + int nsubfiles = 0; int with_attr = 0; argv++; argc--; @@ -75,6 +92,7 @@ main(int argc, char **argv) switch (*s++) { case 'a': with_attr = 1; break; + case 's': test_separate = 1; break; default : break; } argv++; @@ -83,7 +101,20 @@ main(int argc, char **argv) Repo *repo = repo_create(pool, ""); repo_add_susetags(repo, stdin, 0, with_attr); create_filter(pool); - repo_write(repo, stdout, keyfilter, 0); + memset (fileinfoa, 0, sizeof fileinfoa); + if (with_attr && test_separate) + { + fileinfo = fileinfoa; + FILE *fp = fopen ("test.attr", "w"); + repo_write(repo, fp, keyfilter_attr, 0, fileinfo, 0); + fclose (fp); + fileinfo->location = strdup ("test.attr"); + fileinfo++; + + nsubfiles = fileinfo - fileinfoa; + fileinfo = fileinfoa; + } + repo_write(repo, stdout, keyfilter_solv, 0, fileinfo, nsubfiles); #if 0 if (with_attr && attr) {