rpm/0048-add-support-for-rich-d...

276 lines
8.9 KiB
Diff

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