2000-08-28 03:18:25 +08:00
|
|
|
/** \ingroup rpmbuild
|
|
|
|
* \file build/parseReqs.c
|
2000-01-25 04:02:32 +08:00
|
|
|
* Parse dependency tag from spec file or from auto-dependency generator.
|
|
|
|
*/
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2010-01-05 21:33:47 +08:00
|
|
|
#include <ctype.h>
|
2008-05-21 20:59:39 +08:00
|
|
|
#include <rpm/rpmtypes.h>
|
2007-12-08 20:02:32 +08:00
|
|
|
#include <rpm/rpmlog.h>
|
2010-08-25 20:41:09 +08:00
|
|
|
#include "build/rpmbuild_internal.h"
|
|
|
|
#include "build/rpmbuild_misc.h"
|
2000-12-13 04:03:45 +08:00
|
|
|
#include "debug.h"
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
1998-01-13 05:31:29 +08:00
|
|
|
static struct ReqComp {
|
2007-09-12 05:03:27 +08:00
|
|
|
const char * token;
|
2001-04-29 09:05:43 +08:00
|
|
|
rpmsenseFlags sense;
|
2008-03-07 02:17:20 +08:00
|
|
|
} const ReqComparisons[] = {
|
1998-01-13 05:31:29 +08:00
|
|
|
{ "<=", RPMSENSE_LESS | RPMSENSE_EQUAL},
|
|
|
|
{ "=<", RPMSENSE_LESS | RPMSENSE_EQUAL},
|
|
|
|
{ "<", RPMSENSE_LESS},
|
|
|
|
|
1999-07-23 06:38:44 +08:00
|
|
|
{ "==", RPMSENSE_EQUAL},
|
1998-01-13 05:31:29 +08:00
|
|
|
{ "=", RPMSENSE_EQUAL},
|
|
|
|
|
|
|
|
{ ">=", RPMSENSE_GREATER | RPMSENSE_EQUAL},
|
|
|
|
{ "=>", RPMSENSE_GREATER | RPMSENSE_EQUAL},
|
|
|
|
{ ">", RPMSENSE_GREATER},
|
1999-07-14 05:37:57 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
{ NULL, 0 },
|
|
|
|
};
|
|
|
|
|
2008-03-18 15:10:13 +08:00
|
|
|
#define SKIPWHITE(_x) {while(*(_x) && (risspace(*_x) || *(_x) == ',')) (_x)++;}
|
|
|
|
#define SKIPNONWHITE(_x){while(*(_x) &&!(risspace(*_x) || *(_x) == ',')) (_x)++;}
|
1999-05-26 12:05:33 +08:00
|
|
|
|
2010-10-22 18:46:14 +08:00
|
|
|
rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN,
|
2001-04-29 09:05:43 +08:00
|
|
|
int index, rpmsenseFlags tagflags)
|
1998-01-13 05:31:29 +08:00
|
|
|
{
|
1999-05-26 12:05:33 +08:00
|
|
|
const char *r, *re, *v, *ve;
|
2010-12-01 23:15:18 +08:00
|
|
|
const char *emsg = NULL;
|
2009-10-21 17:22:33 +08:00
|
|
|
char * N = NULL, * EVR = NULL;
|
2010-10-22 18:46:14 +08:00
|
|
|
rpmTagVal nametag = RPMTAG_NOT_FOUND;
|
2004-10-10 02:23:00 +08:00
|
|
|
rpmsenseFlags Flags;
|
2010-03-29 11:29:19 +08:00
|
|
|
Header h = pkg->header; /* everything except buildrequires go here */
|
2009-10-21 17:22:33 +08:00
|
|
|
rpmRC rc = RPMRC_FAIL; /* assume failure */
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2004-10-10 02:23:00 +08:00
|
|
|
switch (tagN) {
|
2010-03-29 11:27:44 +08:00
|
|
|
default:
|
|
|
|
case RPMTAG_REQUIREFLAGS:
|
|
|
|
nametag = RPMTAG_REQUIRENAME;
|
|
|
|
tagflags |= RPMSENSE_ANY;
|
|
|
|
break;
|
1999-07-23 01:48:31 +08:00
|
|
|
case RPMTAG_PROVIDEFLAGS:
|
2010-03-29 10:59:54 +08:00
|
|
|
nametag = RPMTAG_PROVIDENAME;
|
1999-06-17 23:44:47 +08:00
|
|
|
break;
|
2000-07-10 07:10:25 +08:00
|
|
|
case RPMTAG_OBSOLETEFLAGS:
|
2010-03-29 10:59:54 +08:00
|
|
|
nametag = RPMTAG_OBSOLETENAME;
|
1999-06-17 23:44:47 +08:00
|
|
|
break;
|
|
|
|
case RPMTAG_CONFLICTFLAGS:
|
2010-03-29 10:59:54 +08:00
|
|
|
nametag = RPMTAG_CONFLICTNAME;
|
1999-06-17 23:44:47 +08:00
|
|
|
break;
|
2010-12-13 18:03:18 +08:00
|
|
|
case RPMTAG_ORDERFLAGS:
|
|
|
|
nametag = RPMTAG_ORDERNAME;
|
|
|
|
break;
|
1999-06-17 23:44:47 +08:00
|
|
|
case RPMTAG_PREREQ:
|
2009-06-01 18:28:50 +08:00
|
|
|
/* XXX map legacy PreReq into Requires(pre,preun) */
|
2010-03-29 10:59:54 +08:00
|
|
|
nametag = RPMTAG_REQUIRENAME;
|
2009-06-01 18:28:50 +08:00
|
|
|
tagflags |= (RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_PREUN);
|
1999-06-17 23:44:47 +08:00
|
|
|
break;
|
2008-01-09 17:11:49 +08:00
|
|
|
case RPMTAG_TRIGGERPREIN:
|
2010-03-29 10:59:54 +08:00
|
|
|
nametag = RPMTAG_TRIGGERNAME;
|
2008-01-09 17:11:49 +08:00
|
|
|
tagflags |= RPMSENSE_TRIGGERPREIN;
|
|
|
|
break;
|
1999-06-17 23:44:47 +08:00
|
|
|
case RPMTAG_TRIGGERIN:
|
2010-03-29 10:59:54 +08:00
|
|
|
nametag = RPMTAG_TRIGGERNAME;
|
2000-07-06 04:39:15 +08:00
|
|
|
tagflags |= RPMSENSE_TRIGGERIN;
|
1999-06-17 23:44:47 +08:00
|
|
|
break;
|
|
|
|
case RPMTAG_TRIGGERPOSTUN:
|
2010-03-29 10:59:54 +08:00
|
|
|
nametag = RPMTAG_TRIGGERNAME;
|
2000-07-06 04:39:15 +08:00
|
|
|
tagflags |= RPMSENSE_TRIGGERPOSTUN;
|
1999-06-17 23:44:47 +08:00
|
|
|
break;
|
|
|
|
case RPMTAG_TRIGGERUN:
|
2010-03-29 10:59:54 +08:00
|
|
|
nametag = RPMTAG_TRIGGERNAME;
|
2000-07-06 04:39:15 +08:00
|
|
|
tagflags |= RPMSENSE_TRIGGERUN;
|
1999-06-17 23:44:47 +08:00
|
|
|
break;
|
2009-05-29 16:03:33 +08:00
|
|
|
case RPMTAG_BUILDPREREQ:
|
1999-06-17 23:44:47 +08:00
|
|
|
case RPMTAG_BUILDREQUIRES:
|
2010-03-29 10:59:54 +08:00
|
|
|
nametag = RPMTAG_REQUIRENAME;
|
2000-07-06 04:39:15 +08:00
|
|
|
tagflags |= RPMSENSE_ANY;
|
1999-06-17 23:44:47 +08:00
|
|
|
h = spec->buildRestrictions;
|
|
|
|
break;
|
2010-03-29 11:27:44 +08:00
|
|
|
case RPMTAG_BUILDCONFLICTS:
|
|
|
|
nametag = RPMTAG_CONFLICTNAME;
|
|
|
|
h = spec->buildRestrictions;
|
1999-06-17 23:44:47 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
for (r = field; *r != '\0'; r = re) {
|
1999-05-26 12:05:33 +08:00
|
|
|
SKIPWHITE(r);
|
|
|
|
if (*r == '\0')
|
|
|
|
break;
|
1999-06-17 23:44:47 +08:00
|
|
|
|
2004-10-10 02:23:00 +08:00
|
|
|
Flags = (tagflags & ~RPMSENSE_SENSEMASK);
|
1999-06-20 02:09:49 +08:00
|
|
|
|
2009-02-21 18:11:54 +08:00
|
|
|
/*
|
|
|
|
* Tokens must begin with alphanumeric, _, or /, but we don't know
|
|
|
|
* the spec's encoding so we only check what we can: plain ascii.
|
|
|
|
*/
|
|
|
|
if (isascii(r[0]) && !(risalnum(r[0]) || r[0] == '_' || r[0] == '/')) {
|
2010-12-01 23:15:18 +08:00
|
|
|
emsg = _("Dependency tokens must begin with alpha-numeric, '_' or '/'");
|
2009-10-21 17:22:33 +08:00
|
|
|
goto exit;
|
1999-06-17 23:44:47 +08:00
|
|
|
}
|
|
|
|
|
1999-05-26 12:05:33 +08:00
|
|
|
re = r;
|
|
|
|
SKIPNONWHITE(re);
|
2004-10-10 02:23:00 +08:00
|
|
|
N = xmalloc((re-r) + 1);
|
2008-04-18 00:19:07 +08:00
|
|
|
rstrlcpy(N, r, (re-r) + 1);
|
1999-05-26 12:05:33 +08:00
|
|
|
|
2004-10-10 02:23:00 +08:00
|
|
|
/* Parse EVR */
|
1999-05-26 12:05:33 +08:00
|
|
|
v = re;
|
|
|
|
SKIPWHITE(v);
|
|
|
|
ve = v;
|
|
|
|
SKIPNONWHITE(ve);
|
|
|
|
|
2004-10-10 02:23:00 +08:00
|
|
|
re = v; /* ==> next token (if no EVR found) starts here */
|
1999-06-17 23:44:47 +08:00
|
|
|
|
1999-05-26 12:05:33 +08:00
|
|
|
/* Check for possible logical operator */
|
|
|
|
if (ve > v) {
|
2008-03-07 02:17:20 +08:00
|
|
|
const struct ReqComp *rc;
|
1999-05-26 12:05:33 +08:00
|
|
|
for (rc = ReqComparisons; rc->token != NULL; rc++) {
|
2009-08-31 16:08:05 +08:00
|
|
|
if ((ve-v) != strlen(rc->token) || !rstreqn(v, rc->token, (ve-v)))
|
2007-09-12 05:03:27 +08:00
|
|
|
continue;
|
1999-05-26 12:05:33 +08:00
|
|
|
|
|
|
|
if (r[0] == '/') {
|
2010-12-01 23:15:18 +08:00
|
|
|
emsg = _("Versioned file name not permitted");
|
2009-10-21 17:22:33 +08:00
|
|
|
goto exit;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1999-06-18 22:33:16 +08:00
|
|
|
|
2004-10-10 02:23:00 +08:00
|
|
|
Flags |= rc->sense;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2004-10-10 02:23:00 +08:00
|
|
|
/* now parse EVR */
|
1999-05-26 12:05:33 +08:00
|
|
|
v = ve;
|
|
|
|
SKIPWHITE(v);
|
|
|
|
ve = v;
|
|
|
|
SKIPNONWHITE(ve);
|
2007-09-12 05:03:27 +08:00
|
|
|
break;
|
1999-05-26 12:05:33 +08:00
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
|
|
|
|
2004-10-10 02:23:00 +08:00
|
|
|
if (Flags & RPMSENSE_SENSEMASK) {
|
1999-05-26 12:05:33 +08:00
|
|
|
if (*v == '\0' || ve == v) {
|
2010-12-01 23:15:18 +08:00
|
|
|
emsg = _("Version required");
|
2009-10-21 17:22:33 +08:00
|
|
|
goto exit;
|
1999-05-26 12:05:33 +08:00
|
|
|
}
|
2004-10-10 02:23:00 +08:00
|
|
|
EVR = xmalloc((ve-v) + 1);
|
2008-04-18 00:19:07 +08:00
|
|
|
rstrlcpy(EVR, v, (ve-v) + 1);
|
2012-04-23 16:04:02 +08:00
|
|
|
if (rpmCharCheck(spec, EVR, ve-v, ".-_+:%{}~")) goto exit;
|
2004-10-10 02:23:00 +08:00
|
|
|
re = ve; /* ==> next token after EVR string starts here */
|
1999-05-26 12:05:33 +08:00
|
|
|
} else
|
2004-10-10 02:23:00 +08:00
|
|
|
EVR = NULL;
|
1999-05-26 12:05:33 +08:00
|
|
|
|
2010-08-25 20:06:47 +08:00
|
|
|
if (addReqProv(h, nametag, N, EVR, Flags, index)) {
|
2010-12-01 23:15:18 +08:00
|
|
|
emsg = _("invalid dependency");
|
2009-10-21 17:22:33 +08:00
|
|
|
goto exit;
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2004-10-10 02:23:00 +08:00
|
|
|
N = _free(N);
|
|
|
|
EVR = _free(EVR);
|
1999-05-26 12:05:33 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
2009-10-21 17:22:33 +08:00
|
|
|
rc = RPMRC_OK;
|
|
|
|
|
|
|
|
exit:
|
2010-12-01 23:15:18 +08:00
|
|
|
if (emsg) {
|
|
|
|
/* Automatic dependencies don't relate to spec lines */
|
|
|
|
if (tagflags & (RPMSENSE_FIND_REQUIRES|RPMSENSE_FIND_PROVIDES)) {
|
|
|
|
rpmlog(RPMLOG_ERR, "%s: %s\n", emsg, r);
|
|
|
|
} else {
|
|
|
|
rpmlog(RPMLOG_ERR, _("line %d: %s: %s\n"),
|
|
|
|
spec->lineNum, emsg, spec->line);
|
|
|
|
}
|
|
|
|
}
|
2009-10-21 17:22:33 +08:00
|
|
|
free(N);
|
|
|
|
free(EVR);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2009-10-21 17:22:33 +08:00
|
|
|
return rc;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|