278 lines
8.0 KiB
Diff
278 lines
8.0 KiB
Diff
|
From 6ac793b215ac8d9db99d9632cbf71b014c7ffee0 Mon Sep 17 00:00:00 2001
|
||
|
From: Lubos Kardos <lkardos@redhat.com>
|
||
|
Date: Thu, 12 May 2016 16:28:09 +0200
|
||
|
Subject: [PATCH] Filter unversioned deps if corresponding versioned deps exist
|
||
|
(rhbz:678605)
|
||
|
|
||
|
After automatic dependencies are generated filter out from them
|
||
|
unversioned dependencies if versioned dependencies with the same name,
|
||
|
type and color already exist.
|
||
|
---
|
||
|
build/rpmfc.c | 173 +++++++++++++++++++++++++++++++++++++++-------------------
|
||
|
1 file changed, 118 insertions(+), 55 deletions(-)
|
||
|
|
||
|
diff --git a/build/rpmfc.c b/build/rpmfc.c
|
||
|
index 73996e8..10fbd68 100644
|
||
|
--- a/build/rpmfc.c
|
||
|
+++ b/build/rpmfc.c
|
||
|
@@ -34,6 +34,17 @@ typedef struct rpmfcAttr_s {
|
||
|
struct matchRule excl;
|
||
|
} * rpmfcAttr;
|
||
|
|
||
|
+typedef struct {
|
||
|
+ int fileIx;
|
||
|
+ rpmds dep;
|
||
|
+} rpmfcFileDep;
|
||
|
+
|
||
|
+typedef struct {
|
||
|
+ rpmfcFileDep *data;
|
||
|
+ int size;
|
||
|
+ int alloced;
|
||
|
+} rpmfcFileDeps;
|
||
|
+
|
||
|
/**
|
||
|
*/
|
||
|
struct rpmfc_s {
|
||
|
@@ -56,7 +67,7 @@ struct rpmfc_s {
|
||
|
ARGI_t fddictn; /*!< (no. files) file depends dictionary no. entries */
|
||
|
ARGI_t ddictx; /*!< (no. dependencies) file->dependency mapping */
|
||
|
rpmstrPool cdict; /*!< file class dictionary */
|
||
|
- rpmstrPool ddict; /*!< file depends dictionary */
|
||
|
+ rpmfcFileDeps fileDeps; /*!< file dependency mapping */
|
||
|
|
||
|
rpmstrPool pool; /*!< general purpose string storage */
|
||
|
};
|
||
|
@@ -398,15 +409,15 @@ static void argvAddUniq(ARGV_t * argvp, const char * key)
|
||
|
|
||
|
#define hasAttr(_a, _n) (argvSearch((_a), (_n), NULL) != NULL)
|
||
|
|
||
|
-static void rpmfcAddFileDep(rpmstrPool ddict, int ix, rpmds ds, char deptype)
|
||
|
+static void rpmfcAddFileDep(rpmfcFileDeps *fileDeps, rpmds ds, int ix)
|
||
|
{
|
||
|
- if (ds) {
|
||
|
- char *key = NULL;
|
||
|
- rasprintf(&key, "%08d%c %s %s 0x%08x", ix, deptype,
|
||
|
- rpmdsN(ds), rpmdsEVR(ds), rpmdsFlags(ds));
|
||
|
- rpmstrPoolId(ddict, key, 1);
|
||
|
- free(key);
|
||
|
+ if (fileDeps->size == fileDeps->alloced) {
|
||
|
+ fileDeps->alloced <<= 2;
|
||
|
+ fileDeps->data = xrealloc(fileDeps->data,
|
||
|
+ fileDeps->alloced * sizeof(fileDeps->data[0]));
|
||
|
}
|
||
|
+ fileDeps->data[fileDeps->size].fileIx = ix;
|
||
|
+ fileDeps->data[fileDeps->size++].dep = ds;
|
||
|
}
|
||
|
|
||
|
static ARGV_t runCmd(const char *nsdep, const char *depname,
|
||
|
@@ -531,11 +542,9 @@ static int rpmfcHelper(rpmfc fc, int ix,
|
||
|
|
||
|
/* Add to package and file dependencies unless filtered */
|
||
|
if (regMatch(exclude, rpmdsDNEVR(ds)+2) == 0) {
|
||
|
- (void) rpmdsMerge(packageDependencies(fc->pkg, tagN), ds);
|
||
|
- rpmfcAddFileDep(fc->ddict, ix, ds,
|
||
|
- tagN == RPMTAG_PROVIDENAME ? 'P' : 'R');
|
||
|
+ //rpmdsMerge(packageDependencies(fc->pkg, tagN), ds);
|
||
|
+ rpmfcAddFileDep(&fc->fileDeps, ds, ix);
|
||
|
}
|
||
|
- rpmdsFree(ds);
|
||
|
} else {
|
||
|
rpmlog(RPMLOG_ERR, _("invalid dependency (%s): %s\n"),
|
||
|
err, pav[i]);
|
||
|
@@ -745,7 +754,11 @@ rpmfc rpmfcFree(rpmfc fc)
|
||
|
argiFree(fc->fddictn);
|
||
|
argiFree(fc->ddictx);
|
||
|
|
||
|
- rpmstrPoolFree(fc->ddict);
|
||
|
+ for (int i = 0; i < fc->fileDeps.size; i++) {
|
||
|
+ rpmdsFree(fc->fileDeps.data[i].dep);
|
||
|
+ }
|
||
|
+ free(fc->fileDeps.data);
|
||
|
+
|
||
|
rpmstrPoolFree(fc->cdict);
|
||
|
|
||
|
rpmstrPoolFree(fc->pool);
|
||
|
@@ -764,6 +777,9 @@ rpmfc rpmfcCreate(const char *buildRoot, rpmFlags flags)
|
||
|
}
|
||
|
fc->pool = rpmstrPoolCreate();
|
||
|
fc->pkg = xcalloc(1, sizeof(*fc->pkg));
|
||
|
+ fc->fileDeps.alloced = 10;
|
||
|
+ fc->fileDeps.data = xmalloc(fc->fileDeps.alloced *
|
||
|
+ sizeof(fc->fileDeps.data[0]));
|
||
|
return fc;
|
||
|
}
|
||
|
|
||
|
@@ -820,17 +836,82 @@ rpmds rpmfcObsoletes(rpmfc fc)
|
||
|
return rpmfcDependencies(fc, RPMTAG_OBSOLETENAME);
|
||
|
}
|
||
|
|
||
|
+
|
||
|
+/* Versioned deps are less than unversioned deps */
|
||
|
+static int cmpVerDeps(const void *a, const void *b)
|
||
|
+{
|
||
|
+ rpmfcFileDep *fDepA = (rpmfcFileDep *) a;
|
||
|
+ rpmfcFileDep *fDepB = (rpmfcFileDep *) b;
|
||
|
+
|
||
|
+ int aIsVersioned = rpmdsFlags(fDepA->dep) & RPMSENSE_SENSEMASK ? 1 : 0;
|
||
|
+ int bIsVersioned = rpmdsFlags(fDepB->dep) & RPMSENSE_SENSEMASK ? 1 : 0;
|
||
|
+
|
||
|
+ return bIsVersioned - aIsVersioned;
|
||
|
+}
|
||
|
+
|
||
|
+/* Sort by index */
|
||
|
+static int cmpIndexDeps(const void *a, const void *b)
|
||
|
+{
|
||
|
+ rpmfcFileDep *fDepA = (rpmfcFileDep *) a;
|
||
|
+ rpmfcFileDep *fDepB = (rpmfcFileDep *) b;
|
||
|
+
|
||
|
+ return fDepA->fileIx - fDepB->fileIx;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * Remove unversioned deps if corresponding versioned deps exist but only
|
||
|
+ * if the versioned dependency has the same type and the same color as the versioned.
|
||
|
+ */
|
||
|
+static void rpmfcNormalizeFDeps(rpmfc fc)
|
||
|
+{
|
||
|
+ rpmstrPool versionedDeps = rpmstrPoolCreate();
|
||
|
+ rpmfcFileDep *normalizedFDeps = xmalloc(fc->fileDeps.size *
|
||
|
+ sizeof(normalizedFDeps[0]));
|
||
|
+ int ix = 0;
|
||
|
+ char *depStr;
|
||
|
+
|
||
|
+ /* Sort. Versioned dependencies first */
|
||
|
+ qsort(fc->fileDeps.data, fc->fileDeps.size, sizeof(fc->fileDeps.data[0]),
|
||
|
+ cmpVerDeps);
|
||
|
+
|
||
|
+ for (int i = 0; i < fc->fileDeps.size; i++) {
|
||
|
+ switch (rpmdsTagN(fc->fileDeps.data[i].dep)) {
|
||
|
+ case RPMTAG_REQUIRENAME:
|
||
|
+ case RPMTAG_RECOMMENDNAME:
|
||
|
+ case RPMTAG_SUGGESTNAME:
|
||
|
+ rasprintf(&depStr, "%08x_%c_%s",
|
||
|
+ fc->fcolor[fc->fileDeps.data[i].fileIx],
|
||
|
+ rpmdsD(fc->fileDeps.data[i].dep),
|
||
|
+ rpmdsN(fc->fileDeps.data[i].dep));
|
||
|
+
|
||
|
+ if (rpmdsFlags(fc->fileDeps.data[i].dep) & RPMSENSE_SENSEMASK) {
|
||
|
+ /* preserve versioned require dependency */
|
||
|
+ normalizedFDeps[ix++] = fc->fileDeps.data[i];
|
||
|
+ rpmstrPoolId(versionedDeps, depStr, 1);
|
||
|
+ } else if (!rpmstrPoolId(versionedDeps, depStr, 0)) {
|
||
|
+ /* preserve unversioned require dep only if versioned dep doesn't exist */
|
||
|
+ normalizedFDeps[ix++] =fc-> fileDeps.data[i];
|
||
|
+ } else {
|
||
|
+ rpmdsFree(fc->fileDeps.data[i].dep);
|
||
|
+ }
|
||
|
+ free(depStr);
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ /* Preserve all non-require dependencies */
|
||
|
+ normalizedFDeps[ix++] = fc->fileDeps.data[i];
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ rpmstrPoolFree(versionedDeps);
|
||
|
+
|
||
|
+ free(fc->fileDeps.data);
|
||
|
+ fc->fileDeps.data = normalizedFDeps;
|
||
|
+ fc->fileDeps.size = ix;
|
||
|
+}
|
||
|
+
|
||
|
static rpmRC rpmfcApplyInternal(rpmfc fc)
|
||
|
{
|
||
|
- const char * s;
|
||
|
- char * se;
|
||
|
rpmds ds, * dsp;
|
||
|
- rpmTagVal tagN;
|
||
|
- const char * N;
|
||
|
- const char * EVR;
|
||
|
- rpmsenseFlags Flags;
|
||
|
- unsigned char deptype;
|
||
|
- int nddict;
|
||
|
int previx;
|
||
|
unsigned int val;
|
||
|
int dix;
|
||
|
@@ -862,45 +943,28 @@ static rpmRC rpmfcApplyInternal(rpmfc fc)
|
||
|
}
|
||
|
}
|
||
|
/* No more additions after this, freeze pool to minimize memory use */
|
||
|
- rpmstrPoolFreeze(fc->ddict, 0);
|
||
|
+
|
||
|
+ rpmfcNormalizeFDeps(fc);
|
||
|
+ for (int i = 0; i < fc->fileDeps.size; i++) {
|
||
|
+ ds = fc->fileDeps.data[i].dep;
|
||
|
+ rpmdsMerge(packageDependencies(fc->pkg, rpmdsTagN(ds)), ds);
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Sort by index */
|
||
|
+ qsort(fc->fileDeps.data, fc->fileDeps.size,
|
||
|
+ sizeof(fc->fileDeps.data[0]), cmpIndexDeps);
|
||
|
|
||
|
/* Generate per-file indices into package dependencies. */
|
||
|
- nddict = rpmstrPoolNumStr(fc->ddict);
|
||
|
previx = -1;
|
||
|
- for (rpmsid id = 1; id <= nddict; id++) {
|
||
|
- s = rpmstrPoolStr(fc->ddict, id);
|
||
|
-
|
||
|
- /* Parse out (file#,deptype,N,EVR,Flags) */
|
||
|
- ix = strtol(s, &se, 10);
|
||
|
- if ( se == NULL ) {
|
||
|
- rpmlog(RPMLOG_ERR, _("Conversion of %s to long integer failed.\n"), s);
|
||
|
- return RPMRC_FAIL;
|
||
|
- }
|
||
|
-
|
||
|
- deptype = *se++;
|
||
|
- se++;
|
||
|
- N = se;
|
||
|
- while (*se && *se != ' ')
|
||
|
- se++;
|
||
|
- *se++ = '\0';
|
||
|
- EVR = se;
|
||
|
- while (*se && *se != ' ')
|
||
|
- se++;
|
||
|
- *se++ = '\0';
|
||
|
- Flags = strtol(se, NULL, 16);
|
||
|
-
|
||
|
- dix = -1;
|
||
|
-
|
||
|
- tagN = rpmdsDToTagN(deptype);
|
||
|
- dsp = packageDependencies(fc->pkg, tagN);
|
||
|
- ds = rpmdsSinglePool(fc->pool, tagN, N, EVR, Flags);
|
||
|
+ for (int i = 0; i < fc->fileDeps.size; i++) {
|
||
|
+ ds = fc->fileDeps.data[i].dep;
|
||
|
+ ix = fc->fileDeps.data[i].fileIx;
|
||
|
+ dsp = packageDependencies(fc->pkg, rpmdsTagN(ds));
|
||
|
dix = rpmdsFind(*dsp, ds);
|
||
|
- rpmdsFree(ds);
|
||
|
-
|
||
|
if (dix < 0)
|
||
|
continue;
|
||
|
|
||
|
- val = (deptype << 24) | (dix & 0x00ffffff);
|
||
|
+ val = (rpmdsD(ds) << 24) | (dix & 0x00ffffff);
|
||
|
argiAdd(&fc->ddictx, -1, val);
|
||
|
|
||
|
if (previx != ix) {
|
||
|
@@ -909,8 +973,8 @@ static rpmRC rpmfcApplyInternal(rpmfc fc)
|
||
|
}
|
||
|
if (fc->fddictn && fc->fddictn->vals)
|
||
|
fc->fddictn->vals[ix]++;
|
||
|
- }
|
||
|
|
||
|
+ }
|
||
|
return RPMRC_OK;
|
||
|
}
|
||
|
|
||
|
@@ -968,7 +1032,6 @@ rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode)
|
||
|
|
||
|
/* Build (sorted) file class dictionary. */
|
||
|
fc->cdict = rpmstrPoolCreate();
|
||
|
- fc->ddict = rpmstrPoolCreate();
|
||
|
|
||
|
ms = magic_open(msflags);
|
||
|
if (ms == NULL) {
|
||
|
--
|
||
|
1.9.3
|
||
|
|