2017-06-30 15:03:35 +00:00
|
|
|
From c1ed362facbab3d08b5576950d4c6a68cfae9e75 Mon Sep 17 00:00:00 2001
|
2017-06-28 08:34:03 +00:00
|
|
|
From: Igor Gnatenko <ignatenko@redhat.com>
|
|
|
|
Date: Sat, 25 Feb 2017 12:28:16 +0100
|
2017-07-18 13:49:11 +00:00
|
|
|
Subject: [PATCH] add support for rich dependencies from dependency generators
|
2017-06-28 08:34:03 +00:00
|
|
|
|
|
|
|
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)
|
2017-06-30 15:03:35 +00:00
|
|
|
|
|
|
|
Conflicts:
|
|
|
|
build/rpmfc.c
|
2017-06-28 08:34:03 +00:00
|
|
|
---
|
|
|
|
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
|
2017-06-28 10:37:07 +00:00
|
|
|
index bc639e86c..6b3705598 100644
|
2017-06-28 08:34:03 +00:00
|
|
|
--- a/build/parsePreamble.c
|
|
|
|
+++ b/build/parsePreamble.c
|
2017-06-28 10:37:07 +00:00
|
|
|
@@ -866,13 +866,13 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
|
2017-06-28 08:34:03 +00:00
|
|
|
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
|
2017-06-28 10:37:07 +00:00
|
|
|
index 7ec05b9c9..1c3332faf 100644
|
2017-06-28 08:34:03 +00:00
|
|
|
--- 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
|
2017-06-28 10:37:07 +00:00
|
|
|
* Add self-provides to package.
|
2017-06-28 08:34:03 +00:00
|
|
|
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) {
|