Igor Gnatenko 34e0e8
From 9ff717b63e94eb6a330050036506f8b78bf1401f Mon Sep 17 00:00:00 2001
Igor Gnatenko d7aa14
From: Igor Gnatenko <ignatenko@redhat.com>
Igor Gnatenko d7aa14
Date: Sat, 25 Feb 2017 12:28:16 +0100
Igor Gnatenko d7aa14
Subject: [PATCH 5/6] add support for rich dependencies from dependency
Igor Gnatenko d7aa14
 generators
Igor Gnatenko d7aa14
Igor Gnatenko d7aa14
Mostly achieved by replacing custom parser with the parseRCPOT().
Igor Gnatenko d7aa14
Igor Gnatenko d7aa14
Closes: https://github.com/rpm-software-management/rpm/issues/167
Igor Gnatenko d7aa14
Signed-off-by: Igor Gnatenko <ignatenko@redhat.com>
Igor Gnatenko d7aa14
(cherry picked from commit 8f509d669b9ae79c86dd510c5a4bc5109f60d733)
Igor Gnatenko d7aa14
---
Igor Gnatenko d7aa14
 build/parsePreamble.c     |  4 +--
Igor Gnatenko d7aa14
 build/parseReqs.c         |  9 +++--
Igor Gnatenko d7aa14
 build/parseScript.c       |  2 +-
Igor Gnatenko d7aa14
 build/reqprov.c           |  8 +++++
Igor Gnatenko d7aa14
 build/rpmbuild_internal.h | 12 ++++++-
Igor Gnatenko d7aa14
 build/rpmfc.c             | 90 ++++++++++++++---------------------------------
Igor Gnatenko d7aa14
 6 files changed, 54 insertions(+), 71 deletions(-)
Igor Gnatenko d7aa14
Igor Gnatenko d7aa14
diff --git a/build/parsePreamble.c b/build/parsePreamble.c
Igor Gnatenko 34e0e8
index bc639e86c..6b3705598 100644
Igor Gnatenko d7aa14
--- a/build/parsePreamble.c
Igor Gnatenko d7aa14
+++ b/build/parsePreamble.c
Igor Gnatenko 34e0e8
@@ -866,13 +866,13 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
Igor Gnatenko d7aa14
     case RPMTAG_CONFLICTNAME:
Igor Gnatenko d7aa14
     case RPMTAG_OBSOLETENAME:
Igor Gnatenko d7aa14
     case RPMTAG_PROVIDENAME:
Igor Gnatenko d7aa14
-	if (parseRCPOT(spec, pkg, field, tag, 0, tagflags))
Igor Gnatenko d7aa14
+	if (parseRCPOT(spec, pkg, field, tag, 0, tagflags, addReqProvPkg, NULL))
Igor Gnatenko d7aa14
 	    goto exit;
Igor Gnatenko d7aa14
 	break;
Igor Gnatenko d7aa14
     case RPMTAG_BUILDPREREQ:
Igor Gnatenko d7aa14
     case RPMTAG_BUILDREQUIRES:
Igor Gnatenko d7aa14
     case RPMTAG_BUILDCONFLICTS:
Igor Gnatenko d7aa14
-	if (parseRCPOT(spec, spec->sourcePackage, field, tag, 0, tagflags))
Igor Gnatenko d7aa14
+	if (parseRCPOT(spec, spec->sourcePackage, field, tag, 0, tagflags, addReqProvPkg, NULL))
Igor Gnatenko d7aa14
 	    goto exit;
Igor Gnatenko d7aa14
 	break;
Igor Gnatenko d7aa14
     case RPMTAG_EXCLUDEARCH:
Igor Gnatenko d7aa14
diff --git a/build/parseReqs.c b/build/parseReqs.c
Igor Gnatenko d7aa14
index 4d500c1df..554ff49a5 100644
Igor Gnatenko d7aa14
--- a/build/parseReqs.c
Igor Gnatenko d7aa14
+++ b/build/parseReqs.c
Igor Gnatenko d7aa14
@@ -121,7 +121,7 @@ static rpmRC parseRCPOTRichCB(void *cbdata, rpmrichParseType type,
Igor Gnatenko d7aa14
 }
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
 rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN,
Igor Gnatenko d7aa14
-	       int index, rpmsenseFlags tagflags)
Igor Gnatenko d7aa14
+	       int index, rpmsenseFlags tagflags, addReqProvFunction cb, void *cbdata)
Igor Gnatenko d7aa14
 {
Igor Gnatenko d7aa14
     const char *r, *re, *v, *ve;
Igor Gnatenko d7aa14
     char *emsg = NULL;
Igor Gnatenko d7aa14
@@ -131,6 +131,9 @@ rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN,
Igor Gnatenko d7aa14
     rpmRC rc = RPMRC_FAIL; /* assume failure */
Igor Gnatenko d7aa14
     int allow_richdeps = 0;
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
+    if (!cbdata)
Igor Gnatenko d7aa14
+	cbdata = pkg;
Igor Gnatenko d7aa14
+
Igor Gnatenko d7aa14
     switch (tagN) {
Igor Gnatenko d7aa14
     default:
Igor Gnatenko d7aa14
     case RPMTAG_REQUIRENAME:
Igor Gnatenko d7aa14
@@ -225,7 +228,7 @@ rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN,
Igor Gnatenko d7aa14
 		freeStringBuf(data.sb);
Igor Gnatenko d7aa14
 		goto exit;
Igor Gnatenko d7aa14
 	    }
Igor Gnatenko d7aa14
-	    if (addReqProv(pkg, nametag, getStringBuf(data.sb), NULL, Flags, index)) {
Igor Gnatenko d7aa14
+	    if (cb && cb(cbdata, nametag, getStringBuf(data.sb), NULL, Flags, index) != RPMRC_OK) {
Igor Gnatenko d7aa14
 		rasprintf(&emsg, _("invalid dependency"));
Igor Gnatenko d7aa14
 		freeStringBuf(data.sb);
Igor Gnatenko d7aa14
 		goto exit;
Igor Gnatenko d7aa14
@@ -300,7 +303,7 @@ rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN,
Igor Gnatenko d7aa14
 		goto exit;
Igor Gnatenko d7aa14
 	}
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
-	if (addReqProv(pkg, nametag, N, EVR, Flags, index)) {
Igor Gnatenko d7aa14
+	if (cb && cb(cbdata, nametag, N, EVR, Flags, index) != RPMRC_OK) {
Igor Gnatenko d7aa14
 	    rasprintf(&emsg, _("invalid dependency"));
Igor Gnatenko d7aa14
 	    goto exit;
Igor Gnatenko d7aa14
 	}
Igor Gnatenko d7aa14
diff --git a/build/parseScript.c b/build/parseScript.c
Igor Gnatenko d7aa14
index 64fd89693..849e40244 100644
Igor Gnatenko d7aa14
--- a/build/parseScript.c
Igor Gnatenko d7aa14
+++ b/build/parseScript.c
Igor Gnatenko d7aa14
@@ -398,7 +398,7 @@ int parseScript(rpmSpec spec, int parsePart)
Igor Gnatenko d7aa14
 				priority);
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
 	/* Generate the trigger tags */
Igor Gnatenko d7aa14
-	if (parseRCPOT(spec, pkg, reqargs, reqtag, index, tagflags))
Igor Gnatenko d7aa14
+	if (parseRCPOT(spec, pkg, reqargs, reqtag, index, tagflags, addReqProvPkg, NULL))
Igor Gnatenko d7aa14
 	    goto exit;
Igor Gnatenko d7aa14
     } else {
Igor Gnatenko d7aa14
 	struct rpmtd_s td;
Igor Gnatenko d7aa14
diff --git a/build/reqprov.c b/build/reqprov.c
Igor Gnatenko d7aa14
index 7422db65f..5fa0a1c6b 100644
Igor Gnatenko d7aa14
--- a/build/reqprov.c
Igor Gnatenko d7aa14
+++ b/build/reqprov.c
Igor Gnatenko d7aa14
@@ -34,6 +34,14 @@ int addReqProv(Package pkg, rpmTagVal tagN,
Igor Gnatenko d7aa14
     return 0;
Igor Gnatenko d7aa14
 }
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
+rpmRC addReqProvPkg(void *cbdata, rpmTagVal tagN,
Igor Gnatenko d7aa14
+		    const char * N, const char *EVR, rpmsenseFlags Flags,
Igor Gnatenko d7aa14
+		    int index)
Igor Gnatenko d7aa14
+{
Igor Gnatenko d7aa14
+    Package pkg = cbdata;
Igor Gnatenko d7aa14
+    return addReqProv(pkg, tagN, N, EVR, Flags, index) ? RPMRC_FAIL : RPMRC_OK;
Igor Gnatenko d7aa14
+}
Igor Gnatenko d7aa14
+
Igor Gnatenko d7aa14
 int rpmlibNeedsFeature(Package pkg, const char * feature, const char * featureEVR)
Igor Gnatenko d7aa14
 {
Igor Gnatenko d7aa14
     char *reqname = NULL;
Igor Gnatenko d7aa14
diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h
Igor Gnatenko 34e0e8
index 7ec05b9c9..1c3332faf 100644
Igor Gnatenko d7aa14
--- a/build/rpmbuild_internal.h
Igor Gnatenko d7aa14
+++ b/build/rpmbuild_internal.h
Igor Gnatenko d7aa14
@@ -283,6 +283,10 @@ int parseScript(rpmSpec spec, int parsePart);
Igor Gnatenko d7aa14
 RPM_GNUC_INTERNAL
Igor Gnatenko d7aa14
 rpmRC rpmCharCheck(rpmSpec spec, const char *field, const char *whitelist);
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
+typedef rpmRC (*addReqProvFunction) (void *cbdata, rpmTagVal tagN,
Igor Gnatenko d7aa14
+				     const char * N, const char * EVR, rpmsenseFlags Flags,
Igor Gnatenko d7aa14
+				     int index);
Igor Gnatenko d7aa14
+
Igor Gnatenko d7aa14
 /** \ingroup rpmbuild
Igor Gnatenko d7aa14
  * Parse dependency relations from spec file and/or autogenerated output buffer.
Igor Gnatenko d7aa14
  * @param spec		spec file control structure
Igor Gnatenko d7aa14
@@ -291,11 +295,13 @@ rpmRC rpmCharCheck(rpmSpec spec, const char *field, const char *whitelist);
Igor Gnatenko d7aa14
  * @param tagN		tag, identifies type of dependency
Igor Gnatenko d7aa14
  * @param index		(0 always)
Igor Gnatenko d7aa14
  * @param tagflags	dependency flags already known from context
Igor Gnatenko d7aa14
+ * @param cb		Callback for adding dependency (nullable)
Igor Gnatenko d7aa14
+ * @param cbdata	Callback data (@pkg if NULL)
Igor Gnatenko d7aa14
  * @return		RPMRC_OK on success, RPMRC_FAIL on failure
Igor Gnatenko d7aa14
  */
Igor Gnatenko d7aa14
 RPM_GNUC_INTERNAL
Igor Gnatenko d7aa14
 rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char * field, rpmTagVal tagN,
Igor Gnatenko d7aa14
-		int index, rpmsenseFlags tagflags);
Igor Gnatenko d7aa14
+		int index, rpmsenseFlags tagflags, addReqProvFunction cb, void *cbdata);
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
 /** \ingroup rpmbuild
Igor Gnatenko d7aa14
  * Evaluate boolean expression.
Igor Gnatenko d7aa14
@@ -440,6 +446,10 @@ int addReqProv(Package pkg, rpmTagVal tagN,
Igor Gnatenko d7aa14
 	       const char * N, const char * EVR, rpmsenseFlags Flags,
Igor Gnatenko d7aa14
 	       uint32_t index);
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
+RPM_GNUC_INTERNAL
Igor Gnatenko d7aa14
+rpmRC addReqProvPkg(void *cbdata, rpmTagVal tagN,
Igor Gnatenko d7aa14
+		    const char * N, const char * EVR, rpmsenseFlags Flags,
Igor Gnatenko d7aa14
+		    int index);
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
 /** \ingroup rpmbuild
Igor Gnatenko 34e0e8
  * Add self-provides to package.
Igor Gnatenko d7aa14
diff --git a/build/rpmfc.c b/build/rpmfc.c
Igor Gnatenko d7aa14
index 921814ad1..7fa8227d0 100644
Igor Gnatenko d7aa14
--- a/build/rpmfc.c
Igor Gnatenko d7aa14
+++ b/build/rpmfc.c
Igor Gnatenko d7aa14
@@ -447,44 +447,27 @@ static ARGV_t runCmd(const char *nsdep, const char *depname,
Igor Gnatenko d7aa14
     return output;
Igor Gnatenko d7aa14
 }
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
-static const char *parseDep(char **depav, int depac,
Igor Gnatenko d7aa14
-		    const char **N, const char **EVR, rpmsenseFlags *Flags)
Igor Gnatenko d7aa14
+struct addReqProvDataFc {
Igor Gnatenko d7aa14
+    rpmfc fc;
Igor Gnatenko d7aa14
+    const char *namespace;
Igor Gnatenko d7aa14
+    regex_t *exclude;
Igor Gnatenko d7aa14
+};
Igor Gnatenko d7aa14
+
Igor Gnatenko d7aa14
+static rpmRC addReqProvFc(void *cbdata, rpmTagVal tagN,
Igor Gnatenko d7aa14
+			  const char * N, const char * EVR, rpmsenseFlags Flags,
Igor Gnatenko d7aa14
+			  int index)
Igor Gnatenko d7aa14
 {
Igor Gnatenko d7aa14
-    const char *err = NULL;
Igor Gnatenko d7aa14
-
Igor Gnatenko d7aa14
-    switch (depac) {
Igor Gnatenko d7aa14
-    case 1: /* only a name */
Igor Gnatenko d7aa14
-	*N = depav[0];
Igor Gnatenko d7aa14
-	*EVR = "";
Igor Gnatenko d7aa14
-	break;
Igor Gnatenko d7aa14
-    case 3: /* name, range and version */
Igor Gnatenko d7aa14
-	for (const char *s = depav[1]; *s; s++) {
Igor Gnatenko d7aa14
-	    switch(*s) {
Igor Gnatenko d7aa14
-	    default:
Igor Gnatenko d7aa14
-		err = _("bad operator");
Igor Gnatenko d7aa14
-		break;
Igor Gnatenko d7aa14
-	    case '=':
Igor Gnatenko d7aa14
-		*Flags |= RPMSENSE_EQUAL;
Igor Gnatenko d7aa14
-		break;
Igor Gnatenko d7aa14
-	    case '<':
Igor Gnatenko d7aa14
-		*Flags |= RPMSENSE_LESS;
Igor Gnatenko d7aa14
-		break;
Igor Gnatenko d7aa14
-	    case '>':
Igor Gnatenko d7aa14
-		*Flags |= RPMSENSE_GREATER;
Igor Gnatenko d7aa14
-		break;
Igor Gnatenko d7aa14
-	    }
Igor Gnatenko d7aa14
-	}
Igor Gnatenko d7aa14
-	if (!err) {
Igor Gnatenko d7aa14
-	    *N = depav[0];
Igor Gnatenko d7aa14
-	    *EVR = depav[2];
Igor Gnatenko d7aa14
-	}
Igor Gnatenko d7aa14
-	break;
Igor Gnatenko d7aa14
-    default:
Igor Gnatenko d7aa14
-	err = _("bad format");
Igor Gnatenko d7aa14
-	break;
Igor Gnatenko d7aa14
-    }
Igor Gnatenko d7aa14
+    struct addReqProvDataFc *data = cbdata;
Igor Gnatenko d7aa14
+    rpmfc fc = data->fc;
Igor Gnatenko d7aa14
+    const char *namespace = data->namespace;
Igor Gnatenko d7aa14
+    regex_t *exclude = data->exclude;
Igor Gnatenko d7aa14
+
Igor Gnatenko d7aa14
+    rpmds ds = rpmdsSingleNS(fc->pool, tagN, namespace, N, EVR, Flags);
Igor Gnatenko d7aa14
+    /* Add to package and file dependencies unless filtered */
Igor Gnatenko d7aa14
+    if (regMatch(exclude, rpmdsDNEVR(ds)+2) == 0)
Igor Gnatenko d7aa14
+	rpmfcAddFileDep(&fc->fileDeps, ds, index);
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
-    return err;
Igor Gnatenko d7aa14
+    return RPMRC_OK;
Igor Gnatenko d7aa14
 }
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
 /**
Igor Gnatenko d7aa14
@@ -522,35 +505,14 @@ static int rpmfcHelper(rpmfc fc, int ix,
Igor Gnatenko d7aa14
     namespace = rpmfcAttrMacro(nsdep, NULL, "namespace");
Igor Gnatenko d7aa14
     exclude = rpmfcAttrReg(depname, NULL, "exclude");
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
+    struct addReqProvDataFc data;
Igor Gnatenko d7aa14
+    data.fc = fc;
Igor Gnatenko d7aa14
+    data.namespace = namespace;
Igor Gnatenko d7aa14
+    data.exclude = exclude;
Igor Gnatenko d7aa14
+
Igor Gnatenko d7aa14
     for (int i = 0; i < pac; i++) {
Igor Gnatenko d7aa14
-	char ** depav = NULL;
Igor Gnatenko d7aa14
-	int xx, depac = 0;
Igor Gnatenko d7aa14
-	const char *N = NULL;
Igor Gnatenko d7aa14
-	const char *EVR = NULL;
Igor Gnatenko d7aa14
-	const char *err = NULL;
Igor Gnatenko d7aa14
-	rpmsenseFlags Flags = dsContext;
Igor Gnatenko d7aa14
-
Igor Gnatenko d7aa14
-	if ((xx = poptParseArgvString(pav[i], &depac, (const char ***)&depav)))
Igor Gnatenko d7aa14
-	    err = poptStrerror(xx);
Igor Gnatenko d7aa14
-
Igor Gnatenko d7aa14
-	if (!err)
Igor Gnatenko d7aa14
-	    err = parseDep(depav, depac, &N, &EVR, &Flags);
Igor Gnatenko d7aa14
-
Igor Gnatenko d7aa14
-	if (!err) {
Igor Gnatenko d7aa14
-	    rpmds ds = rpmdsSingleNS(fc->pool, tagN, namespace, N, EVR, Flags);
Igor Gnatenko d7aa14
-
Igor Gnatenko d7aa14
-	    /* Add to package and file dependencies unless filtered */
Igor Gnatenko d7aa14
-	    if (regMatch(exclude, rpmdsDNEVR(ds)+2) == 0) {
Igor Gnatenko d7aa14
-		//rpmdsMerge(packageDependencies(fc->pkg, tagN), ds);
Igor Gnatenko d7aa14
-		rpmfcAddFileDep(&fc->fileDeps, ds, ix);
Igor Gnatenko d7aa14
-	    }
Igor Gnatenko d7aa14
-	} else {
Igor Gnatenko d7aa14
-	    rpmlog(RPMLOG_ERR, _("invalid dependency (%s): %s\n"),
Igor Gnatenko d7aa14
-		   err, pav[i]);
Igor Gnatenko d7aa14
+	if (parseRCPOT(NULL, fc->pkg, pav[i], tagN, 0, dsContext, addReqProvFc, &data))
Igor Gnatenko d7aa14
 	    rc++;
Igor Gnatenko d7aa14
-	}
Igor Gnatenko d7aa14
-
Igor Gnatenko d7aa14
-	free(depav);
Igor Gnatenko d7aa14
     }
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
     argvFree(pav);
Igor Gnatenko d7aa14
@@ -1297,7 +1259,7 @@ static rpmRC rpmfcApplyExternal(rpmfc fc)
Igor Gnatenko d7aa14
 	}
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
 	/* Parse dependencies into header */
Igor Gnatenko d7aa14
-	rc = parseRCPOT(NULL, fc->pkg, getStringBuf(sb_stdout), dm->ntag ? dm->ntag != -1 : RPMTAG_REQUIRENAME, 0, tagflags);
Igor Gnatenko d7aa14
+	rc = parseRCPOT(NULL, fc->pkg, getStringBuf(sb_stdout), dm->ntag ? dm->ntag != -1 : RPMTAG_REQUIRENAME, 0, tagflags, addReqProvPkg, NULL);
Igor Gnatenko d7aa14
 	freeStringBuf(sb_stdout);
Igor Gnatenko d7aa14
 
Igor Gnatenko d7aa14
 	if (rc) {
Igor Gnatenko d7aa14
-- 
Igor Gnatenko d7aa14
2.13.1
Igor Gnatenko d7aa14