From: Michael Schroeder Date: Tue, 22 Sep 2009 16:49:30 +0000 (+0200) Subject: - get missing translations from other solvables X-Git-Tag: BASE-SuSE-Code-12_1-Branch~161^2~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2809498f0ceebc98709443afcbfdd799d5bb35b1;p=thirdparty%2Flibsolv.git - get missing translations from other solvables - fix solvable_lookup_str_poollang bug - add support for REPOKEY_TYPE_BINARY - do not add provides when extending susetags solvables - fix susetags language handling in demo application --- diff --git a/examples/solv.c b/examples/solv.c index b4c5358a..d0bced43 100644 --- a/examples/solv.c +++ b/examples/solv.c @@ -1208,11 +1208,15 @@ susetags_add_ext(Repo *repo, Repodata *data) { if (strncmp(di.kv.str, "packages.", 9) != 0) continue; + if (!strcmp(di.kv.str + 9, "gz")) + continue; if (!di.kv.str[9] || !di.kv.str[10] || (di.kv.str[11] && di.kv.str[11] != '.')) continue; ext[0] = di.kv.str[9]; ext[1] = di.kv.str[10]; ext[2] = 0; + if (!strcmp(ext, "en")) + continue; if (!susetags_find(repo, di.kv.str, &filechksum, &filechksumtype)) continue; handle = repodata_new_handle(data); @@ -1224,7 +1228,7 @@ susetags_add_ext(Repo *repo, Repodata *data) repodata_add_idarray(data, handle, REPOSITORY_KEYS, SOLVABLE_DISKUSAGE); repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_DIRNUMNUMARRAY); } - if (!strcmp(ext, "FL")) + else if (!strcmp(ext, "FL")) { repodata_add_idarray(data, handle, REPOSITORY_KEYS, SOLVABLE_FILELIST); repodata_add_idarray(data, handle, REPOSITORY_KEYS, REPOKEY_TYPE_DIRSTRARRAY); @@ -1538,8 +1542,21 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) printf(" fetching\n"); if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), iscompressed(filename), filechksum, filechksumtype, &badchecksum)) == 0) break; /* hopeless */ - repo_add_susetags(repo, fp, defvendor, 0, 0); + repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE); fclose(fp); + /* add default language */ + filename = susetags_find(repo, "packages.en.gz", &filechksum, &filechksumtype); + if (!filename) + filename = susetags_find(repo, "packages.en", &filechksum, &filechksumtype); + if (filename) + { + if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), iscompressed(filename), filechksum, filechksumtype, &badchecksum)) != 0) + { + repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE|REPO_REUSE_REPODATA|REPO_EXTEND_SOLVABLES); + fclose(fp); + } + } + repo_internalize(repo); data = repo_add_repodata(repo, 0); susetags_add_ext(repo, data); repodata_internalize(data); diff --git a/ext/repo_susetags.c b/ext/repo_susetags.c index e148d856..d8daa7f0 100644 --- a/ext/repo_susetags.c +++ b/ext/repo_susetags.c @@ -22,6 +22,7 @@ struct parsedata { char *kind; Repo *repo; Repodata *data; + int flags; struct parsedata_common common; int last_found_source; char **share_with; @@ -326,7 +327,7 @@ finish_solvable(struct parsedata *pd, Solvable *s, Id handle, Offset freshens) #if 1 /* move file provides to filelist */ /* relies on the fact that rpm inserts self-provides at the end */ - if (s->provides) + if (s->provides && (pd->flags & REPO_EXTEND_SOLVABLES) == 0) { Id *p, *lastreal, did; const char *str, *sp; @@ -480,6 +481,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int pd.repo = pd.common.repo = repo; pd.data = data; pd.common.pool = pool; + pd.flags = flags; linep = line; s = 0; diff --git a/ext/repo_write.c b/ext/repo_write.c index 2f0d4e42..4fc4f493 100644 --- a/ext/repo_write.c +++ b/ext/repo_write.c @@ -821,6 +821,11 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue id = cbdata->dirused[id]; data_addid(xd, id); break; + case REPOKEY_TYPE_BINARY: + data_addid(xd, kv->num); + if (kv->num) + data_addblob(xd, (unsigned char *)kv->str, kv->num); + break; case REPOKEY_TYPE_DIRNUMNUMARRAY: id = kv->id; if (cbdata->owndirpool) @@ -854,9 +859,6 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue { cbdata->current_sub++; } - else - { - } break; case REPOKEY_TYPE_FLEXARRAY: if (!kv->entry) diff --git a/src/pool.c b/src/pool.c index dad0971b..0b0648ec 100644 --- a/src/pool.c +++ b/src/pool.c @@ -957,14 +957,6 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru if (ndone >= repo->nsolvables) break; - if (!repodata_precheck_keyname(data, SOLVABLE_FILELIST)) - continue; - for (j = 1; j < data->nkeys; j++) - if (data->keys[j].name == SOLVABLE_FILELIST) - break; - if (j == data->nkeys) - continue; - if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq)) { map_empty(&cbd->providedids); @@ -989,13 +981,14 @@ pool_addfileprovides_search(Pool *pool, struct addfileprovides_cbdata *cbd, stru continue; } } - else + + if (!repodata_has_keyname(data, SOLVABLE_FILELIST)) + continue; + + if (data->start < provstart || data->end > provend) { - if (data->start < provstart || data->end > provend) - { - map_empty(&cbd->providedids); - provstart = provend = 0; - } + map_empty(&cbd->providedids); + provstart = provend = 0; } /* check if the data is incomplete */ diff --git a/src/repodata.c b/src/repodata.c index 1b657f7b..e0072e66 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -1940,6 +1940,35 @@ repodata_set_str(Repodata *data, Id solvid, Id keyname, const char *str) data->attrdatalen += l; } +void +repodata_set_binary(Repodata *data, Id solvid, Id keyname, void *buf, int len) +{ + Repokey key; + unsigned char *dp; + + key.name = keyname; + key.type = REPOKEY_TYPE_BINARY; + key.size = 0; + key.storage = KEY_STORAGE_INCORE; + data->attrdata = sat_extend(data->attrdata, data->attrdatalen, len + 5, 1, REPODATA_ATTRDATA_BLOCK); + dp = data->attrdata + data->attrdatalen; + if (len >= (1 << 14)) + { + if (len >= (1 << 28)) + *dp++ = (len >> 28) | 128; + if (len >= (1 << 21)) + *dp++ = (len >> 21) | 128; + *dp++ = (len >> 14) | 128; + } + if (len >= (1 << 7)) + *dp++ = (len >> 7) | 128; + *dp++ = len & 127; + if (len) + memcpy(dp, buf, len); + repodata_set(data, solvid, &key, data->attrdatalen); + data->attrdatalen = dp + len - data->attrdata; +} + /* add an array element consisting of entrysize Ids to the repodata. modifies attriddata * so that the caller can append the new element there */ static void @@ -2260,7 +2289,7 @@ repodata_merge_some_attrs(Repodata *data, Id dest, Id src, Map *keyidmap, int ov /**********************************************************************/ -/* TODO: unify with repo_write! */ +/* TODO: unify with repo_write and repo_solv! */ #define EXTDATA_BLOCK 1023 @@ -2273,6 +2302,7 @@ static void data_addid(struct extdata *xd, Id x) { unsigned char *dp; + xd->buf = sat_extend(xd->buf, xd->len, 5, 1, EXTDATA_BLOCK); dp = xd->buf + xd->len; @@ -2295,7 +2325,7 @@ data_addideof(struct extdata *xd, Id x, int eof) { if (x >= 64) x = (x & 63) | ((x & ~63) << 1); - data_addid(xd, (eof ? x: x | 64)); + data_addid(xd, (eof ? x : x | 64)); } static void @@ -2350,6 +2380,14 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore, case REPOKEY_TYPE_DIR: data_addid(xd, val); break; + case REPOKEY_TYPE_BINARY: + { + Id len; + unsigned char *dp = data_read_id(data->attrdata + val, &len); + dp += len; + data_addblob(xd, data->attrdata + val, dp - (data->attrdata + val)); + } + break; case REPOKEY_TYPE_IDARRAY: for (ida = data->attriddata + val; *ida; ida++) data_addideof(xd, ida[0], ida[1] ? 0 : 1); diff --git a/src/repodata.h b/src/repodata.h index a7c59208..1f9fa6e8 100644 --- a/src/repodata.h +++ b/src/repodata.h @@ -155,6 +155,19 @@ repodata_precheck_keyname(Repodata *data, Id keyname) return x && (x & (1 << (keyname & 7))) ? 1 : 0; } +/* check if the repodata contains data for the specified keyname */ +static inline int +repodata_has_keyname(Repodata *data, Id keyname) +{ + int i; + if (!repodata_precheck_keyname(data, keyname)) + return 0; + for (i = 1; i < data->nkeys; i++) + if (data->keys[i].name == keyname) + return 1; + return 0; +} + /* search key (all keys, if keyname == 0) for Id * Call for each match */ void repodata_search(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, struct _KeyValue *kv), void *cbdata); @@ -200,6 +213,7 @@ void repodata_set_void(Repodata *data, Id solvid, Id keyname); void repodata_set_num(Repodata *data, Id solvid, Id keyname, unsigned int num); void repodata_set_id(Repodata *data, Id solvid, Id keyname, Id id); void repodata_set_str(Repodata *data, Id solvid, Id keyname, const char *str); +void repodata_set_binary(Repodata *data, Id solvid, Id keyname, void *buf, int len); /* create id from string, then set_id */ void repodata_set_poolstr(Repodata *data, Id solvid, Id keyname, const char *str); diff --git a/src/repopack.h b/src/repopack.h index bfc14257..e55072c7 100644 --- a/src/repopack.h +++ b/src/repopack.h @@ -93,6 +93,10 @@ data_fetch(unsigned char *dp, KeyValue *kv, Repokey *key) case REPOKEY_TYPE_SHA256: kv->str = (const char *)dp; return dp + SIZEOF_SHA256; + case REPOKEY_TYPE_BINARY: + dp = data_read_id(dp, &kv->num); + kv->str = (const char *)dp; + return dp + kv->num; case REPOKEY_TYPE_IDARRAY: return data_read_ideof(dp, &kv->id, &kv->eof); case REPOKEY_TYPE_DIRSTRARRAY: @@ -146,6 +150,12 @@ data_skip(unsigned char *dp, int type) while ((*dp) != 0) dp++; return dp + 1; + case REPOKEY_TYPE_BINARY: + { + Id len; + dp = data_read_id(dp, &len); + return dp + len; + } case REPOKEY_TYPE_DIRSTRARRAY: for (;;) { diff --git a/src/solvable.c b/src/solvable.c index dfe8ce12..26caf77e 100644 --- a/src/solvable.c +++ b/src/solvable.c @@ -73,6 +73,49 @@ solvable_lookup_str(Solvable *s, Id keyname) return repo_lookup_str(s->repo, s - s->repo->pool->solvables, keyname); } +const char * +solvable_lookup_str_base(Solvable *s, Id keyname, Id basekeyname) +{ + Pool *pool; + const char *str, *basestr; + Id p, pp; + Solvable *s2; + int pass; + + if (!s->repo) + return 0; + pool = s->repo->pool; + str = solvable_lookup_str(s, keyname); + if (str || keyname == basekeyname) + return str; + basestr = solvable_lookup_str(s, basekeyname); + if (!basestr) + return 0; + /* search for a solvable with same name and same base that has the + * translation */ + if (!pool->whatprovides) + return 0; + /* we do this in two passes, first same vendor, then all other vendors */ + for (pass = 0; pass < 2; pass++) + { + FOR_PROVIDES(p, pp, s->name) + { + s2 = pool->solvables + p; + if (s2->name != s->name) + continue; + if ((s->vendor == s2->vendor) != (pass == 0)) + continue; + str = solvable_lookup_str(s2, basekeyname); + if (!str || strcmp(str, basestr)) + continue; + str = solvable_lookup_str(s2, keyname); + if (str) + return str; + } + } + return 0; +} + const char * solvable_lookup_str_poollang(Solvable *s, Id keyname) { @@ -101,8 +144,8 @@ solvable_lookup_str_poollang(Solvable *s, Id keyname) if (i >= pool->languagecacheother) { pool->languagecache = sat_realloc2(pool->languagecache, pool->languagecacheother + 1, cols * sizeof(Id)); - pool->languagecacheother++; row = pool->languagecache + cols * (ID_NUM_INTERNAL + pool->languagecacheother++); + *row = keyname; } } else @@ -121,7 +164,7 @@ solvable_lookup_str_poollang(Solvable *s, Id keyname) *row = str2id(pool, p, 1); sat_free(p); } - str = solvable_lookup_str(s, *row); + str = solvable_lookup_str_base(s, *row, keyname); if (str) return str; } @@ -135,7 +178,7 @@ solvable_lookup_str_lang(Solvable *s, Id keyname, const char *lang) { const char *str; Id id = pool_id2langid(s->repo->pool, keyname, lang, 0); - if (id && (str = solvable_lookup_str(s, id)) != 0) + if (id && (str = solvable_lookup_str_base(s, id, keyname)) != 0) return str; } return solvable_lookup_str(s, keyname); diff --git a/src/transaction.c b/src/transaction.c index 2a481fa4..4efc4dad 100644 --- a/src/transaction.c +++ b/src/transaction.c @@ -1228,6 +1228,9 @@ addsolvableedges(struct orderdata *od, Solvable *s) if (s2->repo != installed && MAPTST(&trans->transactsmap, p2)) { /* deinstall p before installing p2 */ +#if 0 + printf("add conflict uninst->inst edge (%s -> %s -> %s)\n", solvid2str(pool, p2), dep2str(pool, con), solvid2str(pool, p)); +#endif addedge(od, p2, p, TYPE_CON); } } @@ -1236,6 +1239,9 @@ addsolvableedges(struct orderdata *od, Solvable *s) if (s2->repo == installed && MAPTST(&trans->transactsmap, p2)) { /* deinstall p2 before installing p */ +#if 0 + printf("add conflict uninst->inst edge (%s -> %s -> %s)\n", solvid2str(pool, p), dep2str(pool, con), solvid2str(pool, p2)); +#endif addedge(od, p, p2, TYPE_CON); } } diff --git a/tools/dumpsolv.c b/tools/dumpsolv.c index 95a57301..061f3d04 100644 --- a/tools/dumpsolv.c +++ b/tools/dumpsolv.c @@ -102,6 +102,12 @@ dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv) case REPOKEY_TYPE_CONSTANT: printf("%s: %d\n", keyname, kv->num); break; + case REPOKEY_TYPE_BINARY: + if (kv->num) + printf("%s: %02x..%02x len %d\n", keyname, (unsigned char)kv->str[0], (unsigned char)kv->str[kv->num - 1], kv->num); + else + printf("%s: len 0\n", keyname); + break; case REPOKEY_TYPE_DIRNUMNUMARRAY: if (!kv->entry) printf("%s:\n%*s", keyname, indent, "");