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>
This commit is contained in:
parent
5adc56897b
commit
8f509d669b
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
struct addReqProvDataFc *data = cbdata;
|
||||
rpmfc fc = data->fc;
|
||||
const char *namespace = data->namespace;
|
||||
regex_t *exclude = data->exclude;
|
||||
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue