From: Michael Schroeder Date: Thu, 16 Feb 2012 15:08:56 +0000 (+0100) Subject: - fix filelist handling in repo_susetags and testcase X-Git-Tag: BASE-SuSE-Code-12_2-Branch~163 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39250693a91b40f63e7ad5e6c3b86f3b89426393;p=thirdparty%2Flibsolv.git - fix filelist handling in repo_susetags and testcase --- diff --git a/ext/repo_susetags.c b/ext/repo_susetags.c index d4528127..98b85ced 100644 --- a/ext/repo_susetags.c +++ b/ext/repo_susetags.c @@ -40,6 +40,9 @@ struct parsedata { char *language; /* the default language */ Id langcache[ID_NUM_INTERNAL]; /* cache for the default language */ int lineno; + char *filelist; + int afilelist; /* allocated */ + int nfilelist; /* used */ }; static char *flagtab[] = { @@ -396,65 +399,24 @@ finish_solvable(struct parsedata *pd, Solvable *s, Id handle, Offset freshens) { Pool *pool = pd->repo->pool; -#if 1 - /* move file provides to filelist */ - /* relies on the fact that rpm inserts self-provides at the end */ - if (s->provides && (pd->flags & REPO_EXTEND_SOLVABLES) == 0) + if (pd->nfilelist) { - Id *p, *lastreal, did; - const char *str, *sp; - lastreal = pd->repo->idarraydata + s->provides; - for (p = lastreal; *p; p++) - if (ISRELDEP(*p)) - lastreal = p + 1; - for (p = lastreal; *p; p++) - { - str = pool_id2str(pool, *p); - if (*str != '/') - lastreal = p + 1; - } - if (*lastreal) - { - for (p = lastreal; *p; p++) - { - char fname_buf[128]; - const char *fname; - str = pool_id2str(pool, *p); - sp = strrchr(str, '/'); - /* Need to copy filename now, before we add string that could - realloc the stringspace (and hence invalidate str). */ - fname = sp + 1; - if (strlen(fname) >= 128) - fname = solv_strdup(fname); - else - { - memcpy(fname_buf, fname, strlen(fname) + 1); - fname = fname_buf; - } - if (sp - str >= 128) - { - char *sdup = solv_strdup(str); - sdup[sp - str] = 0; - did = repodata_str2dir(pd->data, sdup, 1); - free(sdup); - } - else - { - char sdup[128]; - strncpy(sdup, str, sp - str); - sdup[sp - str] = 0; - did = repodata_str2dir(pd->data, sdup, 1); - } - if (!did) - did = repodata_str2dir(pd->data, "/", 1); - repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, did, fname); - if (fname != fname_buf) - free((char*)fname); - *p = 0; - } + int l; + Id did; + for (l = 0; l < pd->nfilelist; l += strlen(pd->filelist + l) + 1) + { + char *p = strrchr(pd->filelist + l, '/'); + if (!p) + continue; + *p++ = 0; + did = repodata_str2dir(pd->data, pd->filelist + l, 1); + p[-1] = '/'; + if (!did) + did = repodata_str2dir(pd->data, "/", 1); + repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, did, p); } + pd->nfilelist = 0; } -#endif /* A self provide, except for source packages. This is harmless to do twice (in case we see the same package twice). */ if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) @@ -918,6 +880,26 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int switch (tag) { case CTAG('=', 'P', 'r', 'v'): /* provides */ + if (line[6] == '/') + { + /* probably a filelist entry. stash it away for now */ + int l = strlen(line + 6) + 1; + if (pd.nfilelist + l > pd.afilelist) + { + pd.afilelist = pd.nfilelist + l + 512; + pd.filelist = solv_realloc(pd.filelist, pd.afilelist); + } + memcpy(pd.filelist + pd.nfilelist, line + 6, l); + pd.nfilelist += l; + break; + } + if (pd.nfilelist) + { + int l; + for (l = 0; l < pd.nfilelist; l += strlen(pd.filelist + l) + 1) + s->provides = repo_addid_dep(pd.repo, s->provides, pool_str2id(pool, pd.filelist + l, 1), 0); + pd.nfilelist = 0; + } s->provides = adddep(pool, &pd, s->provides, line, 0, pd.kind); continue; case CTAG('=', 'R', 'e', 'q'): /* requires */ @@ -1124,6 +1106,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int { char *p = strrchr(line + 6, '/'); Id did; + /* strip trailing slash */ if (p && p != line + 6 && !p[1]) { *p = 0; @@ -1168,6 +1151,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int if (s) finish_solvable(&pd, s, handle, freshens); + solv_free(pd.filelist); /* Shared attributes * (e.g. multiple binaries built from same source) diff --git a/ext/testcase.c b/ext/testcase.c index b9051903..b1ef07d5 100644 --- a/ext/testcase.c +++ b/ext/testcase.c @@ -707,7 +707,7 @@ writedeps(Repo *repo, FILE *fp, const char *tag, Id key, Solvable *s, Offset off } if (key == SOLVABLE_PROVIDES && id == SOLVABLE_FILEMARKER) { - prvdp = dp + 1; + prvdp = dp; continue; } idstr = pool_dep2str(pool, id); @@ -860,29 +860,23 @@ adddep(Repo *repo, Offset olddeps, char *str, Id marker) } static void -finish_solvable(Pool *pool, Repodata *data, Solvable *s) +finish_solvable(Pool *pool, Repodata *data, Solvable *s, char *filelist, int nfilelist) { - /* move file provides to filelist */ - if (s->provides) + if (nfilelist) { - Id *p, *lastreal, did; - lastreal = s->repo->idarraydata + s->provides; - for (p = lastreal; *p; p++) - if (ISRELDEP(*p)) - lastreal = p + 1; - for (p = lastreal; *p; p++) - if ((pool_id2str(pool, *p))[0] != '/') - lastreal = p + 1; - for (p = lastreal; *p; p++) + int l; + Id did; + for (l = 0; l < nfilelist; l += strlen(filelist + l) + 1) { - char *str = pool_tmpjoin(pool, pool_id2str(pool, *p), 0, 0); - char *sp = strrchr(str, '/'); - *sp++ = 0; - did = repodata_str2dir(data, str, 1); + char *p = strrchr(filelist + l, '/'); + if (!p) + continue; + *p++ = 0; + did = repodata_str2dir(data, filelist + l, 1); + p[-1] = '/'; if (!did) did = repodata_str2dir(data, "/", 1); - repodata_add_dirstr(data, s - pool->solvables, SOLVABLE_FILELIST, did, sp); - *p = 0; + repodata_add_dirstr(data, handle, SOLVABLE_FILELIST, did, p); } } if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) @@ -904,6 +898,9 @@ testcase_add_susetags(Repo *repo, FILE *fp, int flags) char *sp[5]; unsigned int t; int intag; + char *filelist = 0; + int afilelist = 0; + int nfilelist = 0; data = repo_add_repodata(repo, flags); s = 0; @@ -955,7 +952,8 @@ testcase_add_susetags(Repo *repo, FILE *fp, int flags) { case 'P' << 16 | 'k' << 8 | 'g': if (s) - finish_solvable(pool, data, s); + finish_solvable(pool, data, s, filelist, nfilelist); + nfilelist = 0; if (split(line + 5, sp, 5) != 4) break; s = pool_id2solvable(pool, repo_add_solvable(repo)); @@ -984,6 +982,25 @@ testcase_add_susetags(Repo *repo, FILE *fp, int flags) s->requires = adddep(repo, s->requires, line + 6, SOLVABLE_PREREQMARKER); break; case 'P' << 16 | 'r' << 8 | 'v': + if (line[6] == '/') + { + int l = strlen(line + 6) + 1; + if (nfilelist + l > afilelist) + { + afilelist = nfilelist + l + 512; + filelist = solv_realloc(filelist, afilelist); + } + memcpy(filelist + nfilelist, line + 6, l); + nfilelist += l; + break; + } + if (nfilelist) + { + int l; + for (l = 0; l < nfilelist; l += strlen(filelist + l) + 1) + s->provides = repo_addid_dep(repo, s->provides, pool_str2id(pool, filelist + l, 1), 0); + nfilelist = 0; + } s->provides = adddep(repo, s->provides, line + 6, 0); break; case 'O' << 16 | 'b' << 8 | 's': @@ -1009,10 +1026,11 @@ testcase_add_susetags(Repo *repo, FILE *fp, int flags) } } if (s) - finish_solvable(pool, data, s); + finish_solvable(pool, data, s, filelist, nfilelist); + solv_free(line); + solv_free(filelist); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); - solv_free(line); return 0; }