- remove dead code frpm popt table reorg.
[platform/upstream/rpm.git] / build / reqprov.c
1 /** \ingroup rpmbuild
2  * \file build/reqprov.c
3  *  Add dependency tags to package header(s).
4  */
5
6 #include "system.h"
7
8 #include "rpmbuild.h"
9 #include "debug.h"
10
11 int addReqProv(/*@unused@*/ Spec spec, Header h,
12                rpmsenseFlags depFlags, const char *depName, const char *depEVR,
13                 int index)
14 {
15     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
16     HFD_t hfd = headerFreeData;
17     const char ** names;
18     rpmTagType dnt;
19     rpmTag nametag = 0;
20     rpmTag versiontag = 0;
21     rpmTag flagtag = 0;
22     rpmTag indextag = 0;
23     int len;
24     rpmsenseFlags extra = RPMSENSE_ANY;
25     
26     if (depFlags & RPMSENSE_PROVIDES) {
27         nametag = RPMTAG_PROVIDENAME;
28         versiontag = RPMTAG_PROVIDEVERSION;
29         flagtag = RPMTAG_PROVIDEFLAGS;
30         extra = depFlags & RPMSENSE_FIND_PROVIDES;
31     } else if (depFlags & RPMSENSE_OBSOLETES) {
32         nametag = RPMTAG_OBSOLETENAME;
33         versiontag = RPMTAG_OBSOLETEVERSION;
34         flagtag = RPMTAG_OBSOLETEFLAGS;
35     } else if (depFlags & RPMSENSE_CONFLICTS) {
36         nametag = RPMTAG_CONFLICTNAME;
37         versiontag = RPMTAG_CONFLICTVERSION;
38         flagtag = RPMTAG_CONFLICTFLAGS;
39     } else if (depFlags & RPMSENSE_PREREQ) {
40         nametag = RPMTAG_REQUIRENAME;
41         versiontag = RPMTAG_REQUIREVERSION;
42         flagtag = RPMTAG_REQUIREFLAGS;
43         extra = depFlags & _ALL_REQUIRES_MASK;
44     } else if (depFlags & RPMSENSE_TRIGGER) {
45         nametag = RPMTAG_TRIGGERNAME;
46         versiontag = RPMTAG_TRIGGERVERSION;
47         flagtag = RPMTAG_TRIGGERFLAGS;
48         indextag = RPMTAG_TRIGGERINDEX;
49         extra = depFlags & RPMSENSE_TRIGGER;
50     } else {
51         nametag = RPMTAG_REQUIRENAME;
52         versiontag = RPMTAG_REQUIREVERSION;
53         flagtag = RPMTAG_REQUIREFLAGS;
54         extra = depFlags & _ALL_REQUIRES_MASK;
55     }
56
57     depFlags = (depFlags & (RPMSENSE_SENSEMASK | RPMSENSE_MULTILIB)) | extra;
58
59     if (depEVR == NULL)
60         depEVR = "";
61     
62     /* Check for duplicate dependencies. */
63     if (hge(h, nametag, &dnt, (void **) &names, &len)) {
64         const char ** versions = NULL;
65         rpmTagType dvt = RPM_STRING_ARRAY_TYPE;
66         int *flags = NULL;
67         int *indexes = NULL;
68         int duplicate = 0;
69
70         if (flagtag) {
71             (void) hge(h, versiontag, &dvt, (void **) &versions, NULL);
72             (void) hge(h, flagtag, NULL, (void **) &flags, NULL);
73         }
74         if (indextag)
75             (void) hge(h, indextag, NULL, (void **) &indexes, NULL);
76
77         while (len > 0) {
78             len--;
79             if (strcmp(names[len], depName))
80                 continue;
81             if (flagtag && versions != NULL &&
82                 (strcmp(versions[len], depEVR) ||
83         ((flags[len] | RPMSENSE_MULTILIB) != (depFlags | RPMSENSE_MULTILIB))))
84                 continue;
85             if (indextag && indexes != NULL && indexes[len] != index)
86                 continue;
87
88             /* This is a duplicate dependency. */
89             duplicate = 1;
90
91             if (flagtag && isDependsMULTILIB(depFlags) &&
92                 !isDependsMULTILIB(flags[len]))
93                     flags[len] |= RPMSENSE_MULTILIB;
94
95             break;
96         }
97         names = hfd(names, dnt);
98         versions = hfd(versions, dvt);
99         if (duplicate)
100             return 0;
101     }
102
103     /* Add this dependency. */
104     (void) headerAddOrAppendEntry(h, nametag, RPM_STRING_ARRAY_TYPE, &depName, 1);
105     if (flagtag) {
106         (void) headerAddOrAppendEntry(h, versiontag,
107                                RPM_STRING_ARRAY_TYPE, &depEVR, 1);
108         (void) headerAddOrAppendEntry(h, flagtag,
109                                RPM_INT32_TYPE, &depFlags, 1);
110     }
111     if (indextag)
112         (void) headerAddOrAppendEntry(h, indextag, RPM_INT32_TYPE, &index, 1);
113
114     return 0;
115 }
116
117 int rpmlibNeedsFeature(Header h, const char * feature, const char * featureEVR)
118 {
119     char * reqname = alloca(sizeof("rpmlib()") + strlen(feature));
120
121     (void) stpcpy( stpcpy( stpcpy(reqname, "rpmlib("), feature), ")");
122
123     /* XXX 1st arg is unused */
124    return addReqProv(NULL, h, RPMSENSE_RPMLIB|(RPMSENSE_LESS|RPMSENSE_EQUAL),
125         reqname, featureEVR, 0);
126 }