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