1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-14 19:57:31 +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:
Werner Almesberger 2010-11-19 15:41:04 -03:00
parent 0ca4751b77
commit 9b5480ab3e

View File

@ -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);