mirror of
git://projects.qi-hardware.com/wernermisc.git
synced 2024-11-22 11:05:23 +02:00
qpkg: merge identical versions in package databases
This avoids turning a prerequisite search into a massacre of, guessed, O(sqrt(2^requisites)). - gobble.c (gobble_buf, compact_pkg): if a package being added has the same version as an existing package with the same name, merge them and keep only one
This commit is contained in:
parent
0ca4751b77
commit
9b5480ab3e
@ -68,6 +68,26 @@
|
||||
while (0)
|
||||
|
||||
|
||||
#define DONE goto done
|
||||
|
||||
|
||||
static void compact_pkg(struct pkg *new)
|
||||
{
|
||||
struct pkg *old;
|
||||
|
||||
for (old = new->more; old; old = old->more)
|
||||
if (old->version == new->version)
|
||||
goto compact;
|
||||
return;
|
||||
|
||||
compact:
|
||||
new->id->value = new->more;
|
||||
old->installed = old->installed || new->installed;
|
||||
/* @@@ we may leak a little */
|
||||
free(new);
|
||||
}
|
||||
|
||||
|
||||
static void gobble_buf(const char *name, const char *buf, size_t len)
|
||||
{
|
||||
const char *end = buf+len;
|
||||
@ -78,7 +98,7 @@ static void gobble_buf(const char *name, const char *buf, size_t len)
|
||||
|
||||
initial:
|
||||
if (buf == end)
|
||||
return;
|
||||
DONE;
|
||||
if (*buf == '\n') {
|
||||
lineno++;
|
||||
buf++;
|
||||
@ -238,6 +258,9 @@ depends:
|
||||
goto list_with_version;
|
||||
|
||||
package:
|
||||
if (pkg)
|
||||
compact_pkg(pkg);
|
||||
|
||||
WHITESPACE;
|
||||
pkg = alloc_type(struct pkg);
|
||||
pkg->id = ID(packages);
|
||||
@ -280,12 +303,12 @@ eol:
|
||||
FAIL;
|
||||
lineno++;
|
||||
if (buf == end)
|
||||
return;
|
||||
DONE;
|
||||
if (*buf == ' ' || *buf == '\t')
|
||||
FAIL;
|
||||
goto initial;
|
||||
}
|
||||
return;
|
||||
DONE;
|
||||
|
||||
skip_data:
|
||||
while (buf != end) {
|
||||
@ -293,11 +316,11 @@ skip_data:
|
||||
continue;
|
||||
lineno++;
|
||||
if (buf == end)
|
||||
return;
|
||||
DONE;
|
||||
if (*buf != ' ' && *buf != '\t')
|
||||
goto initial;
|
||||
}
|
||||
return;
|
||||
DONE;
|
||||
|
||||
list_with_version:
|
||||
while (1) {
|
||||
@ -341,7 +364,7 @@ list_with_version:
|
||||
ref->next = *anchor;
|
||||
*anchor = ref;
|
||||
if (buf == end)
|
||||
return;
|
||||
DONE;
|
||||
if (*buf != ',')
|
||||
break;
|
||||
buf++;
|
||||
@ -349,6 +372,11 @@ list_with_version:
|
||||
anchor = NULL;
|
||||
goto eol;
|
||||
|
||||
done:
|
||||
if (pkg)
|
||||
compact_pkg(pkg);
|
||||
return;
|
||||
|
||||
fail:
|
||||
fprintf(stderr, "syntax derailment #%d at %s line %d: ",
|
||||
failed_at, name, lineno);
|
||||
|
Loading…
Reference in New Issue
Block a user