+static Id
+lookup_shared_id(Repodata *data, Id p, Id keyname, Id voidid, int uninternalized)
+{
+ Id r;
+ r = repodata_lookup_type(data, p, keyname);
+ if (r)
+ {
+ if (r == REPOKEY_TYPE_VOID)
+ return voidid;
+ r = repodata_lookup_id(data, p, keyname);
+ if (r)
+ return r;
+ }
+ if (uninternalized)
+ {
+ KeyValue kv;
+ Repokey *key = repodata_lookup_kv_uninternalized(data, p, keyname, &kv);
+ if (!key)
+ return 0;
+ if (key->type == REPOKEY_TYPE_VOID)
+ return voidid;
+ if (key->type == REPOKEY_TYPE_ID)
+ return kv.id;
+ }
+ return 0;
+}
+
+static inline Id
+toevr(Pool *pool, struct parsedata *pd, const char *version, const char *release)
+{
+ return makeevr(pool, !release || (release[0] == '-' && !release[1]) ?
+ version : join2(&pd->jd, version, "-", release));
+}
+
+
+static inline void record_share(struct parsedata *pd, Id handle, Id name, Id evr, Id arch)
+{
+ Repo *repo = pd->repo;
+ int i = handle - repo->start;
+ if (i >= pd->nshare)
+ {
+ pd->share_with = solv_realloc2(pd->share_with, i + 256, sizeof(*pd->share_with));
+ memset(pd->share_with + pd->nshare, 0, (i + 256 - pd->nshare) * sizeof(*pd->share_with));
+ pd->nshare = i + 256;
+ }
+ pd->share_with[i].name = name;
+ pd->share_with[i].evr = evr;
+ pd->share_with[i].arch = arch;
+}
+
+static void process_shares(struct parsedata *pd)
+{
+ Pool *pool = pd->pool;
+ Repo *repo = pd->repo;
+ Repodata *data = pd->data;
+ int i, last_found;
+ Map keyidmap;
+
+ map_init(&keyidmap, data->nkeys);
+ for (i = 1; i < data->nkeys; i++)
+ {
+ Id keyname = data->keys[i].name;
+ if (keyname == SOLVABLE_INSTALLSIZE || keyname == SOLVABLE_DISKUSAGE || keyname == SOLVABLE_FILELIST)
+ continue;
+ if (keyname == SOLVABLE_MEDIADIR || keyname == SOLVABLE_MEDIAFILE || keyname == SOLVABLE_MEDIANR)
+ continue;
+ if (keyname == SOLVABLE_DOWNLOADSIZE || keyname == SOLVABLE_CHECKSUM)
+ continue;
+ if (keyname == SOLVABLE_SOURCENAME || keyname == SOLVABLE_SOURCEARCH || keyname == SOLVABLE_SOURCEEVR)
+ continue;
+ if (keyname == SOLVABLE_PKGID || keyname == SOLVABLE_HDRID || keyname == SOLVABLE_LEADSIGID)
+ continue;
+ if (keyname == SUSETAGS_SHARE_NAME || keyname == SUSETAGS_SHARE_EVR || keyname == SUSETAGS_SHARE_ARCH)
+ continue;
+ MAPSET(&keyidmap, i);
+ }
+ last_found = 0;
+ for (i = 0; i < pd->nshare; i++)
+ {
+ unsigned int n, nn;
+ Solvable *found = 0;
+ if (!pd->share_with[i].name)
+ continue;
+ for (n = repo->start, nn = repo->start + last_found; n < repo->end; n++, nn++)
+ {
+ if (nn >= repo->end)
+ nn = repo->start;
+ found = pool->solvables + nn;
+ if (found->repo == repo
+ && found->name == pd->share_with[i].name
+ && found->evr == pd->share_with[i].evr
+ && found->arch == pd->share_with[i].arch)
+ {
+ last_found = nn - repo->start;
+ break;
+ }
+ }
+ if (n != repo->end)
+ repodata_merge_some_attrs(data, repo->start + i, repo->start + last_found, &keyidmap, 0);
+ }
+ pd->share_with = solv_free(pd->share_with);
+ pd->nshare = 0;
+ map_free(&keyidmap);
+}
+