}
+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);
+}
+
+
/*
* parse susetags
*
int intag = 0;
int intag_linestart = 0;
int cummulate = 0;
- int indesc = 0;
+ int notfound = 0;
int indelta = 0;
int last_found_pack = 0;
Id first_new_pkg = 0;
if ((flags & (SUSETAGS_EXTEND|REPO_EXTEND_SOLVABLES)) != 0 && repo->nrepodata)
{
joinhash = joinhash_init(repo, &joinhashm);
- indesc = 1;
}
data = repo_add_repodata(repo, flags);
arch = lookup_shared_id(sdata, p, SUSETAGS_SHARE_ARCH, pool->solvables[p].arch, sdata == data);
if (!arch)
continue;
- if (p - repo->start >= pd.nshare)
- {
- pd.share_with = solv_realloc2(pd.share_with, p - repo->start + 256, sizeof(*pd.share_with));
- memset(pd.share_with + pd.nshare, 0, (p - repo->start + 256 - pd.nshare) * sizeof(*pd.share_with));
- pd.nshare = p - repo->start + 256;
- }
- pd.share_with[p - repo->start].name = name;
- pd.share_with[p - repo->start].evr = evr;
- pd.share_with[p - repo->start].arch = arch;
+ record_share(&pd, p, name, evr, arch);
}
}
}
tag = tag_from_string(line);
- if (indelta)
- {
- /* Example:
- =Dlt: subversion 1.6.16 1.3.1 i586
- =Dsq: subversion 1.6.15 4.2 i586 d57b3fc86e7a2f73796e8e35b96fa86212c910
- =Cks: SHA1 14a8410cf741856a5d70d89dab62984dba6a1ca7
- =Loc: 1 subversion-1.6.15_1.6.16-4.2_1.3.1.i586.delta.rpm
- =Siz: 81558
- */
- switch (tag)
- {
- case CTAG('=', 'D', 's', 'q'):
- {
- Id evr;
- if (split(line + 5, sp, 5) != 5)
- continue;
- repodata_set_id(data, handle, DELTA_SEQ_NAME, pool_str2id(pool, sp[0], 1));
- evr = toevr(pool, &pd, sp[1], sp[2]);
- repodata_set_id(data, handle, DELTA_SEQ_EVR, evr);
- /* repodata_set_id(data, handle, DELTA_SEQ_ARCH, pool_str2id(pool, sp[3], 1)); */
- repodata_set_str(data, handle, DELTA_SEQ_NUM, sp[4]);
- repodata_set_id(data, handle, DELTA_BASE_EVR, evr);
- continue;
- }
- case CTAG('=', 'C', 'k', 's'):
- set_checksum(&pd, data, handle, DELTA_CHECKSUM, line + 6);
- continue;
- case CTAG('=', 'L', 'o', 'c'):
- {
- int i = split(line + 6, sp, 3);
- if (i != 2 && i != 3)
- {
- pd.ret = pool_error(pool, -1, "susetags: line %d: bad location line '%s'\n", pd.lineno, line);
- continue;
- }
- repodata_set_deltalocation(data, handle, atoi(sp[0]), i == 3 ? sp[2] : 0, sp[1]);
- continue;
- }
- case CTAG('=', 'S', 'i', 'z'):
- if (split(line + 6, sp, 3) == 2)
- repodata_set_num(data, handle, DELTA_DOWNLOADSIZE, strtoull(sp[0], 0, 10));
- continue;
- case CTAG('=', 'P', 'k', 'g'):
- case CTAG('=', 'P', 'a', 't'):
- case CTAG('=', 'D', 'l', 't'):
- handle = 0;
- indelta = 0;
- break;
- default:
- pool_debug(pool, SOLV_ERROR, "susetags: unknown line: %d: %s\n", pd.lineno, line);
- continue;
- }
- }
-
- /*
- * start of (next) package or pattern or delta
- *
- * =Pkg: <name> <version> <release> <architecture>
- * (=Pat: ...)
- */
- if (tag == CTAG('=', 'D', 'l', 't'))
- {
+ /* handle global tags and tags that start a new section */
+ switch (tag)
+ {
+ case CTAG('=', 'V', 'e', 'r'):
+ /* start of a new file */
if (s)
finish_solvable(&pd, s, freshens);
s = 0;
- pd.kind = 0;
- if (split(line + 5, sp, 5) != 4)
+ handle = 0;
+ freshens = 0;
+ indelta = 0;
+ notfound = 0;
+ last_found_pack = 0;
+ if (createdpkgs)
{
- pd.ret = pool_error(pool, -1, "susetags: line %d: bad line '%s'\n", pd.lineno, line);
- break;
+ solv_free(joinhash);
+ joinhash = joinhash_init(repo, &joinhashm);
+ createdpkgs = 0;
}
- handle = repodata_new_handle(data);
- repodata_set_id(data, handle, DELTA_PACKAGE_NAME, pool_str2id(pool, sp[0], 1));
- repodata_set_id(data, handle, DELTA_PACKAGE_EVR, toevr(pool, &pd, sp[1], sp[2]));
- repodata_set_id(data, handle, DELTA_PACKAGE_ARCH, pool_str2id(pool, sp[3], 1));
- repodata_add_flexarray(data, SOLVID_META, REPOSITORY_DELTAINFO, handle);
- indelta = 1;
continue;
- }
- if (tag == CTAG('=', 'P', 'k', 'g')
- || tag == CTAG('=', 'P', 'a', 't'))
- {
- /* If we have an old solvable, complete it by filling in some
- default stuff. */
+
+ case CTAG('=', 'L', 'a', 'n'):
+ /* define language of the following material */
+ pd.language = solv_free(pd.language);
+ memset(pd.langcache, 0, sizeof(pd.langcache));
+ if (line[6])
+ pd.language = solv_strdup(line + 6);
+ continue;
+
+ case CTAG('=', 'P', 'k', 'g'): /* start of a package */
+ case CTAG('=', 'P', 'a', 't'): /* start of a pattern */
+ case CTAG('=', 'D', 'l', 't'): /* start of a delta */
+ /* =Pkg: <name> <version> <release> <architecture> */
+ /* If we have an old solvable, complete it by filling in some default stuff. */
if (s)
finish_solvable(&pd, s, freshens);
+ s = 0;
+ handle = 0;
+ freshens = 0;
+ indelta = 0;
+ notfound = 0;
- /*
- * define kind
- */
-
+ /* define kind */
pd.kind = 0;
- if (line[3] == 't')
+ if (tag == CTAG('=', 'P', 'a', 't'))
pd.kind = "pattern";
- /*
- * parse nevra
- */
-
+ /* parse nevra */
if (split(line + 5, sp, 5) != 4)
{
pd.ret = pool_error(pool, -1, "susetags: line %d: bad line '%s'\n", pd.lineno, line);
break;
}
- s = 0;
- freshens = 0;
+
+ if (tag == CTAG('=', 'D', 'l', 't'))
+ {
+ /* start new delta */
+ handle = repodata_new_handle(data);
+ repodata_set_id(data, handle, DELTA_PACKAGE_NAME, pool_str2id(pool, sp[0], 1));
+ repodata_set_id(data, handle, DELTA_PACKAGE_EVR, toevr(pool, &pd, sp[1], sp[2]));
+ repodata_set_id(data, handle, DELTA_PACKAGE_ARCH, pool_str2id(pool, sp[3], 1));
+ repodata_add_flexarray(data, SOLVID_META, REPOSITORY_DELTAINFO, handle);
+ indelta = 1;
+ continue;
+ }
if (joinhash)
{
/* data join operation. find solvable matching name/arch/evr and
* add data to it */
- Id name, evr, arch;
+ Id name, arch;
/* we don't use the create flag here as a simple pre-check for existance */
if (pd.kind)
name = pool_str2id(pool, join2(&pd.jd, pd.kind, ":", sp[0]), 0);
else
name = pool_str2id(pool, sp[0], 0);
- evr = toevr(pool, &pd, sp[1], sp[2]);
arch = pool_str2id(pool, sp[3], 0);
if (name && arch)
{
Id start = (flags & REPO_EXTEND_SOLVABLES) ? 0 : first_new_pkg;
+ Id evr = toevr(pool, &pd, sp[1], sp[2]);
if (repo->start + last_found_pack + 1 >= start && repo->start + last_found_pack + 1 < repo->end)
{
s = pool->solvables + repo->start + last_found_pack + 1;
}
/* do not create new packages in EXTEND_SOLVABLES mode */
if (!s && (flags & REPO_EXTEND_SOLVABLES) != 0)
- continue;
+ {
+ notfound = 1;
+ continue;
+ }
/* fallthrough to package creation */
}
if (!s)
first_new_pkg = s - pool->solvables;
createdpkgs = 1;
}
+ handle = s - pool->solvables;
last_found_pack = (s - pool->solvables) - repo->start;
- if (data)
- handle = s - pool->solvables;
+ continue;
+
+ default:
+ break;
}
- /* If we have no current solvable to add to, ignore all further lines
- for it. Probably invalid input data in the second set of
- solvables. */
- if (indesc >= 2 && !s)
- {
+ /* handle delta tags */
+ if (indelta)
+ {
+ /* Example:
+ =Dlt: subversion 1.6.16 1.3.1 i586
+ =Dsq: subversion 1.6.15 4.2 i586 d57b3fc86e7a2f73796e8e35b96fa86212c910
+ =Cks: SHA1 14a8410cf741856a5d70d89dab62984dba6a1ca7
+ =Loc: 1 subversion-1.6.15_1.6.16-4.2_1.3.1.i586.delta.rpm
+ =Siz: 81558
+ */
+ switch (tag)
+ {
+ case CTAG('=', 'D', 's', 'q'):
+ {
+ Id evr;
+ if (split(line + 5, sp, 5) != 5)
+ continue;
+ repodata_set_id(data, handle, DELTA_SEQ_NAME, pool_str2id(pool, sp[0], 1));
+ evr = toevr(pool, &pd, sp[1], sp[2]);
+ repodata_set_id(data, handle, DELTA_SEQ_EVR, evr);
+ /* repodata_set_id(data, handle, DELTA_SEQ_ARCH, pool_str2id(pool, sp[3], 1)); */
+ repodata_set_str(data, handle, DELTA_SEQ_NUM, sp[4]);
+ repodata_set_id(data, handle, DELTA_BASE_EVR, evr);
+ continue;
+ }
+ case CTAG('=', 'C', 'k', 's'):
+ set_checksum(&pd, data, handle, DELTA_CHECKSUM, line + 6);
+ continue;
+ case CTAG('=', 'L', 'o', 'c'):
+ {
+ int i = split(line + 6, sp, 3);
+ if (i != 2 && i != 3)
+ {
+ pd.ret = pool_error(pool, -1, "susetags: line %d: bad location line '%s'\n", pd.lineno, line);
+ continue;
+ }
+ repodata_set_deltalocation(data, handle, atoi(sp[0]), i == 3 ? sp[2] : 0, sp[1]);
+ continue;
+ }
+ case CTAG('=', 'S', 'i', 'z'):
+ if (split(line + 6, sp, 3) == 2)
+ repodata_set_num(data, handle, DELTA_DOWNLOADSIZE, strtoull(sp[0], 0, 10));
+ continue;
+ default:
+ pool_debug(pool, SOLV_WARN, "susetags: unknown line: %d: %s\n", pd.lineno, line);
+ continue;
+ }
+ }
+
+ /* we need a solvable for all other tags */
+ if (!s)
+ {
+ if (notfound)
+ continue; /* did not find the solvable to extend */
#if 0
- pool_debug(pool, SOLV_ERROR, "susetags: huh %d: %s?\n", pd.lineno, line);
+ pool_debug(pool, SOLV_WARN, "susetags: stray line: %d: %s\n", pd.lineno, line);
#endif
continue;
}
+
switch (tag)
{
case CTAG('=', 'P', 'r', 'v'): /* provides */
continue;
case CTAG('=', 'P', 'r', 'q'): /* pre-requires / packages required */
if (pd.kind)
- {
- s->requires = adddep(pool, &pd, s->requires, line, 0, 0); /* patterns: a required package */
- }
+ s->requires = adddep(pool, &pd, s->requires, line, 0, 0); /* pattern: package requires */
else
- s->requires = adddep(pool, &pd, s->requires, line, SOLVABLE_PREREQMARKER, 0); /* package: pre-requires */
+ s->requires = adddep(pool, &pd, s->requires, line, SOLVABLE_PREREQMARKER, 0); /* pre-requires */
continue;
case CTAG('=', 'O', 'b', 's'): /* obsoletes */
s->obsoletes = adddep(pool, &pd, s->obsoletes, line, 0, pd.kind);
case CTAG('=', 'P', 'e', 'n'): /* pattern: package enhances */
s->enhances = adddep(pool, &pd, s->enhances, line, 0, 0);
continue;
- case CTAG('=', 'V', 'e', 'r'): /* - version - */
- last_found_pack = 0;
- handle = 0;
- indesc++;
- if (createdpkgs)
- {
- solv_free(joinhash);
- joinhash = joinhash_init(repo, &joinhashm);
- createdpkgs = 0;
- }
- continue;
case CTAG('=', 'V', 'n', 'd'): /* vendor */
s->vendor = pool_str2id(pool, line + 6, 1);
continue;
k = atoi(line + 6);
if (k || !strcasecmp(line + 6, "true"))
repodata_set_void(data, handle, SOLVABLE_ISVISIBLE);
+ continue;
}
- continue;
case CTAG('=', 'S', 'h', 'r'):
{
Id name, evr, arch;
name = pool_str2id(pool, sp[0], 1);
evr = toevr(pool, &pd, sp[1], sp[2]);
arch = pool_str2id(pool, sp[3], 1);
- if (last_found_pack >= pd.nshare)
- {
- pd.share_with = solv_realloc2(pd.share_with, last_found_pack + 256, sizeof(*pd.share_with));
- memset(pd.share_with + pd.nshare, 0, (last_found_pack + 256 - pd.nshare) * sizeof(*pd.share_with));
- pd.nshare = last_found_pack + 256;
- }
- pd.share_with[last_found_pack].name = name;
- pd.share_with[last_found_pack].evr = evr;
- pd.share_with[last_found_pack].arch = arch;
+ record_share(&pd, handle, name, evr, arch);
if ((flags & SUSETAGS_RECORD_SHARES) != 0)
{
if (s->name == name)
case CTAG('=', 'C', 'k', 's'):
set_checksum(&pd, data, handle, SOLVABLE_CHECKSUM, line + 6);
break;
- case CTAG('=', 'L', 'a', 'n'):
- pd.language = solv_free(pd.language);
- memset(pd.langcache, 0, sizeof(pd.langcache));
- if (line[6])
- pd.language = solv_strdup(line + 6);
- break;
case CTAG('=', 'F', 'l', 's'):
{
}
break;
- case CTAG('=', 'P', 'a', 't'):
- case CTAG('=', 'P', 'k', 'g'):
- break;
-
default:
#if 0
pool_debug(pool, SOLV_WARN, "susetags: unknown line: %d: %s\n", pd.lineno, line);
#endif
break;
}
-
}
if (s)
finish_solvable(&pd, s, freshens);
solv_free(pd.filelist);
- /* Shared attributes
- * (e.g. multiple binaries built from same source)
- */
+ /* process shared attributes (e.g. multiple binaries built from same source) */
if (pd.nshare)
- {
- 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);
- }
- free(pd.share_with);
- map_free(&keyidmap);
- }
+ process_shares(&pd);
solv_free(joinhash);
repodata_free_dircache(data);