static void XMLCALL endElement(void *userData, const char *name) { //fprintf(stderr,"-tag: %s\n", name); struct parsedata *pd = userData; Pool *pool = pd->common.pool; Solvable *s = pd->solvable; Repo *repo = pd->common.repo; Id handle = pd->handle; Id id; char *p; if (pd->depth != pd->statedepth) { pd->depth--; // printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth); return; } /* ignore patterns & metadata */ if (pd->state == STATE_START && !strcmp(name, "patterns")) return; if (pd->state == STATE_START && !strcmp(name, "products")) return; //if (pd->state == STATE_START && !strcmp(name, "metadata")) // return; if (pd->state == STATE_SOLVABLE && !strcmp(name, "format")) return; pd->depth--; pd->statedepth--; switch (pd->state) { case STATE_SOLVABLE: if (pd->kind && !s->name) /* add namespace in case of NULL name */ s->name = str2id(pool, join2(pd->kind, ":", ""), 1); if (!s->arch) s->arch = ARCH_NOARCH; if (!s->evr) s->evr = ID_EMPTY; /* some patterns have this */ if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, pd->freshens); s->conflicts = repo_fix_conflicts(repo, s->conflicts); pd->freshens = 0; pd->kind = 0; break; case STATE_NAME: if (pd->kind) s->name = str2id(pool, join2(pd->kind, ":", pd->content), 1); else s->name = str2id(pool, pd->content, 1); break; case STATE_ARCH: s->arch = str2id(pool, pd->content, 1); break; case STATE_VENDOR: s->vendor = str2id(pool, pd->content, 1); break; case STATE_RPM_GROUP: repodata_set_poolstr(pd->data, handle, SOLVABLE_GROUP, pd->content); break; case STATE_RPM_LICENSE: repodata_set_poolstr(pd->data, handle, SOLVABLE_LICENSE, pd->content); break; case STATE_CHECKSUM: { Id type, index; type = sat_chksum_str2type(pd->tmpattr); if (!type) { fprintf(stderr, "Unknown checksum type: %d: %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr); exit(1); } if (strlen(pd->content) != 2 * sat_chksum_len(type)) { fprintf(stderr, "Invalid checksum length: %d: for %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr); exit(1); } repodata_set_checksum(pd->data, handle, SOLVABLE_CHECKSUM, type, pd->content); /* we save the checksum to solvable id relationship for extended metadata */ index = stringpool_str2id(&pd->cspool, pd->content, 1 /* create it */); if (index >= pd->ncscache) { pd->cscache = sat_zextend(pd->cscache, pd->ncscache, index + 1 - pd->ncscache, sizeof(Id), 255); pd->ncscache = index + 1; } /* add the checksum to the cache */ pd->cscache[index] = s - pool->solvables; break; } case STATE_FILE: #if 0 id = str2id(pool, pd->content, 1); s->provides = repo_addid_dep(repo, s->provides, id, SOLVABLE_FILEMARKER); #endif if ((p = strrchr(pd->content, '/')) != 0) { *p++ = 0; if (pd->lastdir && !strcmp(pd->lastdirstr, pd->content)) { id = pd->lastdir; } else { int l; id = repodata_str2dir(pd->data, pd->content, 1); l = strlen(pd->content) + 1; if (l > pd->lastdirstrl) { pd->lastdirstrl = l + 128; pd->lastdirstr = sat_realloc(pd->lastdirstr, pd->lastdirstrl); } strcpy(pd->lastdirstr, pd->content); pd->lastdir = id; } } else { p = pd->content; id = 0; } if (!id) id = repodata_str2dir(pd->data, "/", 1); repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, id, p); break; case STATE_SUMMARY: repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_SUMMARY, pd->tmplang), pd->content); break; case STATE_DESCRIPTION: set_description_author(pd->data, handle, pd->content, pd); break; case STATE_CATEGORY: repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_CATEGORY, pd->tmplang), pd->content); break; case STATE_DISTRIBUTION: repodata_set_poolstr(pd->data, handle, SOLVABLE_DISTRIBUTION, pd->content); break; case STATE_URL: if (pd->content[0]) repodata_set_str(pd->data, handle, SOLVABLE_URL, pd->content); break; case STATE_PACKAGER: if (pd->content[0]) repodata_set_poolstr(pd->data, handle, SOLVABLE_PACKAGER, pd->content); break; case STATE_SOURCERPM: set_sourcerpm(pd->data, s, handle, pd->content); break; case STATE_RELNOTESURL: if (pd->content[0]) { repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content); repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pool, "releasenotes", 1)); } break; case STATE_UPDATEURL: if (pd->content[0]) { repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content); repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pool, "update", 1)); } break; case STATE_OPTIONALURL: if (pd->content[0]) { repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content); repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pool, "optional", 1)); } break; case STATE_FLAG: if (pd->content[0]) repodata_set_poolstr(pd->data, handle, PRODUCT_FLAGS, pd->content); break; case STATE_EULA: if (pd->content[0]) repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_EULA, pd->tmplang), pd->content); break; case STATE_KEYWORD: if (pd->content[0]) repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_KEYWORDS, pd->content); break; case STATE_DISKUSAGE: if (pd->ndirs) commit_diskusage(pd, pd->handle); break; case STATE_ORDER: if (pd->content[0]) repodata_set_str(pd->data, pd->handle, SOLVABLE_ORDER, pd->content); default: break; } pd->state = pd->sbtab[pd->state]; pd->docontent = 0; // fprintf(stderr, "back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth); }
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; const char *flavor; 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 (name[0] == 's' && name[1] == 'r' && name[2] == 'c' && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->arch = ARCH_SRC; 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 : ""); /* ensure self-provides */ if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->provides = repo_addid_dep(pd->repo, s->provides, pool_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 */ flavor = findKernelFlavor(pd, s); if (flavor) { char *cflavor = solv_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 = pool_id2str(pool, prd->name); } else { depname = pool_id2str(pool, pid); } if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':')) { char newdep[100]; snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7); pid = pool_str2id(pool, newdep, 1); if (prd) pid = pool_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 = pool_id2str(pool, prd->name); } else { depname = pool_id2str(pool, pid); } if (!strncmp(depname, "kernel(", 7) && !strchr(depname, ':')) { char newdep[100]; snprintf(newdep, sizeof(newdep), "kernel(%s:%s", cflavor, depname + 7); pid = pool_str2id(pool, newdep, 1); if (prd) pid = pool_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 = pool_str2id(pool, pd->content, 1); break; case STATE_VENDOR: s->vendor = pool_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 || pool_evrcmp(pool, s->evr, evr, EVRCMP_COMPARE) <= 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 = pool_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); */ }