1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-22 10:37:09 +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) 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) static void gobble_buf(const char *name, const char *buf, size_t len)
{ {
const char *end = buf+len; const char *end = buf+len;
@ -78,7 +98,7 @@ static void gobble_buf(const char *name, const char *buf, size_t len)
initial: initial:
if (buf == end) if (buf == end)
return; DONE;
if (*buf == '\n') { if (*buf == '\n') {
lineno++; lineno++;
buf++; buf++;
@ -238,6 +258,9 @@ depends:
goto list_with_version; goto list_with_version;
package: package:
if (pkg)
compact_pkg(pkg);
WHITESPACE; WHITESPACE;
pkg = alloc_type(struct pkg); pkg = alloc_type(struct pkg);
pkg->id = ID(packages); pkg->id = ID(packages);
@ -280,12 +303,12 @@ eol:
FAIL; FAIL;
lineno++; lineno++;
if (buf == end) if (buf == end)
return; DONE;
if (*buf == ' ' || *buf == '\t') if (*buf == ' ' || *buf == '\t')
FAIL; FAIL;
goto initial; goto initial;
} }
return; DONE;
skip_data: skip_data:
while (buf != end) { while (buf != end) {
@ -293,11 +316,11 @@ skip_data:
continue; continue;
lineno++; lineno++;
if (buf == end) if (buf == end)
return; DONE;
if (*buf != ' ' && *buf != '\t') if (*buf != ' ' && *buf != '\t')
goto initial; goto initial;
} }
return; DONE;
list_with_version: list_with_version:
while (1) { while (1) {
@ -341,7 +364,7 @@ list_with_version:
ref->next = *anchor; ref->next = *anchor;
*anchor = ref; *anchor = ref;
if (buf == end) if (buf == end)
return; DONE;
if (*buf != ',') if (*buf != ',')
break; break;
buf++; buf++;
@ -349,6 +372,11 @@ list_with_version:
anchor = NULL; anchor = NULL;
goto eol; goto eol;
done:
if (pkg)
compact_pkg(pkg);
return;
fail: fail:
fprintf(stderr, "syntax derailment #%d at %s line %d: ", fprintf(stderr, "syntax derailment #%d at %s line %d: ",
failed_at, name, lineno); failed_at, name, lineno);