![](https://seccdn.libravatar.org/avatar/bc67c2666cfb0f5c7770293291610cc9.jpg?s=120&d=mm&r=g)
ref: refs/heads/master commit 0eaca8875a63b375ce9c060de5245b6045ac45a7 Author: Michael Schroeder <mls@suse.de> Date: Mon Jun 22 12:58:42 2009 +0200 - move repo_helix from src to ext --- ext/CMakeLists.txt | 4 +- ext/repo_helix.c | 874 +++++++++++++++++++++++++++++++++++++++++++ ext/repo_helix.h | 31 ++ src/CMakeLists.txt | 4 +- src/repo_helix.c | 874 ------------------------------------------- src/repo_helix.h | 31 -- tests/solver/CMakeLists.txt | 2 +- 7 files changed, 910 insertions(+), 910 deletions(-) diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index 8acf8c6..1f53aa8 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -1,12 +1,12 @@ SET(libsatsolverext_SRCS - pool_fileconflicts.c repo_content.c repo_deltainfoxml.c repo_products.c + pool_fileconflicts.c repo_content.c repo_deltainfoxml.c repo_helix.c repo_products.c repo_releasefile_products.c repo_repomdxml.c repo_rpmdb.c repo_rpmmd.c repo_susetags.c repo_updateinfoxml.c repo_write.c repo_zyppdb.c) ADD_LIBRARY(satsolverext STATIC ${libsatsolverext_SRCS}) SET(libsatsolver_HEADERS - pool_fileconflicts.h repo_content.h repo_deltainfoxml.h repo_products.h + pool_fileconflicts.h repo_content.h repo_deltainfoxml.h repo_helix.h repo_products.h repo_releasefile_products.h repo_repomdxml.h repo_rpmdb.h repo_rpmmd.h repo_susetags.h repo_updateinfoxml.h repo_write.h repo_zyppdb.h tools_util.h) diff --git a/ext/repo_helix.c b/ext/repo_helix.c new file mode 100644 index 0000000..fcff7c9 --- /dev/null +++ b/ext/repo_helix.c @@ -0,0 +1,874 @@ +/* + * Copyright (c) 2007, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +/* + * repo_helix.c + * + * Parse 'helix' XML representation + * and create 'repo' + * + */ + +#include <sys/types.h> +#include <limits.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <expat.h> + +#include "repo_helix.h" +#include "evr.h" + + +/* XML parser states */ + +enum state { + STATE_START, + STATE_CHANNEL, + STATE_SUBCHANNEL, + STATE_PACKAGE, + STATE_NAME, + STATE_VENDOR, + STATE_BUILDTIME, + STATE_HISTORY, + STATE_UPDATE, + STATE_EPOCH, + STATE_VERSION, + STATE_RELEASE, + STATE_ARCH, + STATE_PROVIDES, + STATE_PROVIDESENTRY, + STATE_REQUIRES, + STATE_REQUIRESENTRY, + STATE_PREREQUIRES, + STATE_PREREQUIRESENTRY, + STATE_OBSOLETES, + STATE_OBSOLETESENTRY, + STATE_CONFLICTS, + STATE_CONFLICTSENTRY, + STATE_RECOMMENDS, + STATE_RECOMMENDSENTRY, + STATE_SUPPLEMENTS, + STATE_SUPPLEMENTSENTRY, + STATE_SUGGESTS, + STATE_SUGGESTSENTRY, + STATE_ENHANCES, + STATE_ENHANCESENTRY, + STATE_FRESHENS, + STATE_FRESHENSENTRY, + + STATE_SELECTTION, + STATE_PATTERN, + STATE_ATOM, + STATE_PATCH, + STATE_PRODUCT, + + STATE_PEPOCH, + STATE_PVERSION, + STATE_PRELEASE, + STATE_PARCH, + + NUMSTATES +}; + +struct stateswitch { + enum state from; + char *ename; + enum state to; + int docontent; +}; + +static struct stateswitch stateswitches[] = { + { STATE_START, "channel", STATE_CHANNEL, 0 }, + { STATE_CHANNEL, "subchannel", STATE_SUBCHANNEL, 0 }, + { STATE_SUBCHANNEL, "package", STATE_PACKAGE, 0 }, + { STATE_SUBCHANNEL, "selection", STATE_PACKAGE, 0 }, + { STATE_SUBCHANNEL, "pattern", STATE_PACKAGE, 0 }, + { STATE_SUBCHANNEL, "atom", STATE_PACKAGE, 0 }, + { STATE_SUBCHANNEL, "patch", STATE_PACKAGE, 0 }, + { STATE_SUBCHANNEL, "product", STATE_PACKAGE, 0 }, + { STATE_PACKAGE, "name", STATE_NAME, 1 }, + { STATE_PACKAGE, "vendor", STATE_VENDOR, 1 }, + { STATE_PACKAGE, "buildtime", STATE_BUILDTIME, 1 }, + { STATE_PACKAGE, "epoch", STATE_PEPOCH, 1 }, + { STATE_PACKAGE, "version", STATE_PVERSION, 1 }, + { STATE_PACKAGE, "release", STATE_PRELEASE, 1 }, + { STATE_PACKAGE, "arch", STATE_PARCH, 1 }, + { STATE_PACKAGE, "history", STATE_HISTORY, 0 }, + { STATE_PACKAGE, "provides", STATE_PROVIDES, 0 }, + { STATE_PACKAGE, "requires", STATE_REQUIRES, 0 }, + { STATE_PACKAGE, "prerequires", STATE_PREREQUIRES, 0 }, + { STATE_PACKAGE, "obsoletes", STATE_OBSOLETES , 0 }, + { STATE_PACKAGE, "conflicts", STATE_CONFLICTS , 0 }, + { STATE_PACKAGE, "recommends" , STATE_RECOMMENDS , 0 }, + { STATE_PACKAGE, "supplements", STATE_SUPPLEMENTS, 0 }, + { STATE_PACKAGE, "suggests", STATE_SUGGESTS, 0 }, + { STATE_PACKAGE, "enhances", STATE_ENHANCES, 0 }, + { STATE_PACKAGE, "freshens", STATE_FRESHENS, 0 }, + + { STATE_HISTORY, "update", STATE_UPDATE, 0 }, + { STATE_UPDATE, "epoch", STATE_EPOCH, 1 }, + { STATE_UPDATE, "version", STATE_VERSION, 1 }, + { STATE_UPDATE, "release", STATE_RELEASE, 1 }, + { STATE_UPDATE, "arch", STATE_ARCH, 1 }, + + { STATE_PROVIDES, "dep", STATE_PROVIDESENTRY, 0 }, + { STATE_REQUIRES, "dep", STATE_REQUIRESENTRY, 0 }, + { STATE_PREREQUIRES, "dep", STATE_PREREQUIRESENTRY, 0 }, + { STATE_OBSOLETES, "dep", STATE_OBSOLETESENTRY, 0 }, + { STATE_CONFLICTS, "dep", STATE_CONFLICTSENTRY, 0 }, + { STATE_RECOMMENDS, "dep", STATE_RECOMMENDSENTRY, 0 }, + { STATE_SUPPLEMENTS, "dep", STATE_SUPPLEMENTSENTRY, 0 }, + { STATE_SUGGESTS, "dep", STATE_SUGGESTSENTRY, 0 }, + { STATE_ENHANCES, "dep", STATE_ENHANCESENTRY, 0 }, + { STATE_FRESHENS, "dep", STATE_FRESHENSENTRY, 0 }, + { NUMSTATES } + +}; + +/* + * parser data + */ + +typedef struct _parsedata { + // XML parser data + int depth; + enum state state; // current state + int statedepth; + char *content; // buffer for content of node + int lcontent; // actual length of current content + int acontent; // actual buffer size + int docontent; // handle content + + // repo data + Pool *pool; // current pool + Repo *repo; // current repo + Repodata *data; // current repo data + Solvable *solvable; // current solvable + Offset freshens; // current freshens vector + + // package data + int epoch; // epoch (as offset into evrspace) + int version; // version (as offset into evrspace) + int release; // release (as offset into evrspace) + char *evrspace; // buffer for evr + int aevrspace; // actual buffer space + int levrspace; // actual evr length + char *kind; + + struct stateswitch *swtab[NUMSTATES]; + enum state sbtab[NUMSTATES]; +} Parsedata; + + +/*------------------------------------------------------------------*/ +/* E:V-R handling */ + +// create Id from epoch:version-release + +static Id +evr2id(Pool *pool, Parsedata *pd, const char *e, const char *v, const char *r) +{ + char *c; + int l; + + // treat explitcit 0 as NULL + if (e && !strcmp(e, "0")) + e = NULL; + + if (v && !e) + { + const char *v2; + // scan version for ":" + for (v2 = v; *v2 >= '0' && *v2 <= '9'; v2++) // skip leading digits + ; + // if version contains ":", set epoch to "0" + if (v2 > v && *v2 == ':') + e = "0"; + } + + // compute length of Id string + l = 1; // for the \0 + if (e) + l += strlen(e) + 1; // e: + if (v) + l += strlen(v); // v + if (r) + l += strlen(r) + 1; // -r + + // extend content if not sufficient + if (l > pd->acontent) + { + pd->content = (char *)realloc(pd->content, l + 256); + pd->acontent = l + 256; + } + + // copy e-v-r to content + c = pd->content; + if (e) + { + strcpy(c, e); + c += strlen(c); + *c++ = ':'; + } + if (v) + { + strcpy(c, v); + c += strlen(c); + } + if (r) + { + *c++ = '-'; + strcpy(c, r); + c += strlen(c); + } + *c = 0; + // if nothing inserted, return Id 0 + if (!*pd->content) + return ID_NULL; +#if 0 + fprintf(stderr, "evr: %s\n", pd->content); +#endif + // intern and create + return str2id(pool, pd->content, 1); +} + + +// create e:v-r from attributes +// atts is array of name,value pairs, NULL at end +// even index into atts is name +// odd index is value +// +static Id +evr_atts2id(Pool *pool, Parsedata *pd, const char **atts) +{ + const char *e, *v, *r; + e = v = r = 0; + for (; *atts; atts += 2) + { + if (!strcmp(*atts, "epoch")) + e = atts[1]; + else if (!strcmp(*atts, "version")) + v = atts[1]; + else if (!strcmp(*atts, "release")) + r = atts[1]; + } + return evr2id(pool, pd, e, v, r); +} + +/*------------------------------------------------------------------*/ +/* rel operator handling */ + +struct flagtab { + char *from; + int to; +}; + +static struct flagtab flagtab[] = { + { ">", REL_GT }, + { "=", REL_EQ }, + { ">=", REL_GT|REL_EQ }, + { "<", REL_LT }, + { "!=", REL_GT|REL_LT }, + { "<=", REL_LT|REL_EQ }, + { "(any)", REL_LT|REL_EQ|REL_GT }, + { "==", REL_EQ }, + { "gt", REL_GT }, + { "eq", REL_EQ }, + { "ge", REL_GT|REL_EQ }, + { "lt", REL_LT }, + { "ne", REL_GT|REL_LT }, + { "le", REL_LT|REL_EQ }, + { "gte", REL_GT|REL_EQ }, + { "lte", REL_LT|REL_EQ }, + { "GT", REL_GT }, + { "EQ", REL_EQ }, + { "GE", REL_GT|REL_EQ }, + { "LT", REL_LT }, + { "NE", REL_GT|REL_LT }, + { "LE", REL_LT|REL_EQ } +}; + +/* + * process new dependency from parser + * olddeps = already collected deps, this defines the 'kind' of dep + * atts = array of name,value attributes of dep + * isreq == 1 if its a requires + */ + +static unsigned int +adddep(Pool *pool, Parsedata *pd, unsigned int olddeps, const char **atts, Id marker) +{ + Id id, name; + const char *n, *f, *k; + const char **a; + + n = f = k = NULL; + + /* loop over name,value pairs */ + for (a = atts; *a; a += 2) + { + if (!strcmp(*a, "name")) + n = a[1]; + if (!strcmp(*a, "kind")) + k = a[1]; + else if (!strcmp(*a, "op")) + f = a[1]; + else if (marker && !strcmp(*a, "pre") && a[1][0] == '1') + marker = SOLVABLE_PREREQMARKER; + } + if (!n) /* quit if no name found */ + return olddeps; + + /* kind, name */ + if (k && !strcmp(k, "package")) + k = NULL; /* package is default */ + + if (k) /* if kind!=package, intern <kind>:<name> */ + { + int l = strlen(k) + 1 + strlen(n) + 1; + if (l > pd->acontent) /* extend buffer if needed */ + { + pd->content = (char *)realloc(pd->content, l + 256); + pd->acontent = l + 256; + } + sprintf(pd->content, "%s:%s", k, n); + name = str2id(pool, pd->content, 1); + } + else + { + name = str2id(pool, n, 1); /* package: just intern <name> */ + } + + if (f) /* operator ? */ + { + /* intern e:v-r */ + Id evr = evr_atts2id(pool, pd, atts); + /* parser operator to flags */ + int flags; + for (flags = 0; flags < sizeof(flagtab)/sizeof(*flagtab); flags++) + if (!strcmp(f, flagtab[flags].from)) + { + flags = flagtab[flags].to; + break; + } + if (flags > 7) + flags = 0; + /* intern rel */ + id = rel2id(pool, name, evr, flags, 1); + } + else + id = name; /* no operator */ + + /* add new dependency to repo */ + return repo_addid_dep(pd->repo, olddeps, id, marker); +} + + +/*----------------------------------------------------------------*/ + +/* + * XML callback + * <name> + * + */ + +static void XMLCALL +startElement(void *userData, const char *name, const char **atts) +{ + Parsedata *pd = (Parsedata *)userData; + struct stateswitch *sw; + Pool *pool = pd->pool; + Solvable *s = pd->solvable; + + if (pd->depth != pd->statedepth) + { + pd->depth++; + return; + } + + /* ignore deps element */ + if (pd->state == STATE_PACKAGE && !strcmp(name, "deps")) + return; + + pd->depth++; + + /* find node name in stateswitch */ + if (!pd->swtab[pd->state]) + return; + for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++) + { + if (!strcmp(sw->ename, name)) + break; + } + + /* check if we're at the right level */ + if (sw->from != pd->state) + { +#if 0 + fprintf(stderr, "into unknown: %s\n", name); +#endif + return; + } + + // set new state + pd->state = sw->to; + + pd->docontent = sw->docontent; + pd->statedepth = pd->depth; + + // start with empty content + // (will collect data until end element + pd->lcontent = 0; + *pd->content = 0; + + switch (pd->state) + { + + case STATE_NAME: + if (pd->kind) /* if kind is set (non package) */ + { + strcpy(pd->content, pd->kind); + pd->lcontent = strlen(pd->content); + pd->content[pd->lcontent++] = ':'; /* prefix name with '<kind>:' */ + pd->content[pd->lcontent] = 0; + } + break; + + case STATE_PACKAGE: /* solvable name */ + pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo)); + if (!strcmp(name, "selection")) + pd->kind = "selection"; + else if (!strcmp(name, "pattern")) + pd->kind = "pattern"; + else if (!strcmp(name, "atom")) + pd->kind = "atom"; + else if (!strcmp(name, "product")) + pd->kind = "product"; + else if (!strcmp(name, "patch")) + pd->kind = "patch"; + else + pd->kind = NULL; /* default is package */ + pd->levrspace = 1; + pd->epoch = 0; + pd->version = 0; + pd->release = 0; + pd->freshens = 0; +#if 0 + fprintf(stderr, "package #%d\n", s - pool->solvables); +#endif + break; + + case STATE_UPDATE: + pd->levrspace = 1; + pd->epoch = 0; + pd->version = 0; + pd->release = 0; + break; + + case STATE_PROVIDES: /* start of provides */ + s->provides = 0; + break; + case STATE_PROVIDESENTRY: /* entry within provides */ + s->provides = adddep(pool, pd, s->provides, atts, 0); + break; + case STATE_REQUIRESENTRY: + s->requires = adddep(pool, pd, s->requires, atts, -SOLVABLE_PREREQMARKER); + break; + case STATE_PREREQUIRESENTRY: + s->requires = adddep(pool, pd, s->requires, atts, SOLVABLE_PREREQMARKER); + break; + case STATE_OBSOLETES: + s->obsoletes = 0; + break; + case STATE_OBSOLETESENTRY: + s->obsoletes = adddep(pool, pd, s->obsoletes, atts, 0); + break; + case STATE_CONFLICTS: + s->conflicts = 0; + break; + case STATE_CONFLICTSENTRY: + s->conflicts = adddep(pool, pd, s->conflicts, atts, 0); + break; + case STATE_RECOMMENDS: + s->recommends = 0; + break; + case STATE_RECOMMENDSENTRY: + s->recommends = adddep(pool, pd, s->recommends, atts, 0); + break; + case STATE_SUPPLEMENTS: + s->supplements= 0; + break; + case STATE_SUPPLEMENTSENTRY: + s->supplements = adddep(pool, pd, s->supplements, atts, 0); + break; + case STATE_SUGGESTS: + s->suggests = 0; + break; + case STATE_SUGGESTSENTRY: + s->suggests = adddep(pool, pd, s->suggests, atts, 0); + break; + case STATE_ENHANCES: + s->enhances = 0; + break; + case STATE_ENHANCESENTRY: + s->enhances = adddep(pool, pd, s->enhances, atts, 0); + break; + case STATE_FRESHENS: + pd->freshens = 0; + break; + case STATE_FRESHENSENTRY: + pd->freshens = adddep(pool, pd, pd->freshens, atts, 0); + break; + default: + break; + } +} + +static const char *findKernelFlavor(Parsedata *pd, Solvable *s) +{ + Pool *pool = pd->pool; + Id pid, *pidp; + + if (s->provides) + { + pidp = pd->repo->idarraydata + s->provides; + while ((pid = *pidp++) != 0) + { + Reldep *prd; + const char *depname; + + if (!ISRELDEP(pid)) + continue; /* wrong provides name */ + prd = GETRELDEP(pool, pid); + depname = id2str(pool, prd->name); + if (!strncmp(depname, "kernel-", 7)) + return depname + 7; + } + } + + if (s->requires) + { + pidp = pd->repo->idarraydata + s->requires; + while ((pid = *pidp++) != 0) + { + const char *depname; + + if (!ISRELDEP(pid)) + { + depname = id2str(pool, pid); + } + else + { + Reldep *prd = GETRELDEP(pool, pid); + depname = id2str(pool, prd->name); + } + if (!strncmp(depname, "kernel-", 7)) + return depname + 7; + } + } + + return 0; +} + + +/* + * XML callback + * </name> + * + * create Solvable from collected data + */ + +static void XMLCALL +endElement(void *userData, const char *name) +{ + Parsedata *pd = (Parsedata *)userData; + Pool *pool = pd->pool; + Solvable *s = pd->solvable; + Id evr; + unsigned int t = 0; + + if (pd->depth != pd->statedepth) + { + pd->depth--; + // printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth); + return; + } + + /* ignore deps element */ + if (pd->state == STATE_PACKAGE && !strcmp(name, "deps")) + return; + + pd->depth--; + pd->statedepth--; + switch (pd->state) + { + + case STATE_PACKAGE: /* package complete */ + if (!s->arch) /* default to "noarch" */ + s->arch = ARCH_NOARCH; + + if (!s->evr && pd->version) /* set solvable evr */ + s->evr = evr2id(pool, pd, + pd->epoch ? pd->evrspace + pd->epoch : 0, + pd->version ? pd->evrspace + pd->version : 0, + pd->release ? pd->evrspace + pd->release : 0); + /* ensure self-provides */ + if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) + s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); + s->supplements = repo_fix_supplements(pd->repo, s->provides, s->supplements, pd->freshens); + s->conflicts = repo_fix_conflicts(pd->repo, s->conflicts); + pd->freshens = 0; + + /* see bugzilla bnc#190163 */ + const char *flavor = findKernelFlavor(pd, s); + if (flavor) + { + char *cflavor = strdup(flavor); /* make pointer safe */ + + Id npr; + Id pid; + + /* this is either a kernel package or a kmp */ + if (s->provides) + { + Offset prov = s->provides; + npr = 0; + while ((pid = pd->repo->idarraydata[prov++]) != 0) + { + const char *depname = 0; + Reldep *prd = 0; + + if (ISRELDEP(pid)) + { + prd = GETRELDEP(pool, pid); + depname = id2str(pool, prd->name); + } + else + { + depname = id2str(pool, pid); + } + + + if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':')) + { + char newdep[100]; + snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7); + pid = str2id(pool, newdep, 1); + if (prd) + pid = rel2id(pool, pid, prd->evr, prd->flags, 1); + } + + npr = repo_addid_dep(pd->repo, npr, pid, 0); + } + s->provides = npr; + } +#if 1 + + if (s->requires) + { + Offset reqs = s->requires; + npr = 0; + while ((pid = pd->repo->idarraydata[reqs++]) != 0) + { + const char *depname = 0; + Reldep *prd = 0; + + if (ISRELDEP(pid)) + { + prd = GETRELDEP(pool, pid); + depname = id2str(pool, prd->name); + } + else + { + depname = id2str(pool, pid); + } + + if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':')) + { + char newdep[100]; + snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7); + pid = str2id(pool, newdep, 1); + if (prd) + pid = rel2id(pool, pid, prd->evr, prd->flags, 1); + } + npr = repo_addid_dep(pd->repo, npr, pid, 0); + } + s->requires = npr; + } +#endif + free(cflavor); + } + break; + case STATE_NAME: + s->name = str2id(pool, pd->content, 1); + break; + case STATE_VENDOR: + s->vendor = str2id(pool, pd->content, 1); + break; + case STATE_BUILDTIME: + t = atoi (pd->content); + if (t) + repodata_set_num(pd->data, s - pool->solvables, SOLVABLE_BUILDTIME, t); + break; + case STATE_UPDATE: /* new version, keeping all other metadata */ + evr = evr2id(pool, pd, + pd->epoch ? pd->evrspace + pd->epoch : 0, + pd->version ? pd->evrspace + pd->version : 0, + pd->release ? pd->evrspace + pd->release : 0); + pd->levrspace = 1; + pd->epoch = 0; + pd->version = 0; + pd->release = 0; + /* use highest evr */ + if (!s->evr || evrcmp(pool, s->evr, evr, EVRCMP_MATCH_RELEASE) <= 0) + s->evr = evr; + break; + case STATE_EPOCH: + case STATE_VERSION: + case STATE_RELEASE: + case STATE_PEPOCH: + case STATE_PVERSION: + case STATE_PRELEASE: + /* ensure buffer space */ + if (pd->lcontent + 1 + pd->levrspace > pd->aevrspace) + { + pd->evrspace = (char *)realloc(pd->evrspace, pd->lcontent + 1 + pd->levrspace + 256); + pd->aevrspace = pd->lcontent + 1 + pd->levrspace + 256; + } + memcpy(pd->evrspace + pd->levrspace, pd->content, pd->lcontent + 1); + if (pd->state == STATE_EPOCH || pd->state == STATE_PEPOCH) + pd->epoch = pd->levrspace; + else if (pd->state == STATE_VERSION || pd->state == STATE_PVERSION) + pd->version = pd->levrspace; + else + pd->release = pd->levrspace; + pd->levrspace += pd->lcontent + 1; + break; + case STATE_ARCH: + case STATE_PARCH: + s->arch = str2id(pool, pd->content, 1); + break; + default: + break; + } + pd->state = pd->sbtab[pd->state]; + pd->docontent = 0; + // printf("back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth); +} + + +/* + * XML callback + * character data + * + */ + +static void XMLCALL +characterData(void *userData, const XML_Char *s, int len) +{ + Parsedata *pd = (Parsedata *)userData; + int l; + char *c; + + // check if current nodes content is interesting + if (!pd->docontent) + return; + + // adapt content buffer + l = pd->lcontent + len + 1; + if (l > pd->acontent) + { + pd->content = (char *)realloc(pd->content, l + 256); + pd->acontent = l + 256; + } + // append new content to buffer + c = pd->content + pd->lcontent; + pd->lcontent += len; + while (len-- > 0) + *c++ = *s++; + *c = 0; +} + +/*-------------------------------------------------------------------*/ + +#define BUFF_SIZE 8192 + +/* + * read 'helix' type xml from fp + * add packages to pool/repo + * + */ + +void +repo_add_helix(Repo *repo, FILE *fp, int flags) +{ + Pool *pool = repo->pool; + Parsedata pd; + Repodata *data; + char buf[BUFF_SIZE]; + int i, l; + struct stateswitch *sw; + unsigned int now; + + now = sat_timems(0); + if (!(flags & REPO_REUSE_REPODATA)) + data = repo_add_repodata(repo, 0); + else + data = repo_last_repodata(repo); + + /* prepare parsedata */ + memset(&pd, 0, sizeof(pd)); + for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++) + { + if (!pd.swtab[sw->from]) + pd.swtab[sw->from] = sw; + pd.sbtab[sw->to] = sw->from; + } + + pd.pool = pool; + pd.repo = repo; + + pd.content = (char *)malloc(256); /* must hold all solvable kinds! */ + pd.acontent = 256; + pd.lcontent = 0; + + pd.evrspace = (char *)malloc(256); + pd.aevrspace= 256; + pd.levrspace = 1; + pd.data = data; + + // set up XML parser + + XML_Parser parser = XML_ParserCreate(NULL); + XML_SetUserData(parser, &pd); /* make parserdata available to XML callbacks */ + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, characterData); + + // read/parse XML file + for (;;) + { + l = fread(buf, 1, sizeof(buf), fp); + if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR) + { + pool_debug(pool, SAT_FATAL, "%s at line %u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser)); + exit(1); + } + if (l == 0) + break; + } + XML_ParserFree(parser); + free(pd.content); + free(pd.evrspace); + + if (!(flags & REPO_NO_INTERNALIZE)) + repodata_internalize(data); + POOL_DEBUG(SAT_DEBUG_STATS, "repo_add_helix took %d ms\n", sat_timems(now)); + POOL_DEBUG(SAT_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables); + POOL_DEBUG(SAT_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id))); +} diff --git a/ext/repo_helix.h b/ext/repo_helix.h new file mode 100644 index 0000000..78be384 --- /dev/null +++ b/ext/repo_helix.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2007, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +/* + * repo_helix.h + * + */ + +#ifndef SATSOLVER_REPO_HELIX_H +#define SATSOLVER_REPO_HELIX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include "pool.h" +#include "repo.h" + +extern void repo_add_helix(Repo *repo, FILE *fp, int flags); + +#ifdef __cplusplus +} +#endif + + +#endif /* SATSOLVER_REPO_HELIX_H */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 925d92f..bc42602 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ SET(libsatsolver_SRCS bitmap.c poolarch.c poolvendor.c poolid.c strpool.c dirpool.c - solver.c solverdebug.c repo_solv.c repo_helix.c evr.c pool.c + solver.c solverdebug.c repo_solv.c evr.c pool.c queue.c repo.c repodata.c repopage.c util.c policy.c solvable.c transaction.c rules.c problems.c) @@ -10,7 +10,7 @@ ADD_LIBRARY(satsolver STATIC ${libsatsolver_SRCS}) SET(libsatsolver_HEADERS bitmap.h evr.h hash.h policy.h poolarch.h poolvendor.h pool.h poolid.h pooltypes.h queue.h solvable.h solver.h solverdebug.h - repo.h repodata.h repopage.h repo_solv.h repo_helix.h util.h + repo.h repodata.h repopage.h repo_solv.h util.h strpool.h dirpool.h knownid.h transaction.h rules.h problems.h) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") diff --git a/src/repo_helix.c b/src/repo_helix.c deleted file mode 100644 index fcff7c9..0000000 --- a/src/repo_helix.c +++ /dev/null @@ -1,874 +0,0 @@ -/* - * Copyright (c) 2007, Novell Inc. - * - * This program is licensed under the BSD license, read LICENSE.BSD - * for further information - */ - -/* - * repo_helix.c - * - * Parse 'helix' XML representation - * and create 'repo' - * - */ - -#include <sys/types.h> -#include <limits.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <expat.h> - -#include "repo_helix.h" -#include "evr.h" - - -/* XML parser states */ - -enum state { - STATE_START, - STATE_CHANNEL, - STATE_SUBCHANNEL, - STATE_PACKAGE, - STATE_NAME, - STATE_VENDOR, - STATE_BUILDTIME, - STATE_HISTORY, - STATE_UPDATE, - STATE_EPOCH, - STATE_VERSION, - STATE_RELEASE, - STATE_ARCH, - STATE_PROVIDES, - STATE_PROVIDESENTRY, - STATE_REQUIRES, - STATE_REQUIRESENTRY, - STATE_PREREQUIRES, - STATE_PREREQUIRESENTRY, - STATE_OBSOLETES, - STATE_OBSOLETESENTRY, - STATE_CONFLICTS, - STATE_CONFLICTSENTRY, - STATE_RECOMMENDS, - STATE_RECOMMENDSENTRY, - STATE_SUPPLEMENTS, - STATE_SUPPLEMENTSENTRY, - STATE_SUGGESTS, - STATE_SUGGESTSENTRY, - STATE_ENHANCES, - STATE_ENHANCESENTRY, - STATE_FRESHENS, - STATE_FRESHENSENTRY, - - STATE_SELECTTION, - STATE_PATTERN, - STATE_ATOM, - STATE_PATCH, - STATE_PRODUCT, - - STATE_PEPOCH, - STATE_PVERSION, - STATE_PRELEASE, - STATE_PARCH, - - NUMSTATES -}; - -struct stateswitch { - enum state from; - char *ename; - enum state to; - int docontent; -}; - -static struct stateswitch stateswitches[] = { - { STATE_START, "channel", STATE_CHANNEL, 0 }, - { STATE_CHANNEL, "subchannel", STATE_SUBCHANNEL, 0 }, - { STATE_SUBCHANNEL, "package", STATE_PACKAGE, 0 }, - { STATE_SUBCHANNEL, "selection", STATE_PACKAGE, 0 }, - { STATE_SUBCHANNEL, "pattern", STATE_PACKAGE, 0 }, - { STATE_SUBCHANNEL, "atom", STATE_PACKAGE, 0 }, - { STATE_SUBCHANNEL, "patch", STATE_PACKAGE, 0 }, - { STATE_SUBCHANNEL, "product", STATE_PACKAGE, 0 }, - { STATE_PACKAGE, "name", STATE_NAME, 1 }, - { STATE_PACKAGE, "vendor", STATE_VENDOR, 1 }, - { STATE_PACKAGE, "buildtime", STATE_BUILDTIME, 1 }, - { STATE_PACKAGE, "epoch", STATE_PEPOCH, 1 }, - { STATE_PACKAGE, "version", STATE_PVERSION, 1 }, - { STATE_PACKAGE, "release", STATE_PRELEASE, 1 }, - { STATE_PACKAGE, "arch", STATE_PARCH, 1 }, - { STATE_PACKAGE, "history", STATE_HISTORY, 0 }, - { STATE_PACKAGE, "provides", STATE_PROVIDES, 0 }, - { STATE_PACKAGE, "requires", STATE_REQUIRES, 0 }, - { STATE_PACKAGE, "prerequires", STATE_PREREQUIRES, 0 }, - { STATE_PACKAGE, "obsoletes", STATE_OBSOLETES , 0 }, - { STATE_PACKAGE, "conflicts", STATE_CONFLICTS , 0 }, - { STATE_PACKAGE, "recommends" , STATE_RECOMMENDS , 0 }, - { STATE_PACKAGE, "supplements", STATE_SUPPLEMENTS, 0 }, - { STATE_PACKAGE, "suggests", STATE_SUGGESTS, 0 }, - { STATE_PACKAGE, "enhances", STATE_ENHANCES, 0 }, - { STATE_PACKAGE, "freshens", STATE_FRESHENS, 0 }, - - { STATE_HISTORY, "update", STATE_UPDATE, 0 }, - { STATE_UPDATE, "epoch", STATE_EPOCH, 1 }, - { STATE_UPDATE, "version", STATE_VERSION, 1 }, - { STATE_UPDATE, "release", STATE_RELEASE, 1 }, - { STATE_UPDATE, "arch", STATE_ARCH, 1 }, - - { STATE_PROVIDES, "dep", STATE_PROVIDESENTRY, 0 }, - { STATE_REQUIRES, "dep", STATE_REQUIRESENTRY, 0 }, - { STATE_PREREQUIRES, "dep", STATE_PREREQUIRESENTRY, 0 }, - { STATE_OBSOLETES, "dep", STATE_OBSOLETESENTRY, 0 }, - { STATE_CONFLICTS, "dep", STATE_CONFLICTSENTRY, 0 }, - { STATE_RECOMMENDS, "dep", STATE_RECOMMENDSENTRY, 0 }, - { STATE_SUPPLEMENTS, "dep", STATE_SUPPLEMENTSENTRY, 0 }, - { STATE_SUGGESTS, "dep", STATE_SUGGESTSENTRY, 0 }, - { STATE_ENHANCES, "dep", STATE_ENHANCESENTRY, 0 }, - { STATE_FRESHENS, "dep", STATE_FRESHENSENTRY, 0 }, - { NUMSTATES } - -}; - -/* - * parser data - */ - -typedef struct _parsedata { - // XML parser data - int depth; - enum state state; // current state - int statedepth; - char *content; // buffer for content of node - int lcontent; // actual length of current content - int acontent; // actual buffer size - int docontent; // handle content - - // repo data - Pool *pool; // current pool - Repo *repo; // current repo - Repodata *data; // current repo data - Solvable *solvable; // current solvable - Offset freshens; // current freshens vector - - // package data - int epoch; // epoch (as offset into evrspace) - int version; // version (as offset into evrspace) - int release; // release (as offset into evrspace) - char *evrspace; // buffer for evr - int aevrspace; // actual buffer space - int levrspace; // actual evr length - char *kind; - - struct stateswitch *swtab[NUMSTATES]; - enum state sbtab[NUMSTATES]; -} Parsedata; - - -/*------------------------------------------------------------------*/ -/* E:V-R handling */ - -// create Id from epoch:version-release - -static Id -evr2id(Pool *pool, Parsedata *pd, const char *e, const char *v, const char *r) -{ - char *c; - int l; - - // treat explitcit 0 as NULL - if (e && !strcmp(e, "0")) - e = NULL; - - if (v && !e) - { - const char *v2; - // scan version for ":" - for (v2 = v; *v2 >= '0' && *v2 <= '9'; v2++) // skip leading digits - ; - // if version contains ":", set epoch to "0" - if (v2 > v && *v2 == ':') - e = "0"; - } - - // compute length of Id string - l = 1; // for the \0 - if (e) - l += strlen(e) + 1; // e: - if (v) - l += strlen(v); // v - if (r) - l += strlen(r) + 1; // -r - - // extend content if not sufficient - if (l > pd->acontent) - { - pd->content = (char *)realloc(pd->content, l + 256); - pd->acontent = l + 256; - } - - // copy e-v-r to content - c = pd->content; - if (e) - { - strcpy(c, e); - c += strlen(c); - *c++ = ':'; - } - if (v) - { - strcpy(c, v); - c += strlen(c); - } - if (r) - { - *c++ = '-'; - strcpy(c, r); - c += strlen(c); - } - *c = 0; - // if nothing inserted, return Id 0 - if (!*pd->content) - return ID_NULL; -#if 0 - fprintf(stderr, "evr: %s\n", pd->content); -#endif - // intern and create - return str2id(pool, pd->content, 1); -} - - -// create e:v-r from attributes -// atts is array of name,value pairs, NULL at end -// even index into atts is name -// odd index is value -// -static Id -evr_atts2id(Pool *pool, Parsedata *pd, const char **atts) -{ - const char *e, *v, *r; - e = v = r = 0; - for (; *atts; atts += 2) - { - if (!strcmp(*atts, "epoch")) - e = atts[1]; - else if (!strcmp(*atts, "version")) - v = atts[1]; - else if (!strcmp(*atts, "release")) - r = atts[1]; - } - return evr2id(pool, pd, e, v, r); -} - -/*------------------------------------------------------------------*/ -/* rel operator handling */ - -struct flagtab { - char *from; - int to; -}; - -static struct flagtab flagtab[] = { - { ">", REL_GT }, - { "=", REL_EQ }, - { ">=", REL_GT|REL_EQ }, - { "<", REL_LT }, - { "!=", REL_GT|REL_LT }, - { "<=", REL_LT|REL_EQ }, - { "(any)", REL_LT|REL_EQ|REL_GT }, - { "==", REL_EQ }, - { "gt", REL_GT }, - { "eq", REL_EQ }, - { "ge", REL_GT|REL_EQ }, - { "lt", REL_LT }, - { "ne", REL_GT|REL_LT }, - { "le", REL_LT|REL_EQ }, - { "gte", REL_GT|REL_EQ }, - { "lte", REL_LT|REL_EQ }, - { "GT", REL_GT }, - { "EQ", REL_EQ }, - { "GE", REL_GT|REL_EQ }, - { "LT", REL_LT }, - { "NE", REL_GT|REL_LT }, - { "LE", REL_LT|REL_EQ } -}; - -/* - * process new dependency from parser - * olddeps = already collected deps, this defines the 'kind' of dep - * atts = array of name,value attributes of dep - * isreq == 1 if its a requires - */ - -static unsigned int -adddep(Pool *pool, Parsedata *pd, unsigned int olddeps, const char **atts, Id marker) -{ - Id id, name; - const char *n, *f, *k; - const char **a; - - n = f = k = NULL; - - /* loop over name,value pairs */ - for (a = atts; *a; a += 2) - { - if (!strcmp(*a, "name")) - n = a[1]; - if (!strcmp(*a, "kind")) - k = a[1]; - else if (!strcmp(*a, "op")) - f = a[1]; - else if (marker && !strcmp(*a, "pre") && a[1][0] == '1') - marker = SOLVABLE_PREREQMARKER; - } - if (!n) /* quit if no name found */ - return olddeps; - - /* kind, name */ - if (k && !strcmp(k, "package")) - k = NULL; /* package is default */ - - if (k) /* if kind!=package, intern <kind>:<name> */ - { - int l = strlen(k) + 1 + strlen(n) + 1; - if (l > pd->acontent) /* extend buffer if needed */ - { - pd->content = (char *)realloc(pd->content, l + 256); - pd->acontent = l + 256; - } - sprintf(pd->content, "%s:%s", k, n); - name = str2id(pool, pd->content, 1); - } - else - { - name = str2id(pool, n, 1); /* package: just intern <name> */ - } - - if (f) /* operator ? */ - { - /* intern e:v-r */ - Id evr = evr_atts2id(pool, pd, atts); - /* parser operator to flags */ - int flags; - for (flags = 0; flags < sizeof(flagtab)/sizeof(*flagtab); flags++) - if (!strcmp(f, flagtab[flags].from)) - { - flags = flagtab[flags].to; - break; - } - if (flags > 7) - flags = 0; - /* intern rel */ - id = rel2id(pool, name, evr, flags, 1); - } - else - id = name; /* no operator */ - - /* add new dependency to repo */ - return repo_addid_dep(pd->repo, olddeps, id, marker); -} - - -/*----------------------------------------------------------------*/ - -/* - * XML callback - * <name> - * - */ - -static void XMLCALL -startElement(void *userData, const char *name, const char **atts) -{ - Parsedata *pd = (Parsedata *)userData; - struct stateswitch *sw; - Pool *pool = pd->pool; - Solvable *s = pd->solvable; - - if (pd->depth != pd->statedepth) - { - pd->depth++; - return; - } - - /* ignore deps element */ - if (pd->state == STATE_PACKAGE && !strcmp(name, "deps")) - return; - - pd->depth++; - - /* find node name in stateswitch */ - if (!pd->swtab[pd->state]) - return; - for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++) - { - if (!strcmp(sw->ename, name)) - break; - } - - /* check if we're at the right level */ - if (sw->from != pd->state) - { -#if 0 - fprintf(stderr, "into unknown: %s\n", name); -#endif - return; - } - - // set new state - pd->state = sw->to; - - pd->docontent = sw->docontent; - pd->statedepth = pd->depth; - - // start with empty content - // (will collect data until end element - pd->lcontent = 0; - *pd->content = 0; - - switch (pd->state) - { - - case STATE_NAME: - if (pd->kind) /* if kind is set (non package) */ - { - strcpy(pd->content, pd->kind); - pd->lcontent = strlen(pd->content); - pd->content[pd->lcontent++] = ':'; /* prefix name with '<kind>:' */ - pd->content[pd->lcontent] = 0; - } - break; - - case STATE_PACKAGE: /* solvable name */ - pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo)); - if (!strcmp(name, "selection")) - pd->kind = "selection"; - else if (!strcmp(name, "pattern")) - pd->kind = "pattern"; - else if (!strcmp(name, "atom")) - pd->kind = "atom"; - else if (!strcmp(name, "product")) - pd->kind = "product"; - else if (!strcmp(name, "patch")) - pd->kind = "patch"; - else - pd->kind = NULL; /* default is package */ - pd->levrspace = 1; - pd->epoch = 0; - pd->version = 0; - pd->release = 0; - pd->freshens = 0; -#if 0 - fprintf(stderr, "package #%d\n", s - pool->solvables); -#endif - break; - - case STATE_UPDATE: - pd->levrspace = 1; - pd->epoch = 0; - pd->version = 0; - pd->release = 0; - break; - - case STATE_PROVIDES: /* start of provides */ - s->provides = 0; - break; - case STATE_PROVIDESENTRY: /* entry within provides */ - s->provides = adddep(pool, pd, s->provides, atts, 0); - break; - case STATE_REQUIRESENTRY: - s->requires = adddep(pool, pd, s->requires, atts, -SOLVABLE_PREREQMARKER); - break; - case STATE_PREREQUIRESENTRY: - s->requires = adddep(pool, pd, s->requires, atts, SOLVABLE_PREREQMARKER); - break; - case STATE_OBSOLETES: - s->obsoletes = 0; - break; - case STATE_OBSOLETESENTRY: - s->obsoletes = adddep(pool, pd, s->obsoletes, atts, 0); - break; - case STATE_CONFLICTS: - s->conflicts = 0; - break; - case STATE_CONFLICTSENTRY: - s->conflicts = adddep(pool, pd, s->conflicts, atts, 0); - break; - case STATE_RECOMMENDS: - s->recommends = 0; - break; - case STATE_RECOMMENDSENTRY: - s->recommends = adddep(pool, pd, s->recommends, atts, 0); - break; - case STATE_SUPPLEMENTS: - s->supplements= 0; - break; - case STATE_SUPPLEMENTSENTRY: - s->supplements = adddep(pool, pd, s->supplements, atts, 0); - break; - case STATE_SUGGESTS: - s->suggests = 0; - break; - case STATE_SUGGESTSENTRY: - s->suggests = adddep(pool, pd, s->suggests, atts, 0); - break; - case STATE_ENHANCES: - s->enhances = 0; - break; - case STATE_ENHANCESENTRY: - s->enhances = adddep(pool, pd, s->enhances, atts, 0); - break; - case STATE_FRESHENS: - pd->freshens = 0; - break; - case STATE_FRESHENSENTRY: - pd->freshens = adddep(pool, pd, pd->freshens, atts, 0); - break; - default: - break; - } -} - -static const char *findKernelFlavor(Parsedata *pd, Solvable *s) -{ - Pool *pool = pd->pool; - Id pid, *pidp; - - if (s->provides) - { - pidp = pd->repo->idarraydata + s->provides; - while ((pid = *pidp++) != 0) - { - Reldep *prd; - const char *depname; - - if (!ISRELDEP(pid)) - continue; /* wrong provides name */ - prd = GETRELDEP(pool, pid); - depname = id2str(pool, prd->name); - if (!strncmp(depname, "kernel-", 7)) - return depname + 7; - } - } - - if (s->requires) - { - pidp = pd->repo->idarraydata + s->requires; - while ((pid = *pidp++) != 0) - { - const char *depname; - - if (!ISRELDEP(pid)) - { - depname = id2str(pool, pid); - } - else - { - Reldep *prd = GETRELDEP(pool, pid); - depname = id2str(pool, prd->name); - } - if (!strncmp(depname, "kernel-", 7)) - return depname + 7; - } - } - - return 0; -} - - -/* - * XML callback - * </name> - * - * create Solvable from collected data - */ - -static void XMLCALL -endElement(void *userData, const char *name) -{ - Parsedata *pd = (Parsedata *)userData; - Pool *pool = pd->pool; - Solvable *s = pd->solvable; - Id evr; - unsigned int t = 0; - - if (pd->depth != pd->statedepth) - { - pd->depth--; - // printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth); - return; - } - - /* ignore deps element */ - if (pd->state == STATE_PACKAGE && !strcmp(name, "deps")) - return; - - pd->depth--; - pd->statedepth--; - switch (pd->state) - { - - case STATE_PACKAGE: /* package complete */ - if (!s->arch) /* default to "noarch" */ - s->arch = ARCH_NOARCH; - - if (!s->evr && pd->version) /* set solvable evr */ - s->evr = evr2id(pool, pd, - pd->epoch ? pd->evrspace + pd->epoch : 0, - pd->version ? pd->evrspace + pd->version : 0, - pd->release ? pd->evrspace + pd->release : 0); - /* ensure self-provides */ - if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) - s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); - s->supplements = repo_fix_supplements(pd->repo, s->provides, s->supplements, pd->freshens); - s->conflicts = repo_fix_conflicts(pd->repo, s->conflicts); - pd->freshens = 0; - - /* see bugzilla bnc#190163 */ - const char *flavor = findKernelFlavor(pd, s); - if (flavor) - { - char *cflavor = strdup(flavor); /* make pointer safe */ - - Id npr; - Id pid; - - /* this is either a kernel package or a kmp */ - if (s->provides) - { - Offset prov = s->provides; - npr = 0; - while ((pid = pd->repo->idarraydata[prov++]) != 0) - { - const char *depname = 0; - Reldep *prd = 0; - - if (ISRELDEP(pid)) - { - prd = GETRELDEP(pool, pid); - depname = id2str(pool, prd->name); - } - else - { - depname = id2str(pool, pid); - } - - - if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':')) - { - char newdep[100]; - snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7); - pid = str2id(pool, newdep, 1); - if (prd) - pid = rel2id(pool, pid, prd->evr, prd->flags, 1); - } - - npr = repo_addid_dep(pd->repo, npr, pid, 0); - } - s->provides = npr; - } -#if 1 - - if (s->requires) - { - Offset reqs = s->requires; - npr = 0; - while ((pid = pd->repo->idarraydata[reqs++]) != 0) - { - const char *depname = 0; - Reldep *prd = 0; - - if (ISRELDEP(pid)) - { - prd = GETRELDEP(pool, pid); - depname = id2str(pool, prd->name); - } - else - { - depname = id2str(pool, pid); - } - - if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':')) - { - char newdep[100]; - snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7); - pid = str2id(pool, newdep, 1); - if (prd) - pid = rel2id(pool, pid, prd->evr, prd->flags, 1); - } - npr = repo_addid_dep(pd->repo, npr, pid, 0); - } - s->requires = npr; - } -#endif - free(cflavor); - } - break; - case STATE_NAME: - s->name = str2id(pool, pd->content, 1); - break; - case STATE_VENDOR: - s->vendor = str2id(pool, pd->content, 1); - break; - case STATE_BUILDTIME: - t = atoi (pd->content); - if (t) - repodata_set_num(pd->data, s - pool->solvables, SOLVABLE_BUILDTIME, t); - break; - case STATE_UPDATE: /* new version, keeping all other metadata */ - evr = evr2id(pool, pd, - pd->epoch ? pd->evrspace + pd->epoch : 0, - pd->version ? pd->evrspace + pd->version : 0, - pd->release ? pd->evrspace + pd->release : 0); - pd->levrspace = 1; - pd->epoch = 0; - pd->version = 0; - pd->release = 0; - /* use highest evr */ - if (!s->evr || evrcmp(pool, s->evr, evr, EVRCMP_MATCH_RELEASE) <= 0) - s->evr = evr; - break; - case STATE_EPOCH: - case STATE_VERSION: - case STATE_RELEASE: - case STATE_PEPOCH: - case STATE_PVERSION: - case STATE_PRELEASE: - /* ensure buffer space */ - if (pd->lcontent + 1 + pd->levrspace > pd->aevrspace) - { - pd->evrspace = (char *)realloc(pd->evrspace, pd->lcontent + 1 + pd->levrspace + 256); - pd->aevrspace = pd->lcontent + 1 + pd->levrspace + 256; - } - memcpy(pd->evrspace + pd->levrspace, pd->content, pd->lcontent + 1); - if (pd->state == STATE_EPOCH || pd->state == STATE_PEPOCH) - pd->epoch = pd->levrspace; - else if (pd->state == STATE_VERSION || pd->state == STATE_PVERSION) - pd->version = pd->levrspace; - else - pd->release = pd->levrspace; - pd->levrspace += pd->lcontent + 1; - break; - case STATE_ARCH: - case STATE_PARCH: - s->arch = str2id(pool, pd->content, 1); - break; - default: - break; - } - pd->state = pd->sbtab[pd->state]; - pd->docontent = 0; - // printf("back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth); -} - - -/* - * XML callback - * character data - * - */ - -static void XMLCALL -characterData(void *userData, const XML_Char *s, int len) -{ - Parsedata *pd = (Parsedata *)userData; - int l; - char *c; - - // check if current nodes content is interesting - if (!pd->docontent) - return; - - // adapt content buffer - l = pd->lcontent + len + 1; - if (l > pd->acontent) - { - pd->content = (char *)realloc(pd->content, l + 256); - pd->acontent = l + 256; - } - // append new content to buffer - c = pd->content + pd->lcontent; - pd->lcontent += len; - while (len-- > 0) - *c++ = *s++; - *c = 0; -} - -/*-------------------------------------------------------------------*/ - -#define BUFF_SIZE 8192 - -/* - * read 'helix' type xml from fp - * add packages to pool/repo - * - */ - -void -repo_add_helix(Repo *repo, FILE *fp, int flags) -{ - Pool *pool = repo->pool; - Parsedata pd; - Repodata *data; - char buf[BUFF_SIZE]; - int i, l; - struct stateswitch *sw; - unsigned int now; - - now = sat_timems(0); - if (!(flags & REPO_REUSE_REPODATA)) - data = repo_add_repodata(repo, 0); - else - data = repo_last_repodata(repo); - - /* prepare parsedata */ - memset(&pd, 0, sizeof(pd)); - for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++) - { - if (!pd.swtab[sw->from]) - pd.swtab[sw->from] = sw; - pd.sbtab[sw->to] = sw->from; - } - - pd.pool = pool; - pd.repo = repo; - - pd.content = (char *)malloc(256); /* must hold all solvable kinds! */ - pd.acontent = 256; - pd.lcontent = 0; - - pd.evrspace = (char *)malloc(256); - pd.aevrspace= 256; - pd.levrspace = 1; - pd.data = data; - - // set up XML parser - - XML_Parser parser = XML_ParserCreate(NULL); - XML_SetUserData(parser, &pd); /* make parserdata available to XML callbacks */ - XML_SetElementHandler(parser, startElement, endElement); - XML_SetCharacterDataHandler(parser, characterData); - - // read/parse XML file - for (;;) - { - l = fread(buf, 1, sizeof(buf), fp); - if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR) - { - pool_debug(pool, SAT_FATAL, "%s at line %u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser)); - exit(1); - } - if (l == 0) - break; - } - XML_ParserFree(parser); - free(pd.content); - free(pd.evrspace); - - if (!(flags & REPO_NO_INTERNALIZE)) - repodata_internalize(data); - POOL_DEBUG(SAT_DEBUG_STATS, "repo_add_helix took %d ms\n", sat_timems(now)); - POOL_DEBUG(SAT_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables); - POOL_DEBUG(SAT_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id))); -} diff --git a/src/repo_helix.h b/src/repo_helix.h deleted file mode 100644 index 78be384..0000000 --- a/src/repo_helix.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2007, Novell Inc. - * - * This program is licensed under the BSD license, read LICENSE.BSD - * for further information - */ - -/* - * repo_helix.h - * - */ - -#ifndef SATSOLVER_REPO_HELIX_H -#define SATSOLVER_REPO_HELIX_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdio.h> -#include "pool.h" -#include "repo.h" - -extern void repo_add_helix(Repo *repo, FILE *fp, int flags); - -#ifdef __cplusplus -} -#endif - - -#endif /* SATSOLVER_REPO_HELIX_H */ diff --git a/tests/solver/CMakeLists.txt b/tests/solver/CMakeLists.txt index 8e2b523..9fbed2b 100644 --- a/tests/solver/CMakeLists.txt +++ b/tests/solver/CMakeLists.txt @@ -10,7 +10,7 @@ TARGET_LINK_LIBRARIES(gimmick satsolver) SET(deptestomatic_SOURCES deptestomatic.c) ADD_EXECUTABLE(deptestomatic ${deptestomatic_SOURCES}) -TARGET_LINK_LIBRARIES(deptestomatic satsolver ${EXPAT_LIBRARY} ${ZLIB_LIBRARY}) +TARGET_LINK_LIBRARIES(deptestomatic satsolverext satsolver ${EXPAT_LIBRARY} ${ZLIB_LIBRARY}) install(TARGETS deptestomatic -- To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org For additional commands, e-mail: zypp-commit+help@opensuse.org