rpmlib.h mass eviction
[platform/upstream/rpm.git] / build / parseReqs.c
1 /** \ingroup rpmbuild
2  * \file build/parseReqs.c
3  *  Parse dependency tag from spec file or from auto-dependency generator.
4  */
5
6 #include "system.h"
7
8 #include <rpm/rpmtag.h>
9 #include <rpm/rpmbuild.h>
10 #include <rpm/rpmlog.h>
11 #include "debug.h"
12
13 /**
14  */
15 static struct ReqComp {
16 const char * token;
17     rpmsenseFlags sense;
18 } ReqComparisons[] = {
19     { "<=", RPMSENSE_LESS | RPMSENSE_EQUAL},
20     { "=<", RPMSENSE_LESS | RPMSENSE_EQUAL},
21     { "<", RPMSENSE_LESS},
22
23     { "==", RPMSENSE_EQUAL},
24     { "=", RPMSENSE_EQUAL},
25     
26     { ">=", RPMSENSE_GREATER | RPMSENSE_EQUAL},
27     { "=>", RPMSENSE_GREATER | RPMSENSE_EQUAL},
28     { ">", RPMSENSE_GREATER},
29
30     { NULL, 0 },
31 };
32
33 #define SKIPWHITE(_x)   {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
34 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
35
36 rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpm_tag_t tagN,
37                int index, rpmsenseFlags tagflags)
38 {
39     const char *r, *re, *v, *ve;
40     char * N, * EVR;
41     rpmsenseFlags Flags;
42     Header h;
43
44     switch (tagN) {
45     case RPMTAG_PROVIDEFLAGS:
46         tagflags |= RPMSENSE_PROVIDES;
47         h = pkg->header;
48         break;
49     case RPMTAG_OBSOLETEFLAGS:
50         tagflags |= RPMSENSE_OBSOLETES;
51         h = pkg->header;
52         break;
53     case RPMTAG_CONFLICTFLAGS:
54         tagflags |= RPMSENSE_CONFLICTS;
55         h = pkg->header;
56         break;
57     case RPMTAG_BUILDCONFLICTS:
58         tagflags |= RPMSENSE_CONFLICTS;
59         h = spec->buildRestrictions;
60         break;
61     case RPMTAG_PREREQ:
62         tagflags |= RPMSENSE_PREREQ;
63         h = pkg->header;
64         break;
65     case RPMTAG_BUILDPREREQ:
66         tagflags |= RPMSENSE_PREREQ;
67         h = spec->buildRestrictions;
68         break;
69     case RPMTAG_TRIGGERPREIN:
70         tagflags |= RPMSENSE_TRIGGERPREIN;
71         h = pkg->header;
72         break;
73     case RPMTAG_TRIGGERIN:
74         tagflags |= RPMSENSE_TRIGGERIN;
75         h = pkg->header;
76         break;
77     case RPMTAG_TRIGGERPOSTUN:
78         tagflags |= RPMSENSE_TRIGGERPOSTUN;
79         h = pkg->header;
80         break;
81     case RPMTAG_TRIGGERUN:
82         tagflags |= RPMSENSE_TRIGGERUN;
83         h = pkg->header;
84         break;
85     case RPMTAG_BUILDREQUIRES:
86         tagflags |= RPMSENSE_ANY;
87         h = spec->buildRestrictions;
88         break;
89     default:
90     case RPMTAG_REQUIREFLAGS:
91         tagflags |= RPMSENSE_ANY;
92         h = pkg->header;
93         break;
94     }
95
96     for (r = field; *r != '\0'; r = re) {
97         SKIPWHITE(r);
98         if (*r == '\0')
99             break;
100
101         Flags = (tagflags & ~RPMSENSE_SENSEMASK);
102
103         /* Tokens must begin with alphanumeric, _, or / */
104         if (!(xisalnum(r[0]) || r[0] == '_' || r[0] == '/')) {
105             rpmlog(RPMLOG_ERR,
106                      _("line %d: Dependency tokens must begin with alpha-numeric, '_' or '/': %s\n"),
107                      spec->lineNum, spec->line);
108             return RPMRC_FAIL;
109         }
110
111         re = r;
112         SKIPNONWHITE(re);
113         N = xmalloc((re-r) + 1);
114         strncpy(N, r, (re-r));
115         N[re-r] = '\0';
116
117         /* Parse EVR */
118         v = re;
119         SKIPWHITE(v);
120         ve = v;
121         SKIPNONWHITE(ve);
122
123         re = v; /* ==> next token (if no EVR found) starts here */
124
125         /* Check for possible logical operator */
126         if (ve > v) {
127           struct ReqComp *rc;
128           for (rc = ReqComparisons; rc->token != NULL; rc++) {
129             if ((ve-v) != strlen(rc->token) || strncmp(v, rc->token, (ve-v)))
130                 continue;
131
132             if (r[0] == '/') {
133                 rpmlog(RPMLOG_ERR,
134                          _("line %d: Versioned file name not permitted: %s\n"),
135                          spec->lineNum, spec->line);
136                 return RPMRC_FAIL;
137             }
138
139             switch(tagN) {
140             case RPMTAG_BUILDPREREQ:
141             case RPMTAG_PREREQ:
142             case RPMTAG_PROVIDEFLAGS:
143             case RPMTAG_OBSOLETEFLAGS:
144                 /* Add prereq on rpmlib that has versioned dependencies. */
145                 if (!rpmExpandNumeric("%{?_noVersionedDependencies}"))
146                     (void) rpmlibNeedsFeature(h, "VersionedDependencies", "3.0.3-1");
147                 break;
148             default:
149                 break;
150             }
151             Flags |= rc->sense;
152
153             /* now parse EVR */
154             v = ve;
155             SKIPWHITE(v);
156             ve = v;
157             SKIPNONWHITE(ve);
158             break;
159           }
160         }
161
162         if (Flags & RPMSENSE_SENSEMASK) {
163             if (*v == '\0' || ve == v) {
164                 rpmlog(RPMLOG_ERR, _("line %d: Version required: %s\n"),
165                         spec->lineNum, spec->line);
166                 return RPMRC_FAIL;
167             }
168             EVR = xmalloc((ve-v) + 1);
169             strncpy(EVR, v, (ve-v));
170             EVR[ve-v] = '\0';
171             re = ve;    /* ==> next token after EVR string starts here */
172         } else
173             EVR = NULL;
174
175         (void) addReqProv(spec, h, tagN, N, EVR, Flags, index);
176
177         N = _free(N);
178         EVR = _free(EVR);
179
180     }
181
182     return RPMRC_OK;
183 }