summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Gnatenko <ignatenko@redhat.com>2017-02-25 12:28:16 +0100
committerIgor Gnatenko <ignatenko@redhat.com>2017-03-08 10:57:12 +0100
commit8f509d669b9ae79c86dd510c5a4bc5109f60d733 (patch)
treee447a9d956c8098c52c6d0f99eaf2c7e88cf06fd
parent5adc56897b9da5dac49701f704ef54390db57c59 (diff)
downloadrpm-8f509d669b9ae79c86dd510c5a4bc5109f60d733.tar.gz
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>
-rw-r--r--build/parsePreamble.c4
-rw-r--r--build/parseReqs.c9
-rw-r--r--build/parseScript.c2
-rw-r--r--build/reqprov.c8
-rw-r--r--build/rpmbuild_internal.h12
-rw-r--r--build/rpmfc.c90
6 files changed, 54 insertions, 71 deletions
diff --git a/build/parsePreamble.c b/build/parsePreamble.c
index ae21bc126..6d25f4cb9 100644
--- a/build/parsePreamble.c
+++ b/build/parsePreamble.c
@@ -871,13 +871,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 cc1ee5808..7373f8550 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;
@@ -130,6 +130,9 @@ rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN,
rpmsenseFlags Flags;
rpmRC rc = RPMRC_FAIL; /* assume failure */
+ if (!cbdata)
+ cbdata = pkg;
+
switch (tagN) {
default:
case RPMTAG_REQUIRENAME:
@@ -221,7 +224,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;
@@ -296,7 +299,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 48bc8d703..bd0c2f072 100644
--- a/build/parseScript.c
+++ b/build/parseScript.c
@@ -416,7 +416,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 d96837a90..421903290 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 rpmlib feature dependency.
diff --git a/build/rpmfc.c b/build/rpmfc.c
index c73635bd1..1c096f862 100644
--- a/build/rpmfc.c
+++ b/build/rpmfc.c
@@ -497,44 +497,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;
}
/**
@@ -577,35 +560,14 @@ static int rpmfcHelper(rpmfc fc, int ix,
namespace = rpmfcAttrMacro(nsdep, "namespace", NULL);
exclude = rpmfcAttrReg(depname, "exclude", NULL);
+ 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);
@@ -1353,7 +1315,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) {