From 62d1e627439ccd74da2f9ec45566653e18c2576a Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Fri, 15 Feb 2008 18:58:59 +0000 Subject: [PATCH] - really support DIRSTRARRAY type - make pool_addfileprovides do something useful --- src/pool.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------------ src/poolid.c | 2 +- src/repo_solv.c | 21 +++++++++- src/repodata.c | 64 ++++++++++++++++++++++++++++++ src/repodata.h | 1 + 5 files changed, 181 insertions(+), 27 deletions(-) diff --git a/src/pool.c b/src/pool.c index b2c4941..77733c1 100644 --- a/src/pool.c +++ b/src/pool.c @@ -636,7 +636,9 @@ pool_setdebuglevel(Pool *pool, int level) /*************************************************************************/ struct searchfiles { - const char **files; + Id *ids; + char **dirs; + char **names; int nfiles; Map seen; }; @@ -647,7 +649,7 @@ static void pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct searchfiles *isf) { Id dep, sid; - const char *s; + const char *s, *sr; while ((dep = *ida++) != 0) { @@ -696,24 +698,66 @@ pool_addfileprovides_dep(Pool *pool, Id *ida, struct searchfiles *sf, struct sea s = id2str(pool, dep); if (*s != '/') continue; - sf->files = sat_extend(sf->files, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); - sf->files[sf->nfiles++] = strdup(s); + sf->ids = sat_extend(sf->ids, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); + sf->dirs = sat_extend(sf->dirs, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); + sf->names = sat_extend(sf->names, sf->nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); + sf->ids[sf->nfiles] = dep; + sr = strrchr(s, '/'); + sf->names[sf->nfiles] = strdup(sr + 1); + sf->dirs[sf->nfiles] = sat_malloc(sr - s + 1); + if (sr != s) + strncpy(sf->dirs[sf->nfiles], s, sr - s); + sf->dirs[sf->nfiles][sr - s] = 0; + sf->nfiles++; } } -#if 0 +struct addfileprovides_cbdata { + int nfiles; + Id *ids; + char **dirs; + char **names; + + Repodata *olddata; + Id *dids; + Map useddirs; +}; + static int -addfileprovides_cb(void *data, Solvable *s, Id key, const char *str) +addfileprovides_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *value) { + struct addfileprovides_cbdata *cbd = cbdata; Pool *pool = s->repo->pool; + int i; Id id; - id = str2id(pool, str, 0); - if (!id) - return 0; /* can't happen */ - s->provides = repo_addid_dep(s->repo, s->provides, id, SOLVABLE_FILEMARKER); + + if (data != cbd->olddata) + { + map_free(&cbd->useddirs); + map_init(&cbd->useddirs, data->dirpool.ndirs); + for (i = 0; i < cbd->nfiles; i++) + { + Id did = repodata_str2dir(data, cbd->dirs[i], 0); + cbd->dids[i] = did; + if (did) + MAPSET(&cbd->useddirs, did); + } + cbd->olddata = data; + } + if (!MAPTST(&cbd->useddirs, value->id)) + return 0; + for (i = 0; i < cbd->nfiles; i++) + { + if (cbd->dids[i] != value->id) + continue; + if (!strcmp(cbd->names[i], value->str)) + break; + } + if (i == cbd->nfiles) + return 0; + s->provides = repo_addid_dep(s->repo, s->provides, cbd->ids[i], SOLVABLE_FILEMARKER); return 0; } -#endif void pool_addfileprovides(Pool *pool, Repo *installed) @@ -721,7 +765,11 @@ pool_addfileprovides(Pool *pool, Repo *installed) Solvable *s; Repo *repo; struct searchfiles sf, isf; + struct addfileprovides_cbdata cbd; int i; + Id id_filelist; + + id_filelist = str2id(pool, "filelist", 1); memset(&sf, 0, sizeof(sf)); map_init(&sf.seen, pool->ss.nstrings + pool->nrels); @@ -754,32 +802,54 @@ pool_addfileprovides(Pool *pool, Repo *installed) map_free(&isf.seen); POOL_DEBUG(SAT_DEBUG_STATS, "found %d file dependencies\n", sf.nfiles); POOL_DEBUG(SAT_DEBUG_STATS, "found %d installed file dependencies\n", isf.nfiles); + cbd.dids = 0; + map_init(&cbd.useddirs, 1); if (sf.nfiles) { #if 0 for (i = 0; i < sf.nfiles; i++) - POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in filelist\n", sf.files[i]); + POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in filelist\n", id2str(pool, sf.ids[i])); #endif - sf.files = sat_extend(sf.files, sf.nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); - sf.files[sf.nfiles++] = 0; -#if 0 - pool_search(0, SOLVABLE_FILELIST, (const char *)sf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0); -#endif - sat_free(sf.files); + cbd.nfiles = sf.nfiles; + cbd.ids = sf.ids; + cbd.dirs = sf.dirs; + cbd.names = sf.names; + cbd.olddata = 0; + cbd.dids = sat_realloc2(cbd.dids, sf.nfiles, sizeof(Id)); + pool_search(pool, 0, id_filelist, 0, 0, addfileprovides_cb, &cbd); + sat_free(sf.ids); + for (i = 0; i < sf.nfiles; i++) + { + sat_free(sf.dirs[i]); + sat_free(sf.names[i]); + } + sat_free(sf.dirs); + sat_free(sf.names); } if (isf.nfiles && installed) { #if 0 for (i = 0; i < isf.nfiles; i++) - POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in installed filelist\n", isf.files[i]); -#endif - isf.files = sat_extend(isf.files, isf.nfiles, 1, sizeof(const char *), SEARCHFILES_BLOCK); - isf.files[isf.nfiles++] = 0; -#if 0 - repo_search(installed, 0, SOLVABLE_FILELIST, (const char *)isf.files, SEARCH_STRING|SEARCH_MULTIPLE, addfileprovides_cb, 0); + POOL_DEBUG(SAT_DEBUG_STATS, "looking up %s in installed filelist\n", id2str(pool, isf.ids[i])); #endif - sat_free(isf.files); + cbd.nfiles = isf.nfiles; + cbd.ids = isf.ids; + cbd.dirs = isf.dirs; + cbd.names = isf.names; + cbd.olddata = 0; + cbd.dids = sat_realloc2(cbd.dids, isf.nfiles, sizeof(Id)); + repo_search(installed, 0, id_filelist, 0, 0, addfileprovides_cb, &cbd); + sat_free(isf.ids); + for (i = 0; i < isf.nfiles; i++) + { + sat_free(isf.dirs[i]); + sat_free(isf.names[i]); + } + sat_free(isf.dirs); + sat_free(isf.names); } + map_free(&cbd.useddirs); + sat_free(cbd.dids); pool_freewhatprovides(pool); /* as we have added provides */ } diff --git a/src/poolid.c b/src/poolid.c index 6911367..4cc9a24 100644 --- a/src/poolid.c +++ b/src/poolid.c @@ -110,7 +110,7 @@ rel2id(Pool *pool, Id name, Id evr, int flags, int create) /* extend whatprovides_rel if needed */ if (pool->whatprovides_rel && (id & WHATPROVIDES_BLOCK) == 0) { - pool->whatprovides_rel = sat_realloc(pool->whatprovides_rel, (id + (WHATPROVIDES_BLOCK + 1)) * sizeof(Offset)); + pool->whatprovides_rel = sat_realloc2(pool->whatprovides_rel, id + (WHATPROVIDES_BLOCK + 1), sizeof(Offset)); memset(pool->whatprovides_rel + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset)); } return MAKERELDEP(id); diff --git a/src/repo_solv.c b/src/repo_solv.c index 6989663..a6faa3b 100644 --- a/src/repo_solv.c +++ b/src/repo_solv.c @@ -1262,7 +1262,26 @@ fprintf(stderr, "solv %d name %d type %d class %d\n", i, id, keys[key].type, key break; } break; - + case TYPE_DIRSTRARRAY: + for (;;) + { + did = read_id(&data, 0); + if (keys[key].storage == KEY_STORAGE_INCORE) + { + incore_add_id(&data, did); + while ((h = read_u8(&data)) != 0) + incore_add_u8(&data, h); + incore_add_u8(&data, 0); + } + else + { + while (read_u8(&data) != 0) + ; + } + if (!(did & 0x40)) + break; + } + break; default: skip_item(&data, keys[key].type, numid, numrel); } diff --git a/src/repodata.c b/src/repodata.c index 59782b1..e1ee942 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -765,6 +765,63 @@ fprintf(stderr, "repodata_add_dirnumnum %d %d %d %d (%d)\n", entry, dir, num, nu } void +repodata_add_dirstr(Repodata *data, Id entry, Id keyname, Id dir, const char *str) +{ + Id *ida, *pp, stroff; + Repokey key; + int l; + + l = strlen(str) + 1; + data->attrdata = sat_realloc(data->attrdata, data->attrdatalen + l); + memcpy(data->attrdata + data->attrdatalen, str, l); + stroff = data->attrdatalen; + data->attrdatalen += l; + +#if 0 +fprintf(stderr, "repodata_add_dirstr %d %d %s (%d)\n", entry, dir, str, data->attriddatalen); +#endif + if (data->attrs && data->attrs[entry]) + { + for (pp = data->attrs[entry]; *pp; pp += 2) + if (data->keys[*pp].name == keyname && data->keys[*pp].type == TYPE_DIRSTRARRAY) + break; + if (*pp) + { + int oldsize = 0; + for (ida = data->attriddata + pp[1]; *ida; ida += 2) + oldsize += 2; + if (ida + 1 == data->attriddata + data->attriddatalen) + { + /* this was the last entry, just append it */ + data->attriddata = sat_realloc2(data->attriddata, data->attriddatalen + 2, sizeof(Id)); + data->attriddatalen--; /* overwrite terminating 0 */ + } + else + { + /* too bad. move to back. */ + data->attriddata = sat_realloc2(data->attriddata, data->attriddatalen + oldsize + 3, sizeof(Id)); + memcpy(data->attriddata + data->attriddatalen, data->attriddata + pp[1], oldsize * sizeof(Id)); + pp[1] = data->attriddatalen; + data->attriddatalen += oldsize; + } + data->attriddata[data->attriddatalen++] = dir; + data->attriddata[data->attriddatalen++] = stroff; + data->attriddata[data->attriddatalen++] = 0; + return; + } + } + key.name = keyname; + key.type = TYPE_DIRSTRARRAY; + key.size = 0; + key.storage = KEY_STORAGE_INCORE; + data->attriddata = sat_realloc2(data->attriddata, data->attriddatalen + 3, sizeof(Id)); + repodata_set(data, entry, &key, data->attriddatalen); + data->attriddata[data->attriddatalen++] = dir; + data->attriddata[data->attriddatalen++] = stroff; + data->attriddata[data->attriddatalen++] = 0; +} + +void repodata_merge_attrs (Repodata *data, Id dest, Id src) { Id *keyp; @@ -1024,6 +1081,13 @@ fprintf(stderr, "schemadata %p\n", data->schemadata); data_addideof(xd, ida[2], ida[3] ? 0 : 1); } break; + case TYPE_DIRSTRARRAY: + for (ida = data->attriddata + id; *ida; ida += 2) + { + data_addideof(xd, ida[0], ida[2] ? 0 : 1); + data_addblob(xd, data->attrdata + ida[1], strlen((char *)(data->attrdata + ida[1])) + 1); + } + break; default: fprintf(stderr, "don't know how to handle type %d\n", key->type); exit(1); diff --git a/src/repodata.h b/src/repodata.h index c3e73d8..fee6f38 100644 --- a/src/repodata.h +++ b/src/repodata.h @@ -127,6 +127,7 @@ void repodata_set_constant(Repodata *data, Id entry, Id keyname, Id constant); void repodata_set_void(Repodata *data, Id entry, Id keyname); void repodata_set_str(Repodata *data, Id entry, Id keyname, const char *str); void repodata_add_dirnumnum(Repodata *data, Id entry, Id keyname, Id dir, Id num, Id num2); +void repodata_add_dirstr(Repodata *data, Id entry, Id keyname, Id dir, const char *str); void repodata_merge_attrs (Repodata *data, Id dest, Id src); void repodata_internalize(Repodata *data); -- 2.7.4