2 * \file build/parseReqs.c
3 * Parse dependency tag from spec file or from auto-dependency generator.
13 /*@observer@*/ /*@unchecked@*/
14 static struct ReqComp {
15 /*@observer@*/ /*@null@*/ const char * token;
17 } ReqComparisons[] = {
18 { "<=", RPMSENSE_LESS | RPMSENSE_EQUAL},
19 { "=<", RPMSENSE_LESS | RPMSENSE_EQUAL},
20 { "<", RPMSENSE_LESS},
22 { "==", RPMSENSE_EQUAL},
23 { "=", RPMSENSE_EQUAL},
25 { ">=", RPMSENSE_GREATER | RPMSENSE_EQUAL},
26 { "=>", RPMSENSE_GREATER | RPMSENSE_EQUAL},
27 { ">", RPMSENSE_GREATER},
32 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
33 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
35 int parseRCPOT(Spec spec, Package pkg, const char *field, int tag,
36 int index, rpmsenseFlags tagflags)
38 const char *r, *re, *v, *ve;
39 char * req, * version;
44 case RPMTAG_PROVIDEFLAGS:
45 tagflags |= RPMSENSE_PROVIDES;
48 case RPMTAG_OBSOLETEFLAGS:
49 tagflags |= RPMSENSE_OBSOLETES;
52 case RPMTAG_CONFLICTFLAGS:
53 tagflags |= RPMSENSE_CONFLICTS;
56 case RPMTAG_BUILDCONFLICTS:
57 tagflags |= RPMSENSE_CONFLICTS;
58 h = spec->buildRestrictions;
61 tagflags |= RPMSENSE_PREREQ;
64 case RPMTAG_BUILDPREREQ:
65 tagflags |= RPMSENSE_PREREQ;
66 h = spec->buildRestrictions;
68 case RPMTAG_TRIGGERIN:
69 tagflags |= RPMSENSE_TRIGGERIN;
72 case RPMTAG_TRIGGERPOSTUN:
73 tagflags |= RPMSENSE_TRIGGERPOSTUN;
76 case RPMTAG_TRIGGERUN:
77 tagflags |= RPMSENSE_TRIGGERUN;
80 case RPMTAG_BUILDREQUIRES:
81 tagflags |= RPMSENSE_ANY;
82 h = spec->buildRestrictions;
85 case RPMTAG_REQUIREFLAGS:
86 tagflags |= RPMSENSE_ANY;
91 for (r = field; *r != '\0'; r = re) {
96 flags = (tagflags & ~RPMSENSE_SENSEMASK);
98 /* Tokens must begin with alphanumeric, _, or / */
99 if (!(xisalnum(r[0]) || r[0] == '_' || r[0] == '/')) {
100 rpmError(RPMERR_BADSPEC,
101 _("line %d: Dependency tokens must begin with alpha-numeric, '_' or '/': %s\n"),
102 spec->lineNum, spec->line);
103 return RPMERR_BADSPEC;
106 /* Don't permit file names as args for certain tags */
108 case RPMTAG_OBSOLETEFLAGS:
109 case RPMTAG_CONFLICTFLAGS:
110 case RPMTAG_BUILDCONFLICTS:
112 rpmError(RPMERR_BADSPEC,_("line %d: File name not permitted: %s\n"),
113 spec->lineNum, spec->line);
114 return RPMERR_BADSPEC;
116 /*@switchbreak@*/ break;
118 /*@switchbreak@*/ break;
123 req = xmalloc((re-r) + 1);
124 strncpy(req, r, (re-r));
133 re = v; /* ==> next token (if no version found) starts here */
135 /* Check for possible logical operator */
138 for (rc = ReqComparisons; rc->token != NULL; rc++) {
139 if ((ve-v) != strlen(rc->token) || strncmp(v, rc->token, (ve-v)))
140 /*@innercontinue@*/ continue;
143 rpmError(RPMERR_BADSPEC,
144 _("line %d: Versioned file name not permitted: %s\n"),
145 spec->lineNum, spec->line);
146 return RPMERR_BADSPEC;
150 case RPMTAG_BUILDPREREQ:
152 case RPMTAG_PROVIDEFLAGS:
153 case RPMTAG_OBSOLETEFLAGS:
154 /* Add prereq on rpmlib that has versioned dependencies. */
155 if (!rpmExpandNumeric("%{_noVersionedDependencies}"))
156 (void) rpmlibNeedsFeature(h, "VersionedDependencies", "3.0.3-1");
157 /*@switchbreak@*/ break;
159 /*@switchbreak@*/ break;
163 /* now parse version */
168 /*@innerbreak@*/ break;
173 if (flags & RPMSENSE_SENSEMASK) {
174 if (*v == '\0' || ve == v) {
175 rpmError(RPMERR_BADSPEC, _("line %d: Version required: %s\n"),
176 spec->lineNum, spec->line);
177 return RPMERR_BADSPEC;
179 version = xmalloc((ve-v) + 1);
180 strncpy(version, v, (ve-v));
181 version[ve-v] = '\0';
182 re = ve; /* ==> next token after version string starts here */
187 (void) addReqProv(spec, h, flags, req, version, index);
190 version = _free(version);